bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: bash blocking on exec assigning an output file descriptor to a fifo


From: Eric Blake
Subject: Re: bash blocking on exec assigning an output file descriptor to a fifo
Date: Tue, 14 Feb 2012 14:31:19 -0700
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:10.0) Gecko/20120131 Thunderbird/10.0

On 02/14/2012 02:04 PM, Øyvind Hvidsten wrote:
> Please correct any mistakes in my wording, as I would very much like to
> be able to use the correct terms when describing this. Also, please ask
> if anything is unclear :)
> 
> My problem occurs when I do the following:
> mkfifo foo; exec 3<"foo"; echo done
> 
> This blocks on the exec statement, and never reaches the echo statement,

Correct.

> even though I don't think I've asked bash to read from that file
> descriptor (yet).

But POSIX says that it is not just reads from a fifo that block, but
open() itself will block.  And you _did_ ask bash to open(O_RDONLY) the
fifo into fd 3, which means it will block until there is a writer.

> The plan was to use "read -t 0 <&3" at a later stage
> to check if something is available there.

Then don't open it for reading until that later point:

read -t 0 <foo

> 
> The following series of statements will however not block and echo
> "done" immediately:
> mkfifo foo; exec 3<>"foo"; echo done

This is inherently non-portable - it says to open "foo" with O_RDWR
privileges, which POSIX says does not have to work (and on cygwin, it
does not work).  But on Linux, where it does work, it doesn't block,
since you are opening a writer at the same time as the reader, so you've
gotten past the open() block and can now rely on the read() and write()
blocking.

> 
> This also blocks:
> mkfifo foo; exec 3>"foo"; exec 3<"foo"; echo done

Yep.

> 
> Why is this?

Opening a fifo for writing without a reader also blocks, also per POSIX.

If you want a single shell script to portably handle both reading and
writing into the same fifo, then you have to use a subshell and
backgrounding in order to split the shell script into two processes, one
reading and one writing, and recognize that whichever of the parent or
subshell uses the fifo first will block until the counterpart process
opens the same fifo in the other direction.

-- 
Eric Blake   eblake@redhat.com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]