2012-01-16 13 views
2

fstat(2)でPOSIX経由でファイルがシンボリックリンクかどうかをチェックしますか?ファイルがシンボリックリンクかどうかを調べるためのfstat()のPOSIXの方法はありますか?

open(2)にフラグO_NOFOLLOWがありますが、これはチェックできますが、POSIXではありません。

ありman fstatに言われfstat(2)S_ISLNK、次のとおりです。

The S_ISLNK() and S_ISSOCK() macros are not in POSIX.1-1996, 
    but both are present in POSIX.1-2001; the former is from SVID 
    4, the latter from SUSv2. 

は、コンパイルは私のマシン上で失敗します。

また、別のS_IFLNKlstat(2)にありますが、fstat(2)(これはファイルへのリンクに従います)では機能しません。

+1

'fstat'と' lstat'の両方を使い、inodeを比較するのはどうですか? –

+2

シンボリックリンクは、最終的に開くファイルです。 fdからそれを開くためにどのパスが使われているのか分かりません。(もはや存在しないかもしれません) –

+0

@KerrekSB: 'lstat'関数はシンボリックリンクのinodeを返しますが、これは役に立ちません。 O_NOFOLLOW以外に –

答えて

3

それはfstatがシンボリックリンクをたどることは事実ではありません。代わりに、openがシンボリックリンクに続きます。 fstatになると、遅すぎて情報がなくなります。

なぜあなたが知る必要があるのか​​、私たちはその問題を解決することができます。 (別の質問を開きます。)ファイルがどのように動作するか

をここではいくつかの擬似C /シェルコードは次のとおりです。

system("echo 'Hello, World!' >A.txt"); 
system("ln A.txt B.txt"); 
system("ln -s A.txt C.txt"); 

fdes = open("C.txt"); 
unlink("A.txt"); 
unlink("C.txt"); 
data = read(fdes); 
write(stdout, data); 

結果:あなたのプログラムを印刷"Hello, world!"

 
+--Application--+ +--Kernel--+ +-------Disk-------+ 
|    | |   | |     | 
| fdes --------------> file ---------> inode #973 <-------+ 
|    | |   | | "Hello World!" | | 
+---------------+ +----------+ |     | | 
            | directory ---------+ 
            | "B.txt"   | 
            |     | 
            +------------------+ 

カーネルに関する限り、ファイルのオープンは "inode#973"です。カーネルメモリのデータ構造には、現在の位置などの追加情報がありますが、パスがわかりません。カーネルはその情報を知ることは期待されていません。

パスが何であるかをカーネルに問い合わせた場合、となります。「あなたはB.txtを持っています」と表示されます。しかし、あなたは "B.txt"を開いたことはなく、 "A.txt"へのシンボリックリンクである "C.txt"を開いて、 "A.txt"と "C.txt"の両方を削除しました。始める)。

単純なアナロジーは:

あなたは古い友人からの電話を取得します。彼は、「私は電話帳であなたの番号を調べましたか、私はそれを覚えましたか、誰かにあなたの番号を尋ねなければなりませんでしたか?

あなたは答えを知る方法がありません。あなたが知っているのは、誰がラインの反対側にいるのかです。開いているファイルには、名前(ハードリンクやシンボリックリンク)の情報が格納されていないのと同じように、アクセス権とデータに関する情報だけが格納されています。

解決策:lstat(はい、競合状態があります)を使用してください。ファイルを自分で開かなかった場合(親プロセスから取得した場合やソケットで取得した場合など)、シンボリックリンクで開かれたかどうかを知ることは多かれ少なかれです。

+0

、open()でファイルをチェックする別の方法はありますか? – wenlujon

+0

いいえ<! - comment - > –

+0

楽しいものにするには、シンボリックリンクがもう存在しないか、シンボリックリンクが同じ名前の別のファイルを指している可能性があります。最初のファイルはリンク解除されました)! – bdonlan

関連する問題