简体   繁体   中英

read not blocking on named pipe

i have the following bit of C code which reads from a pipe and then should block but it never blocks

int pipe_fd;
int res;
int open_mode = O_RDONLY;
char buf[100];
int bytes_read = 0;

memset (buf, '\0', sizeof(buf));
pipe_fd = open(FIFO_NAME, open_mode);

if (access(FIFO_NAME, F_OK) == -1)
{
    res = mkfifo(FIFO_NAME, 0777);
    if (res != 0)
    {
            fprintf (stderr, "Could not create fifo %s\n", FIFO_NAME);  
            exit (EXIT_FAILURE);
    }
}

for(;;)
{        
    do     
    {     
        res = read(pipe_fd, buf, sizeof(buf));
        bytes_read += res;
    }while (res > 0);

    // process data then go back and block
    ............
}

It is sent a simple buffer by some code in a bash script like this './test 1'

#!/bin/bash

pipe=/tmp/pipe

if [[ ! -p $pipe ]]; then
    echo "Reader not running"
    exit 1
fi

if [[ "$1" ]]; then
     echo "some string" >$pipe
else
     echo "q" >$pipe
fi

I run the C code program in gdb and initially it does block on the read but as soon as i call the bash script the C code no longer blocks , it does successfully read the data from the buffer and then each time it reads there are 0 bytes read so not sure why its no longer blocking. The 'some string' data is correctly received at the other side.

I just need it to sit there waiting for data process it and then go back and wait for more

I run the C code program in gdb and initially it does block on the read but as soon as i call the bash script the C code no longer blocks , it does successfully read the data from the buffer and then each time it reads there are 0 bytes read so not sure why its no longer blocking. The 'some string' data is correctly received at the other side.

0 means EOF. FIFO can be read or written only when there are processes connected to it for both reading and writing. When there are no more writers (your shell scripts terminated) readers are notified about that through read() returning the EOF.

FIFOs behave that way to be compatible with shell pipe logic eg:

$ mkfifo ./tmp1
$ cat < input > ./tmp1 &
$ cat < ./tmp1 > /dev/null

If read() will not return EOF, the second cat would block forever.

I just need it to sit there waiting for data process it and then go back and wait for more

In your C program you have to re open() the FIFO after read() returned the EOF first time.

PS Found quite nice FIFO summary for your. Check the table on the second page.

I think write side shell script close the pipe every time when echo something.

So, the write script need to open the pipe and repeatedly use the opended descriptor to write something and close the opended descripter finally.

你的bash脚本关闭管道,所以C得到一个“eof”条件

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM