如何检查存储在variables中的给定文件描述符是否仍然有效?
我有一个文件描述符存储在一个variables说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
为零超时,并且events
成员设置为0,并在返回后检查POLLNVAL
in POLLNVAL
更有效。
这样说,操作“检查给定的资源句柄是否仍然有效”几乎总是从根本上不正确。 释放资源句柄后(例如fd close
),其值可能会被重新分配给您分配的下一个此类资源。 如果还有剩余的引用可能会被使用,他们会错误地使用新资源而不是旧资源。 因此,真正的答案可能是:如果你不知道你的程序的逻辑,你有重大的基本逻辑错误,需要修复。
你可以使用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)可能是您可以在文件描述符上执行的最廉价和最不可能的失败操作。 该规范特别指出,它不能被信号中断,也不受任何地方的任何锁的影响。
我不认为有任何function可以告诉你,如果描述符仍然有效。 描述符通常只是一个像6这样的小整数,如果您稍后closures文件并打开一个新文件,则您的libc可以select重复使用该编号。
相反,您应该考虑使用dup()
来复制文件描述符。 通过复制文件描述符而不是在多个地方使用相同的描述符,可能会更容易知道文件描述符是否仍然有效。 你只需要记住在完成时closures原始描述符和复制的描述符。
在我看来,如果你想知道它是否仍然指向相同的资源,那么一个(非完美的)方法就是在打开后fstat()
描述符,然后再次执行并比较结果。 首先查看.st_mode
& S_IFMT
并从那里开始 – 它是一个文件系统对象吗? 看看.st_dev / .st_ino.
它是一个sockets? 尝试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
干杯,弗洛