如何检查存储在变量中的给定文件描述符是否仍然有效?

问题描述 投票:0回答:6

我有一个文件描述符存储在变量中,比如

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, ....);

现在我想检查

fdvar1
(仍然保存打开的描述符)是否仍然有效。 有相关的 API 吗?

c linux gcc file-descriptor
6个回答
105
投票

fcntl(fd, F_GETFD)
是检查
fd
是否是有效的打开文件描述符的最便宜的规范方法。如果您需要批量检查很多,使用超时为零的
poll
并将
events
成员设置为 0,并在返回后检查
POLLNVAL
中的
revents
会更有效。

话虽如此,“检查给定资源句柄是否仍然有效”的操作几乎总是从根本上不正确。释放资源句柄后(例如,fd 为

close
d),其值可能会重新分配给您分配的下一个此类资源。如果还有任何可能使用的剩余引用,它们将错误地操作新资源而不是旧资源。因此,真正的答案可能是:如果您还不知道程序的逻辑,那么您就存在需要修复的重大基本逻辑错误。


39
投票

您可以使用

fcntl()
功能:

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

8
投票

我认为没有任何函数可以告诉您描述符是否仍然有效。 描述符通常只是一个像 6 这样的小整数,如果您关闭文件并稍后打开一个新文件,您的 libc 可以选择重用该数字。

相反,您应该考虑使用

dup()
来复制文件描述符。 通过复制文件描述符而不是在多个位置使用相同的描述符,您可能会更容易知道文件描述符是否仍然有效。 您只需记住在完成后关闭原始描述符和复制的描述符即可。


7
投票

来自this论坛文章:

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

fcntl(GETFL) 可能是最便宜且最不可能失败的 您可以对文件描述符执行的操作。特别是, 规范表明它不能被信号中断,也不能被中断 它是否受到任何地方持有的任何类型的锁的影响。


1
投票

在我看来,如果您想知道它是否仍然指向相同的资源,一种(非完美)方法是在打开后立即打开描述符,然后您可以再次执行此操作并比较结果。 首先查看

fstat()
&
.st_mode
,然后从那里开始——它是一个文件系统对象吗?看看
S_IFMT
是插座吗?尝试
.st_dev / .st_ino.
getsockname()
。 它不会 100% 确定,但它可以告诉您它是否绝对不一样。
    


-1
投票

getpeername()

有关详细信息,请参阅例如手册页 
http://linux.die.net/man/2/fstat

干杯, 弗洛

© www.soinside.com 2019 - 2024. All rights reserved.