23

我只想知道在 fd 上连续两次关闭的行为是什么。

例如-

close(fd);
close(fd);

[fd 是一个整数]

4

5 回答 5

22

第一次调用应该返回0;第二个调用应该返回-1,并设置errnoEBADF.

fd您应该通过设置为已知的错误号码来防止第二次呼叫发生,例如-1,在第一次呼叫之后立即进行a ,然后在进行第二次呼叫之前进行close检查(如果是则不进行呼叫):fdfd-1

close(fd);
fd = -1;
...
// More code
...
if (fd != -1) {
    close(fd)
    fd = -1;
}

当您需要close从多个位置进行调用,但您不确定文件是否已打开或是否已关闭时,此 Code Pattern 会有所帮助。传递-1toclose是无害的(EBADF当然,你会得到一个 )。

于 2012-10-08T13:32:17.303 回答
9

它应该是无害的,除非您在两次关闭调用之间进行线程化或执行某些操作。然后,您可能最终会关闭程序中其他内容已打开的 fd。

线程相关的方式是库几乎总是在你背后做一些奇怪的事情。Libc 将打开文件以查找错误消息或其他与语言环境相关的内容,解析器可以打开配置文件等。如果您关闭文件描述符并再次关闭它,在线程环境中,您很容易陷入文件描述符已被库重用,您在其背后关闭它。

于 2012-10-08T13:30:13.687 回答
6

正如其他人指出的那样,两次关闭同一个fd 应该是非致命的,但要注意这样的代码

close(fd);
/* ... */
newfd = open(....);
/* ... */
close(fd);

到第二次关闭时,您无法确定是否fd实际上与newfd! 每当您尝试使用newfd.

所以(如果两个close调用之间有代码)这样​​做是不安全的。总是close文件描述符恰好一次。总是free只缓冲一次。

于 2013-12-30T02:46:28.293 回答
5

第二次调用将失败,Errno: EBADF因为那时fd 不是活动文件描述符。

它应该对执行完全没有影响。但是,如果第一次关闭时设置了任何错误号,那将会丢失,因此您不应该关闭文件描述符两次。

于 2012-10-08T13:33:41.377 回答
1

如果 fd 的值保持不变,第二次调用将返回 fd 无效的错误(EBADF - 正如 dasblinkenlight 指出的那样)

想想做一些喜欢的事

if fd != -1 )
{
   close (fd );
   fd = -1;
}
于 2012-10-08T13:31:57.510 回答