bash blocking on exec assigning an output file descriptor to a fifo
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, even though I don't think I've asked bash to read from that file descriptor (yet). The plan was to use "read -t 0 <&3" at a later stage to check if something is available there. The following series of statements will however not block and echo "done" immediately: mkfifo foo; exec 3<>"foo"; echo done This also blocks: mkfifo foo; exec 3>"foo"; exec 3<"foo"; echo done Why is this? My current version of bash: GNU bash, version 4.1.5(1)-release (x86_64-pc-linux-gnu)
Re: bash blocking on exec assigning an output file descriptor to a fifo
On 2/14/12 4: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, > even though I don't think I've asked bash to read from that file descriptor > (yet). The plan was to use "read -t 0 <&3" at a later stage to check if > something is available there. This is from the Posix description of `open'. Bash uses O_WRONLY and O_RDONLY when opening files for output or input, respectively (> and <). It does not use O_NONBLOCK. == When opening a FIFO with O_RDONLY or O_WRONLY set: If O_NONBLOCK is set, an open() for reading-only shall return without delay. An open() for writing-only shall return an error if no process currently has the file open for reading. If O_NONBLOCK is clear, an open() for reading-only shall block the calling thread until a thread opens the file for writing. An open() for writing-only shall block the calling thread until a thread opens the file for reading. == exec 3<>foo works because it uses O_RDWR. This is just how FIFOs work. Chet -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/
Re: bash blocking on exec assigning an output file descriptor to a fifo
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 > 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 ebl...@redhat.com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
Re: bash blocking on exec assigning an output file descriptor to a fifo
O_NONBLOCK is up there in things I wouldn't mind using. Namely, having access to errno. I don't see any way of determining the "fullness" of a buffer even through /proc/self/fdinfo/ on Linux. -- Dan Douglas signature.asc Description: This is a digitally signed message part.