- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有以下代码:
void
set_fl(int fd, int flags) /* flags are file status flags to turn on */
{
int val;
if ((val = fcntl(fd, F_GETFL, 0)) < 0)
err_sys("fcntl F_GETFL error");
val |= flags; /* turn on flags */
if (fcntl(fd, F_SETFL, val) < 0)
err_sys("fcntl F_SETFL error");
}
int
main(void)
{
char buf[BUFSIZ];
set_fl(STDOUT_FILENO, O_NONBLOCK); //set STDOUT_FILENO to nonblock
if(read(STDIN_FILENO, buf, BUFSIZ)==-1) { //read from STDIN_FILENO
printf("something went wrong with read()! %s\n", strerror(errno));
}
}
如您所见,我将 STDOUT_FILENO
设置为非阻塞模式,但似乎对 STDIN_FILENO
的读取操作立即完成。为什么?
$ ./testprog
something went wrong with read()! Resource temporarily unavailable
谢谢
最佳答案
完全正确:在读取结果后立即执行 errno
打印和 perror
调用导致“资源繁忙”和错误编号 11,或者 EAGAIN/EWOULDBLOCK
,如下代码所示:
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
int main (void) {
char buf;
fcntl (STDOUT_FILENO, F_SETFL, fcntl (STDOUT_FILENO, F_GETFL, 0) | O_NONBLOCK);
fprintf (stderr, "%5d: ", errno); perror("");
read (STDIN_FILENO, &buf, 1);
fprintf (stderr, "%5d: ", errno); perror("");
}
生成:
0: Success
11: Resource temporarily unavailable
原因是文件描述符有两种不同类型的标志(参见详细说明复制文件描述符的部分中的here):
You can duplicate a file descriptor, or allocate another file descriptor that refers to the same open file as the original. Duplicate descriptors share one file position and one set of file status flags (see File Status Flags), but each has its own set of file descriptor flags (see Descriptor Flags).
第一个是file descriptor flags每个文件描述符确实是唯一的。根据文档,FD_CLOEXEC
(在 exec
上关闭)是目前这个阵营中唯一的一个。
所有其他标志都是 file status flags , 并在已复制的文件描述符之间共享。这些包括 I/O operating modes例如 O_NONBLOCK
。
所以,这里发生的是标准输出文件描述符是从标准输入文件描述符复制的(顺序无关紧要,只是一个是从另一个复制的事实),因此在一个上设置非阻塞模式影响所有重复项(并且可能还包括标准错误文件描述符,尽管我尚未确认)。
在重复的文件描述符上使用阻塞模式通常不是一个好主意,也不是子进程可能继承的文件描述符的好主意 - 这些子进程并不总是善意地拥有他们的标准文件行为不当(从他们的角度来看)。
如果您想要对单个文件描述符进行更细粒度的控制,请考虑使用 select
在尝试读取之前检查描述符。
关于linux - STDIN_FILENO 和 STDOUT_FILENO 的非阻塞 I/O 行为很奇怪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9676991/
我对使用“>/home/hel/myfile”执行文件感到困惑。如果 fd 是“/home/hel/myfile”的文件处理程序,这完全等同于 dup2(fd, STDOUT_FILENO) 吗?至于
我有一个奇怪的问题。我的C语言不是很好。我正在尝试创建一个守护进程来在 Linux 中执行基于 bash 脚本的服务。为了方便起见,我简化了代码。下面是我的代码。 #include #include
我想知道为什么取消注释以下程序中的第一个 printf 语句会改变其后续行为: #include #include #include #include int main() { //pri
我正在尝试实现 GNU popen 库,但遇到 dup2 问题。我想将子管道复制到 STDOUT_FILENO 和 STDERR_FILENO。 我在这里对 dup2 有点困惑,因为它在手册页上说 d
我想知道 Linux C 中 stdout 和 STDOUT_FILENO 之间的区别。 经过一番搜索,我得出以下结论。你能帮我复习一下并纠正其中的任何错误吗?谢谢 stdout属于C语言的标准I/O
fd = open("/dev/null", O_RDWR); if (fd == -1) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
这个问题在这里已经有了答案: Difference between fclose and close (4 个答案) 关闭 6 年前。 我想将 STDOUT 重定向到磁盘上的文件。重点是让我程序上的
我有多个进程通过主程序的 fork 产生,这意味着它们输出到相同的标准输出(我想要的)。但是我需要以某种方式防止输出交错。我已经使用 fcntl 锁来同步对日志文件的访问,所以我也想将它用于 stdo
我有以下代码: void set_fl(int fd, int flags) /* flags are file status flags to turn on */ { int val;
我知道这里有很多关于 C 中写入、读取系统调用和文件描述符的问题。我试着搜索了一下,但我真的找不到我要找的东西,所以... 从 STDIN_FILENO 读取时在新行上出现 EOF? 假设我在 tes
我有一项作业正在处理,但我很难完成它。这个想法是编写一个程序 if.c 来执行一个程序,如果成功则执行第二个程序。我应该抑制第一个程序的标准输出并取消抑制第二个程序的标准输出。我在多项测试中收到错误消
我是一名优秀的程序员,十分优秀!