如何检查存储在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_modeS_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

干杯,弗洛