Cでファイル記述子(Linux)のファイル名を取得することはできますか?
Cでファイル記述子(Linux)のファイル名を取得することはできますか?
回答:
あなたは使用することができますreadlink
上の/proc/self/fd/NNN
NNNは、ファイル記述子です。これにより、ファイルを開いたときの名前が表示されます。ただし、それ以降にファイルが移動または削除された場合、正確ではなくなる可能性があります(Linuxが名前を追跡できる場合もあります)。確認するには、指定されstat
たファイル名とfstat
fdを確認st_dev
しst_ino
、同じであることを確認します。
もちろん、すべてのファイル記述子がファイルを参照しているわけではありません。それらについては、などの奇妙なテキスト文字列が表示されpipe:[1538488]
ます。実際のファイル名はすべて絶対パスになるため、どれで十分かを判断できます。さらに、他の人が指摘したように、ファイルはそれらを指す複数のハードリンクを持つことができます-これはそれが開かれたものだけを報告します。特定のファイルのすべての名前を検索する場合は、ファイルシステム全体をトラバースする必要があります。
fd
はそのような参照になります)、iノード番号を再利用することはできません。ファイルを閉じた後、または開く前にiノード番号を使用するソフトウェアは、本質的に競合状態の影響を受けます。
setuid()
トリックを行うと/proc/self/fd
、プロセスからアクセスできなくなる可能性があります。参照:permalink.gmane.org/gmane.linux.kernel/1302546
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 でいいと思いました。
getsockname
ます。
Windowsでは、GetFileInformationByHandleExを使用してFileNameInfoを渡すと、ファイル名を取得できます。
Tylerが指摘するように、特定のFDが0のファイル名(さまざまな場合)または> 1(複数の「ハードリンク」とは一般的に後者の状況がどのように説明されるか)に対応する場合があるため、「直接かつ確実に」必要なことを行う方法はありません。 )。それでもすべての制限付きの機能が必要な場合(速度が1でなく、0、2、...の結果が得られる可能性がある場合)は、次の方法でそれを行うことができます。最初に、FDをfstatします。これにより、 、結果struct stat
ので、ファイルが存在するデバイス、ファイルのハードリンクの数、特殊ファイルかどうかなど。これはすでに質問に答えている可能性があります。たとえば、ハードリンクが0の場合、実際には対応するファイル名がないことを知っています。ディスク上。
統計で希望が得られる場合は、すべてのハードリンクが見つかるまで、関連するデバイス上のディレクトリの「ツリーをたどる」必要があります(または、最初のリンクだけで、複数のハードリンクが必要ない場合は、1つだけで十分です) )。そのために、readdir(そしてもちろんopendir&c)を使用struct dirent
して、元のディレクトリと同じinode番号が見つかるまで、サブディレクトリを再帰的に開きますstruct stat
(このとき、名前だけでなくパス全体が必要な場合は、再構築するには、ディレクトリのチェーンを逆方向にたどる必要があります)。
この一般的なアプローチは受け入れられますが、より詳細なCコードが必要な場合はお知らせください。役に立たない場合、つまり、必然的に遅いパフォーマンスやアプリケーションの目的で!= 1の結果が得られる可能性;-)
不可能な。ファイル記述子は、ファイルシステム内に複数の名前を持っているか、まったく名前を持たない場合があります。
編集:OSを指定しなかったので、OS固有のAPIのないプレーンな古いPOSIXシステムについて話していると仮定します。