G+: So here's a fun problem

David Coles
So here's a fun problem. Given two processes communicating via a pipe, how can you tell if the pipe is full?

At least on Linux it appears that the best (and what looks like the only) way of doing so querying the number of unread bytes using the FIONREAD ioctl. If you get a value like 65536 (the default pipe capacity since 2.6.11) then it's full.

What if it's not a named pipe? Well then you can use /proc/${pid}/fd/${pipe_fd} to gain access to the pipe between the two processes.

fifo_size.py


(+1's) 4
Emil Mikulic
I'm afraid to ask what happens if you attempt a nonblocking write.

David Coles
If you attempt a non-blocking write whilst the pipe is full then you get an EAGAIN, though if bigger than PIPE_BUF (4kiB on Linux) and there's some space then you might just get a partial write. For non-blocking IO it seems you should always expect the worst since it tends to be highly non-standard across differnt Unixes.


pipe(7) - Linux manual page


Emil Mikulic
Sounds about right. :(

David Coles
Sounds like some other Unixes expose the number of unread bytes via st_size (which would be a heck of a lot easier to check) but probably uncommon enough that it's not worth implementing (the Linux implementation has to sum all the buffers to work out the size).

Rae Yip
Sheer genius. ;)

Patrick McLean
Now I just need to rewrite this in C, add some magic to get it to figure out pids etc, give it some pretty formatting and submit it to util-linux.

Though someone really should send a PR to the pipe(7) man page to document that ioctl.