9

This is a simple echo server in Unix, using nc:

mkfifo fifo
cat fifo | nc -k -l 4458 -v | cat >fifo

(based on this)

As I can see it, the data flow works as follows:

fifo (my named pipe)
 |
 | (using cat)
 |
 v
nc
 |
 | (using cat)
 |
 v
fifo 

And here is the question: why doesn't this work?

nc -k -l 4458 -v >fifo <fifo

You will notice that if you try to telnet to localhost on 4458 you will get a "Connection refused" error.

Razvan
  • 215
  • I don't have an answer but hopefully this might help someone more knowledgeable than me. cat myfifo | nc -k -l 4458 > myfifo also works. If you use a text file, file.txt like so nc -k -l 4458 < file.txt > file.txt The first connection will connect and close (makes sense because the input was truncated and EOF closes the socket), the second connection will become a forgetful echo server: it will echo every other line and save the unechoed lines to the text file. – user1794469 May 19 '16 at 15:13

1 Answers1

10

This is because the netcat command has not even started yet! The shell when trying to open the fifo for input will block. Try

strace cat >fifo <fifo

and you will see nothing. Instead use, for example,

nc -k -l 4458 -v <>fifo >&0

which opens the fifo for read and write as stdin, and then dups it to stdout.


Tracing the full bash command shows that neither the open for read nor write returns (until the opposite open is done):

$ strace -f -e open bash -c 'nc -k -l 4458 -v  >fifo <fifo'
...
Process 3631 attached
[pid  3631] open("fifo", O_WRONLY|O_CREAT|O_TRUNC, 0666

$ strace -f -e open bash -c 'nc -k -l 4458 -v  <fifo >fifo'
...
Process 3684 attached
[pid  3684] open("fifo", O_RDONLY

man 3 mkfifo: Opening a FIFO for reading normally blocks until some other process opens the same FIFO for writing, and vice versa.

meuh
  • 51,383
  • 1
    The blocking is documented: http://www.tldp.org/LDP/lpg/node19.html – thrig May 19 '16 at 15:43
  • Why does the shell block when using ">fifo <fifo"? It would seem that it opens it for writing and then for reading. So, since there is already a handle for writing opened shouldn't it continue normally? – Razvan May 19 '16 at 15:50
  • @Razvan I've updated the answer with the actual strace for the two alternative orders of open of the fifo, and you can see that open for write or read both block. – meuh May 19 '16 at 16:03