On Thu, Jul 27, 2006 at 09:40:21PM -0600, Andrew McNabb wrote:
> I'm having a really weird problem with Named Pipes.  I can honestly say
> that I have no clue what's going on.  Heck, I always thought that the
> following two lines were equivalent:
> 
> somecommand >a <b
> somecommand <b >a
> 
> It turns out I was always wrong.  I've got a full description with code
> posted at:
> 
> http://www.mcnabbs.org/andrew/linux/pipemystery/
> 
> Here's your chance to show off your deep understanding. :)

First, another example, then the explanation:

$ mkfifo foo.fifo
$ strace cat foo.fifo
  - Note that cat hangs while trying to open foo.fifo

In another shell:
$ echo foo > foo.fifo
  - Note that cat in the first shell finally succeeds in opening the
    fifo and catting the contents.

It appears that you can't open a pipe for reading unless it's been
opened for writing already.

So, here's what happens in the non-working version of mystery.sh and
httpget.sh on the webpage you linked to:

nc -v www.mcnabbs.org 80 <$FIFO1 >$FIFO2 &
 - open($FIFO1, O_RDONLY) -- $FIFO1 hasn't been opened for writing, this
   blocks
./httpget.sh <$FIFO2 >$FIFO1
 - open($FIFO1, O_RDONLY) -- $FIFO2 hasn't been opened for writing, this
   blocks

Hence, deadlock.

The version that works;
nc -v www.mcnabbs.org 80 <$FIFO1 >$FIFO2 &
 - open($FIFO1, O_RDONLY) -- $FIFO1 hasn't been opened for writing, this
      blocks
./httpget.sh >$FIFO1 <$FIFO2
 - open($FIFO1, O_WRONLY) -- success
 - nc now unblocks on the open($FIFO1, O_RDONLY)
 - $FIFO2 is opened in a similar manner.

Here's the relevant text from fifo(4):

  The  kernel  maintains  exactly one pipe object for each FIFO special
  file that is opened by at least one process.  The FIFO must be opened on
  both ends  (reading  and  writing) before data can be passed.  Normally,
  opening the FIFO blocks until the other end is opened also.

  A process can open a FIFO in non-blocking mode. In this case, opening
  for read  only  will  succeed  even if noone has opened on the write
  side yet; opening for write only will fail with ENXIO (no such device
  or address) unless the other end has already been opened.

--
Byron Clark

Attachment: signature.asc
Description: Digital signature

/*
PLUG: http://plug.org, #utah on irc.freenode.net
Unsubscribe: http://plug.org/mailman/options/plug
Don't fear the penguin.
*/

Reply via email to