How to "cross" stdin and stdout of two programs? Specifically, I have 2 programs call pgm1 and pgm2, they are interactive tic-tac-toe games. They both output a number (0to8) indicating position where it wants to mark and expect another number (0to8) indicating where the user wants to mark. The difference between the two is pgm1 makes first move and pgm2 makes second move. They both work fine via interactive user. Can they be made to play against each other using io redirection?

I tried the following things in vain:

  1. Open pgm2 in a separate terminal (it waits for input), find it's pid. Then run pgm1 in another terminal ./pgm1 < /proc/pid_pgm2/fd/1 > /proc/pid_pgm2/fd/0
  2. Made 2 pipes using mkfifo, say pipe1 and pipe2 and ran the following in two different terminals: ./pgm1 < pipe1 > pipe2 and ./pgm2 < pipe2 > pipe1
  3. tried the above two, running pgm1 before pgm2, running pgm2 before pgm1
    I made sure to use fflush(stdout) in both the programs, immediately after using printf().

Could anyone tell me what i am missing / or going wrong / or is this even possible?


You should be able to get this to work with a FIFO and a pipe.

$ mkfifo fifo
$ ./pgm2 < fifo | ./pgm1 > fifo

Program two's input is the fifo, and outputs to the pipe. Program one's input is the pipe and outputs to the fifo.

Be warned though: this is very racy in general, and can deadlock if the "ping/pong" between the processes isn't perfect.

See also this Stack Overflow question: How to redirect stdout of 2nd process back to stdin of 1st process?

  • Thanks it is working... Just to know, is this not equivalent to the 2nd point that i tried? why is this working while that isn't? – kumar Sep 27 '13 at 9:41

You've got a deadlock in your: ./pgm1 < pipe1 > pipe2 and ./pgm2 < pipe2 > pipe1

The open("pipe1", O_RDONLY) done by the shell prior to executing pgm1 will block until something else does a writing open on that same pipe. Until that's done, it won't do the next open("pipe2", O_WRONLY).

Same for the other one. The open("pipe2", O_RDONLY) will block and because the open("pipe2", O_WRONLY) will not be done since the other shell is waiting for a writer on pipe1, you've got a deadlock.

Had you written it

pgm1 < pipe1 > pipe2 & pgm2 > pipe1 < pipe2

It would have worked.

On Linux, you can also write it:

{ pgm1 <&3 3<&- | pgm2 3<&-; } 3< /dev/fd/1 | :

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.