I am working on a flow-based programming system called net2sh. It is currently based on shell tools connected by named pipes. Several processes work together to get the job done, communicating over named pipes, not unlike a production line in a factory.

In general it is working delightfully well, however there is one major problem with it. In the case where processes are communicating over two or more named pipes, the "sending" process and "receiving" process must open the pipes in the same order. This is because when a process opens a named pipe, it blocks until the other end has also been opened.

I want a way to avoid this, without spawning extra "helper" processes for each pipe, without having to hack existing components, and without having to mess with the program networks to avoid this problem.

Ideally I am looking for some "non-blocking fifo" option, where "open" on a fifo always succeeds immediately but subsequent operations may block if the pipe buffer is full (or empty, for read)... I'd even consider using a kernel patch to that effect. According to fifo(7) O_NONBLOCK does do something different when opening fifos, not what I want exactly, and in order to use that I would have to rewrite every existing shell tool such as cat.

Here is a minimal example which deadlocks:

mkfifo a b
(> a; > b; ) &
(< b; < a; ) &
wait

If you can help me to solve this sensibly I will be very grateful!

share|edit|close|delete|flag

1 Answer 1

There is a good description of using O_NONBLOCK with named pipes here: How do I perform a non-blocking fopen on a named pipe (mkfifo)?

It sounds like you want it to work in your entire environment without changing any C code. Therefore, one approach would be to set LD_PRELOAD to some shared library which contains a wrapper for open(2) which adds O_NONBLOCK to the flags whenever pathname refers to a named pipe.

A concise example of using LD_PRELOAD to override a library function is here: https://www.technovelty.org/c/using-ld_preload-to-override-a-function.html

Whether this actually works in practice without breaking anything else, you'll have to find out for yourself (please let us know!).

share|edit|flag
    
Thanks, that's a good idea. I think I would have to do some additional hackery, not just add O_NONBLOCK to open, but it might be do-able. Much appreciated. LD_PRELOAD, while somewhat evil, is safer and less difficult than patching the kernel! –  Sam Watkins Feb 4 at 2:31  

Your Answer