O_NONBLOCK是否被设置文件描述符或底层文件的属性? [英] Is O_NONBLOCK being set a property of the file descriptor or underlying file?

查看:226
本文介绍了O_NONBLOCK是否被设置文件描述符或底层文件的属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我一直在阅读上由The Open Group网站上 的fcntl 打开 ,和 ,我得到的IM pression这是否 O_NONBLOCK 上设置一个文件描述符,因此无论是非阻塞I / O使用的描述,应该是文件描述符的属性而不是基础文件。作为文件描述符手段的属性,例如,如果我复制一个文件描述符或打开另一个描述符到相同的文件,然后我可以使用阻塞I / O一个,并与其他非阻塞I / O。

From what I have been reading on The Open Group website on fcntl, open, read, and write, I get the impression that whether O_NONBLOCK is set on a file descriptor, and hence whether non-blocking I/O is used with the descriptor, should be a property of that file descriptor rather than the underlying file. Being a property of the file descriptor means, for example, that if I duplicate a file descriptor or open another descriptor to the same file, then I can use blocking I/O with one and non-blocking I/O with the other.

与FIFO做实验,但是,看来,它是不可能同时有阻塞I / O描述符和非阻塞I / O描述符的FIFO(所以无论 O_NONBLOCK 设置为底层文件的属性[先进先出]):

Experimenting with a FIFO, however, it appears that it is not possible to have a blocking I/O descriptor and non-blocking I/O descriptor to the FIFO simultaneously (so whether O_NONBLOCK is set is a property of the underlying file [the FIFO]):

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    int fds[2];
    if (pipe(fds) == -1) {
        fprintf(stderr, "`pipe` failed.\n");
        return EXIT_FAILURE;
    }

    int fd0_dup = dup(fds[0]);
    if (fd0_dup <= STDERR_FILENO) {
        fprintf(stderr, "Failed to duplicate the read end\n");
        return EXIT_FAILURE;
    }

    if (fds[0] == fd0_dup) {
        fprintf(stderr, "`fds[0]` should not equal `fd0_dup`.\n");
        return EXIT_FAILURE;
    }

    if ((fcntl(fds[0], F_GETFL) & O_NONBLOCK)) {
        fprintf(stderr, "`fds[0]` should not have `O_NONBLOCK` set.\n");
        return EXIT_FAILURE;
    }

    if (fcntl(fd0_dup, F_SETFL, fcntl(fd0_dup, F_GETFL) | O_NONBLOCK) == -1) {
        fprintf(stderr, "Failed to set `O_NONBLOCK` on `fd0_dup`\n");
        return EXIT_FAILURE;
    }

    if ((fcntl(fds[0], F_GETFL) & O_NONBLOCK)) {
        fprintf(stderr, "`fds[0]` should still have `O_NONBLOCK` unset.\n");
        return EXIT_FAILURE; // RETURNS HERE
    }

    char buf[1];
    if (read(fd0_dup, buf, 1) != -1) {
        fprintf(stderr, "Expected `read` on `fd0_dup` to fail immediately\n");
        return EXIT_FAILURE;
    }
    else if (errno != EAGAIN) {
        fprintf(stderr, "Expected `errno` to be `EAGAIN`\n");
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}

这让我思考:有没有可能有一个非阻塞I / O描述符和阻塞I / O描述符相同的文件,如果是这样,它依赖于文件类型(常规文件,FIFO,块特殊文件,字符特殊文件,插座等)?

This leaves me thinking: is it ever possible to have a non-blocking I/O descriptor and blocking I/O descriptor to the same file and if so, does it depend on the type of file (regular file, FIFO, block special file, character special file, socket, etc.)?

推荐答案

O_NONBLOCK是打开文件描述的属性,而不是文件描述符,也不是底层文件的。

O_NONBLOCK is a property of the open file description, not of the file descriptor, nor of the underlying file.

是的,你可能有单独的文件描述符打开同一个文件,其中之一是阻止和另一个是非阻塞的。

Yes, you could have separate file descriptors open for the same file, one of which is blocking and the other of which is non-blocking.

您需要(创建了一个FIFO来区分使用<一个href=\"http://www.opengroup.org/onlinepubs/9699919799/functions/mkfifo.html\"><$c$c>mkfifo())和管道(使用创建的<一个href=\"http://www.opengroup.org/onlinepubs/9699919799/functions/pipe.html\"><$c$c>pipe()).

You need to distinguish between a FIFO (created using mkfifo()) and a pipe (created using pipe()).

请注意,该阻断状态是打开文件描述的属性,但在最简单的情况下,有文件描述符和打开文件描述之间的一对一的映射。该 的open() 函数调用创建新打开文件描述和指的是打开文件描述一个新的文件描述符。

Note that the blocking status is a property of the 'open file description', but in the simplest cases, there is a one-to-one mapping between file descriptors and open file descriptions. The open() function call creates a new open file description and a new file descriptor that refers to the open file description.

当您使用 DUP() ,你有两个文件描述符共享一个打开文件的描述,和属性都属于打开的文件的描述。 )的描述的fcntl( 说这F_SETFL影响与文件描述符关联的打开文件描述。注意, lseek的() 调整文件与文件描述符关联的打开文件描述的位置 - 所以它影响从原来的1个重复的其他文件描述符

When you use dup(), you have two file descriptors sharing one open file description, and the properties belong to the open file description. The description of fcntl() says that F_SETFL affects the open file description associated with the file descriptor. Note that lseek() adjusts the file position of the open file description associated with the file descriptor - so it affects other file descriptors duplicated from the original one.

删除错误从code,以减少它的处理,你有:

Removing the error handling from your code to reduce it, you have:

int fds[2];
pipe(fds);
int fd0_dup = dup(fds[0]);
fcntl(fd0_dup, F_SETFL, fcntl(fd0_dup, F_GETFL) | O_NONBLOCK);

现在都fd0_dup和FDS [0]引用相同的打开文件描述(因为 DUP的()),因此的fcntl( )操作影响了文件描述符。

Now both fd0_dup and fds[0] refer to the same open file description (because of the dup()), so the fcntl() operation affected both file descriptors.

if ((fcntl(fds[0], F_GETFL) & O_NONBLOCK)) { ... }

因此​​在这里观察到的行为由POSIX必需的。

Hence the observed behaviour here is required by POSIX.

这篇关于O_NONBLOCK是否被设置文件描述符或底层文件的属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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