58

var などの変数に格納されたファイル記述子があります。その記述子が後の段階で有効かどうかを確認するにはどうすればよいですか?

  fdvar1= open(.....);
  fdvar2 = fdvar1;       // Please ignore the bad design

  ....
  // lots of loops , conditionals and threads. It can call close(fdvar2) also.  
  ....

  if(CheckValid(fdvar1)) // How can I do this check  ?
    write(fdvar1, ....);

ここで、var1 (まだ開いている記述子を保持している) がまだ有効かどうかを確認したいと思います。そのためのAPIはありますか?

4

6 に答える 6

89

fcntl(fd, F_GETFD)fdこれは、有効なオープンファイル記述子であることを確認するための標準的な最も安価な方法です。大量のバッチチェックが必要な場合は、pollタイムアウトをゼロにしてeventsメンバーを0に設定し、メンバーが戻った後にチェックインするPOLLNVALreventsが効率的です。

そうは言っても、「特定のリソースハンドルがまだ有効かどうかを確認する」という操作は、ほとんどの場合、根本的に正しくありません。リソースハンドルが解放された後(たとえば、fdがclosedの場合)、その値は、次に割り当てるそのようなリソースに再割り当てされる場合があります。使用される可能性のある参照が残っている場合、それらは古いリソースではなく新しいリソースで誤って動作します。したがって、本当の答えはおそらく次のとおりです。プログラムのロジックをまだ知らない場合は、修正する必要のある主要な基本的なロジックエラーがあります。

于 2012-09-09T16:20:09.373 に答える
34

fcntl()次の機能を使用できます。

int fd_is_valid(int fd)
{
    return fcntl(fd, F_GETFD) != -1 || errno != EBADF;
}
于 2012-09-09T16:20:02.963 に答える
6

記述子がまだ有効かどうかを判断できる関数はないと思います。記述子は通常、6 のような小さな整数であり、ファイルを閉じて後で新しいファイルを開く場合、libc はその番号を再利用することを選択できます。

代わりに、を使用dup()してファイル記述子をコピーすることを検討する必要があります。複数の場所で同じ記述子を使用するのではなく、ファイル記述子を複製することにより、ファイル記述子がまだ有効かどうかを簡単に知ることができる場合があります。完了したら、元の記述子と複製された記述子の両方を閉じることを忘れないでください。

于 2012-09-09T16:21:24.117 に答える
6

このフォーラムの記事から:

int is_valid_fd(int fd)
{
    return fcntl(fd, F_GETFL) != -1 || errno != EBADF;
}

fcntl(GETFL) は、おそらく、ファイル記述子に対して実行できる最も安価で、失敗する可能性が最も低い操作です。特に、仕様は、シグナルによって中断されないこと、またどこかに保持されているあらゆる種類のロックの影響を受けないことを示唆しています。

于 2012-09-09T16:25:30.023 に答える
0

それがまだ同じリソースを指しているかどうかを知りたい場合、1つの(完全ではない)アプローチはfstat()、開いた直後の記述子に対するものであり、後でもう一度実行して結果を比較できるようです。.st_mode&を見ることから始めてS_IFMT、そこから進みます。これはファイルシステム オブジェクトですか? .st_dev / .st_ino. Is it is socket?を見てください。、 を試してgetsockname()くださいgetpeername()。100%確実ではありませんが、間違いなく同じでないかどうかはわかります。

于 2013-02-09T15:24:27.417 に答える
-1

私はこの問題を解決しました。汎用で使えるかどうかはわかりませんが、シリアル接続では問題なく動作します (例: /dev/ttyUSB0)!

struct stat s;
fstat(m_fileDescriptor, &s);

// struct stat::nlink_t   st_nlink;   ... number of hard links 
if( s.st_nlink < 1 ){
 // treat device disconnected case
}

詳細については、たとえば man ページhttp://linux.die.net/man/2/fstatを参照してください。

乾杯、フロー

于 2014-10-10T13:51:55.053 に答える