Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to see if a pipe is empty

Assuming a pipe,

int pipe_fd[2];
pipe(pipe_fd);

We fork, and expect that one process will write into the pipe at an arbitrary time. In one of the processes, we want to be able to check the contents of the pipe without blocking.

i.e. While a typical read will block if nothing is present and the write end remains open. I want to go do other stuff and potentially even read a bit at a time, do some stuff, and then check back to see if there's more, a la:

close(pipe_fd[1]);

while(1){
    if(/**Check pipe contents**/){
        int present_chars = 0;    

        while( read(pipe_fd[0],&buffer[present_chars],1) != 0)
            ++present_chars;

        //do something

    }
    else
        //do something else
}
like image 500
darkpbj Avatar asked Dec 11 '12 00:12

darkpbj


People also ask

How do you know if FIFO is empty?

When a user process attempts to read from an empty pipe (or FIFO), the following happens: If one end of the pipe is closed, 0 is returned, indicating the end of the file. If the write side of the FIFO has closed, read(2) returns 0 to indicate the end of the file.

Which of the following is used to read data from pipe?

The first element of the pipefd array, pipefd[0] is used for reading data from the pipe. The second element of the pipefd array, pipefd[1] is used for writing data to the pipe. On success, the pipe() function returns 0. If an error occurs during pipe initialization, then the pipe() function returns -1.

What happen when you write to a pipe not opened by writing process?

If there is nothing in the pipe (or queue), nothing is read. When other process writes to pipe, you can read it on read side. So it is perfectly valid to read empty pipe (you will read 0 entries). The behavior is described in the relevant man page.


1 Answers

Your logic is wrong in that read will not return 0 when it runs out of characters; instead, it will block until it receives more, unless you put the file in non-blocking mode, but then it will return -1 and set errno to EWOULDBLOCK or EAGAIN rather than returning 0. The only time read can ever return 0 is when the size argument was 0 or end-of-file has been reached. And, for pipes, end-of-file means the writing end of the pipe has been closed; end-of-file status does not occur just because there's not any input available yet.

With that said, the simplest way to check is:

if (poll(&(struct pollfd){ .fd = fd, .events = POLLIN }, 1, 0)==1) {
    /* data available */
}

but unless you're using nonblocking mode, you'll need to make this check before every single read operation. Passing a larger buffer to read rather than doing it a byte-at-a-time would eliminate most of the cost of checking.

like image 104
R.. GitHub STOP HELPING ICE Avatar answered Oct 22 '22 18:10

R.. GitHub STOP HELPING ICE