我有一个文件描述符存储在变量中,比如
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 吗?
fcntl(fd, F_GETFD)
是检查 fd
是否是有效的打开文件描述符的最便宜的规范方法。如果您需要批量检查很多,使用超时为零的 poll
并将 events
成员设置为 0,并在返回后检查 POLLNVAL
中的 revents
会更有效。
话虽如此,“检查给定资源句柄是否仍然有效”的操作几乎总是从根本上不正确。释放资源句柄后(例如,fd 为
close
d),其值可能会重新分配给您分配的下一个此类资源。如果还有任何可能使用的剩余引用,它们将错误地操作新资源而不是旧资源。因此,真正的答案可能是:如果您还不知道程序的逻辑,那么您就存在需要修复的重大基本逻辑错误。
您可以使用
fcntl()
功能:
int fd_is_valid(int fd)
{
return fcntl(fd, F_GETFD) != -1 || errno != EBADF;
}
我认为没有任何函数可以告诉您描述符是否仍然有效。 描述符通常只是一个像 6 这样的小整数,如果您关闭文件并稍后打开一个新文件,您的 libc 可以选择重用该数字。
相反,您应该考虑使用
dup()
来复制文件描述符。 通过复制文件描述符而不是在多个位置使用相同的描述符,您可能会更容易知道文件描述符是否仍然有效。 您只需记住在完成后关闭原始描述符和复制的描述符即可。
来自this论坛文章:
int is_valid_fd(int fd)
{
return fcntl(fd, F_GETFL) != -1 || errno != EBADF;
}
fcntl(GETFL) 可能是最便宜且最不可能失败的 您可以对文件描述符执行的操作。特别是, 规范表明它不能被信号中断,也不能被中断 它是否受到任何地方持有的任何类型的锁的影响。
在我看来,如果您想知道它是否仍然指向相同的资源,一种(非完美)方法是在打开后立即打开描述符,然后您可以再次执行此操作并比较结果。 首先查看
fstat()
& .st_mode
,然后从那里开始——它是一个文件系统对象吗?看看S_IFMT
是插座吗?尝试.st_dev / .st_ino.
,getsockname()
。 它不会 100% 确定,但它可以告诉您它是否绝对不一样。