Non-blocking read on pipe

和自甴很熟 提交于 2019-12-04 09:10:11

There is nothing special to pipe and O_NONBLOCK. The following example work as expected. I did not check every retval from every call to make the example a bit more readable. A real world application must do the checks.

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

int main()
{
    int fds[2];
    pid_t pid;
    char buf[100];

    pipe(fds);

    pid = fork();

    if ( pid )
    {
        while (1 )
        {
            memcpy( buf, "abcdefghi\0",10);
            write( fds[1], buf, 10);
            sleep(2);
        }
    }
    else
    {
        int retval = fcntl( fds[0], F_SETFL, fcntl(fds[0], F_GETFL) | O_NONBLOCK);
        printf("Ret from fcntl: %d\n", retval);
        while (1)
        {
            ssize_t r=read( fds[0], buf, 10 );
            printf("read: %d\n", r);

            if ( r > 0 )
            {
                printf("Buffer: %s\n", buf);
            }
            else
            {
                printf("Read nothing\n");
                perror("Error was");
                sleep(1);
            }
        }
    }
}

After writing my example I inspect your code and found:

flags = fcntl(pfd[0], F_GETFD);
flags |= O_NONBLOCK;
if (fcntl(pfd[0], F_SETFD, flags))

Please change F_SETFD to F_SETFL and also for the get operation. You would not change the file descriptor flags but the file descriptor status flags :-)

From man 3 fcntl:

File descriptor flags The following commands manipulate the flags associated with a file descriptor. Currently, only one such flag is defined: FD_CLOEXEC, the close-on-exec flag. If the FD_CLOEXEC bit is 0, the file descriptor will remain open across an execve(2), otherwise it will be closed.

File status flags Each open file description has certain associated status flags, ini‐ tialized by open(2) and possibly modified by fcntl(). Duplicated file descriptors (made with dup(2), fcntl(F_DUPFD), fork(2), etc.) refer to the same open file description, and thus share the same file status flags.

F_SETFL (int) Set the file status flags to the value specified by arg. File access mode (O_RDONLY, O_WRONLY, O_RDWR) and file creation flags (i.e., O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC) in arg are ignored. On Linux this command can change only the O_APPEND, O_ASYNC, O_DIRECT, O_NOATIME, and O_NONBLOCK flags. It is not possible to change the O_DSYNC and O_SYNC flags; see BUGS, below.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!