【发布时间】:2018-04-23 19:00:34
【问题描述】:
通过调用 signal() 忽略 SIGPIPE 后,write() 调用可能会失败,并且 errno 设置等于 EPIPE。我还需要像下面的示例那样关闭文件描述符吗?
if (write(sock_fd, buf, len) < 0) {
if (errno == EPIPE) {
close(sock_fd);
}
}
【问题讨论】:
通过调用 signal() 忽略 SIGPIPE 后,write() 调用可能会失败,并且 errno 设置等于 EPIPE。我还需要像下面的示例那样关闭文件描述符吗?
if (write(sock_fd, buf, len) < 0) {
if (errno == EPIPE) {
close(sock_fd);
}
}
【问题讨论】:
请记住,当您创建管道时,使用同名的系统调用,您会得到 两个 文件描述符:一个用于读取,一个用于写入。当 read fd 已关闭时,您会从 write fd 上的写入操作中获得 EPIPE。写入 fd 仍处于打开状态。如果您再次尝试写入,您将再次获得 EPIPE。
(通常,当这种情况发生时,管道是由 shell 或其他父进程设置的,并且 read fd 对您的程序永远不可用,但这对内核无关紧要。它在 一些进程,但现在不是。)
由于它仍处于打开状态,因此您确实需要将其关闭。但是,退出会自动关闭所有仍处于打开状态的 fd。因此,如果您在关闭管道后要做的下一件事是退出,那么您无需先关闭它。由于它是一个管道,并且您已经获得了 EPIPE,因此不会出现 close 可能报告的任何延迟写入错误。
【讨论】:
您总是必须关闭文件描述符。没有如果,没有但是。
【讨论】: