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