GNU/Linux >> Linux の 問題 >  >> Linux

C でファイル記述子からファイル名を取得する

Mac OS X でこの問題が発生しました。/proc はありません。 仮想ファイル システムであるため、受け入れられたソリューションは機能しません。

代わりに F_GETPATH があります fcntl のコマンド :

 F_GETPATH          Get the path of the file descriptor Fildes.  The argu-
                    ment must be a buffer of size MAXPATHLEN or greater.

したがって、ファイル記述子に関連付けられたファイルを取得するには、次のスニペットを使用できます:

#include <sys/syslimits.h>
#include <fcntl.h>

char filePath[PATH_MAX];
if (fcntl(fd, F_GETPATH, filePath) != -1)
{
    // do something with the file path
}

MAXPATHLEN がどこだったか覚えていないので PATH_MAX と思った syslimits からでも問題ありません。


readlink を使用できます /proc/self/fd/NNN で ここで、NNN はファイル記述子です。これにより、ファイルを開いたときの名前が表示されますが、それ以降にファイルが移動または削除された場合は、正確でなくなる可能性があります (ただし、Linux では名前の変更を追跡できる場合があります)。確認するには、stat 指定されたファイル名と fstat あなたが持っているfd、そしてst_devを確認してください および st_ino

もちろん、すべてのファイル記述子がファイルを参照しているわけではありません。それらについては、pipe:[1538488] などの奇妙なテキスト文字列が表示されます。 .実際のファイル名はすべて絶対パスになるため、どれがどれであるかを簡単に判断できます。さらに、他の人が指摘したように、ファイルはそれらを指す複数のハードリンクを持つことができます - これはそれが開かれたものだけを報告します。特定のファイルのすべての名前を見つけたい場合は、ファイル システム全体をトラバースするだけです。


タイラーが指摘しているように、特定の FD が 0 個のファイル名 (さまざまな場合) または> 1 個 (複数の「ハード リンク」が後者の状況を一般的に説明する方法である) に対応する可能性があるため、必要なことを「直接的かつ確実に」実行する方法はありません。 )。すべての制限 (速度、および 1 ではなく 0、2、... の結果が得られる可能性) を備えた機能が引き続き必要な場合は、次の方法で実行できます。最初に、FD を fstat します。 、結果の struct stat 、ファイルが保存されているデバイス、ハードリンクの数、特別なファイルかどうかなど。これはすでにあなたの質問に答えているかもしれません。ハード リンクが 0 の場合、対応するファイル名が実際にはディスク上にないことがわかります。

統計から希望が得られる場合は、すべてのハード リンクが見つかるまで、関連するデバイスのディレクトリの「ツリーをたどる」必要があります (または、複数必要なく、いずれかが必要な場合は最初のリンクのみ)。 )。その目的のために、readdir (そしてもちろん opendir &c) を使用して、struct dirent で見つかるまで再帰的にサブディレクトリを開きます。 したがって、元の struct stat で持っていたのと同じ inode 番号を受け取りました (名前だけでなくパス全体が必要な場合は、ディレクトリのチェーンを逆方向にたどって再構築する必要があります)。

この一般的なアプローチが受け入れられるが、より詳細な C コードが必要な場合は、私たちに知らせてください。書くのは難しくありません (ただし、それが役に立たない場合、つまり、必然的に遅いパフォーマンスに耐えられない場合や、アプリケーションの目的のために !=1 の結果を得る可能性があります;-)


Windows では、GetFileInformationByHandleEx を使用して FileNameInfo を渡すと、ファイル名を取得できます。


Linux
  1. ファイル記述子リンクの移植性?

  2. Awkからファイルをキャットする方法は?

  3. アセンブリ内のファイルからの読み取り

  1. BASH で mv を使用してファイル名にタイムスタンプを追加する

  2. ターミナルウィンドウからLinuxでファイルを作成するには?

  3. ファイル名に / を使用できますか?

  1. 別の行からのAWK?

  2. ファイルからGrepパターンを読み取る?

  3. install -c は cp とどう違うのですか