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