为stdout打开非阻塞I/O时,操作系统也为stdin打开它是否正确? [英] When non-blocking I/O is turned on for stdout, is it correct for the OS to turn it on for stdin too?

查看:90
本文介绍了为stdout打开非阻塞I/O时,操作系统也为stdin打开它是否正确?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到OS X和Linux上都有一些意外行为.为标准输出打开非阻塞I/O(使用O_NONBLOCK)也为标准输入打开了它!

I have noticed some unexpected behaviour on both OS X and Linux. Turning on non-blocking I/O (using O_NONBLOCK) for standard output turns it on for standard input too!

这些OS的行为是否正确?如果是这样,此行为是否由POSIX定义?如果是这种情况,请指向相关文档.

Are these OSes behaving correctly? If so, is this behaviour defined by POSIX? Please point me to the relevant documentation if this is the case.

这是我用来测试的示例程序:

Here's a example program I used to test this:

#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

int main (int argc, char *argv[]) {
  int flags = fcntl(STDOUT_FILENO, F_GETFL);
  if (argc > 1 && strcmp(argv[1], "1") == 0) {
    fcntl(STDOUT_FILENO, F_SETFL, flags | O_NONBLOCK);
  }
  printf("stdout O_NONBLOCK is: %d\n", fcntl(STDOUT_FILENO, F_GETFL) & O_NONBLOCK);
  printf("stdin O_NONBLOCK is: %d\n", fcntl(STDIN_FILENO, F_GETFL) & O_NONBLOCK);
  return 0;
}

在OS X上:

$ clang -o fd-test fd-test.c
$ ./fd-test
stdout O_NONBLOCK is: 0
stdin O_NONBLOCK is: 0
$ ./fd-test 1
stdout O_NONBLOCK is: 4
stdin O_NONBLOCK is: 4

在Linux上:

$ gcc -o fd-test fd-test.c
$ ./fd-test
stdout O_NONBLOCK is: 0
stdin O_NONBLOCK is: 0
$ ./fd-test 1
stdout O_NONBLOCK is: 2048
stdin O_NONBLOCK is: 2048

推荐答案

从shell启动进程时,stdinstdoutstderr指向相同的文件描述.您的fcntl(1)调用将此文件描述标记为O_NONBLOCK,因此,预期两个文件描述符都标记为O_NONBLOCK.

When a process is started from the shell, stdin, stdout and stderr point to the same file description. This file description is marked as O_NONBLOCK by your fcntl(1) call and therefore expectedly both file descriptors are marked as O_NONBLOCK.

如果确实要从两个文件描述符中写入同一文件,但又希望将其标记为O_NONBLOCK,则需要为同一文件创建一个新的文件描述.如果知道有关文件的文件名,则可以通过使用所需的文件名和标志调用open()来实现.在某些操作系统上,您可以使用特定于平台的API查找文件名,例如/proc/fd虚拟文件系统(包括Linux在内的许多Unices)或Plan 9中的fd2path()函数.请参阅

If you want to indeed write to the same file from two file descriptors but want one to be marked as O_NONBLOCK, you need to create a new file description for the same file. If you know the file name of the file in question, you can achieve this by simply calling open() with the desired file name and flags. On some operating systems, you can find the file name using a platform-specific API, such as the /proc/fd virtual file system (many Unices including Linux) or the fd2path() function from Plan 9. Refer to this question for more details.

请注意,仅调用open("/dev/fd/0", ...)可能无法按预期方式工作,因为如果我没记错的话,它会在某些平台上返回指向相同文件描述的指针.

Note that simply calling open("/dev/fd/0", ...) may not work as intended as it returns a pointer to the same file description on some platforms if I recall correctly.

这篇关于为stdout打开非阻塞I/O时,操作系统也为stdin打开它是否正确?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆