【发布时间】:2016-08-09 00:14:25
【问题描述】:
可以在管道上进行非阻塞 I/O 吗? fcntl 未能设置 O_NONBLOCK。 Linux 编程接口的第 918 页包含一个表“从管道或 FIFO (p) 读取 n 字节的语义”。此表列出了管道和 FIFO 的行为,其中一列标题为启用了 O_NONBLOCK?这意味着您可以在管道上设置 O_NONBLOCK 标志。它是否正确?以下代码设置标志失败,但 fcntl(2) 不报错。
#include <fcntl.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#define SLEEP 1
int
main(int argc, char *argv[]) {
pid_t childPid;
int pfd[2];
int nread, flags;
int c = 'a';
setbuf(stdout, NULL);
if (pipe(pfd) == -1) {
printf("error: pipe");
exit(EXIT_FAILURE);
}
switch (childPid = fork()) {
case -1:
printf("error: fork");
exit(EXIT_FAILURE);
case 0: /* child */
if (close(pfd[0]) == -1) {
printf("child: close pfd read");
exit(EXIT_FAILURE);
}
sleep(SLEEP);
_exit(EXIT_SUCCESS);
default:
break;
/* parent falls through */
}
if (close(pfd[1]) == -1) {
printf("parent: close pipe write");
exit(EXIT_FAILURE);
}
flags = fcntl(pfd[0], F_GETFD);
flags |= O_NONBLOCK;
if (fcntl(pfd[0], F_SETFD, flags))
perror("fcntl");
/* verify flags set correctly */
flags = fcntl(pfd[0], F_GETFD);
if (!(flags & O_NONBLOCK)) {
printf("failed to set O_NONBLOCK\n");
exit(EXIT_FAILURE);
}
wait(NULL);
exit(EXIT_SUCCESS);
}
【问题讨论】:
-
这看起来像是
F_GETFD操作中的一个错误。我已经确认这确实将描述符设置为非阻塞并且操作不会阻塞,但F_GETFD仍然返回零。