如何检查存储在变量中的给定文件描述符是否仍然有效?

时间:2012-09-09 16:15:24

标签: c linux gcc file-descriptor

我有一个文件描述符存储在变量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都是为了这个?

6 个答案:

答案 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