Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Tesing a fifo without opening it?

On Sun, Sep 12, 2010 at 12:02:23PM -0700, Bart Schaefer wrote:
> On Sep 10,  8:35am, Dominik Vogt wrote:
> }
> } I'm writing a multi process scripting system in zsh:
> Aside:  You need to be careful with this sort of thing; if at any point
> the amount of data being written exceeds the kernel buffer size of the
> fifo, the writer will block, and if the other process happens also to
> be writing a reply, you end up with deadlock.  As long as you keep the
> two in lock step alternating with builtin read/print, you're probably
> OK, but with the "send exit to the sub scripts" addition you may be
> venturing into more dangerous territory.
> } So far, this works very well.  Note that reading from an writing to the
> } pipes blocks (in the open() call) until the other end has also opened
> } the pipe.  Also note that the main script may start many concurrent sub
> } scripts and communicate with them through many different fifos.
> Did you consider using the coproc mechanism for this?

Actually, the scripting system started as a bash script (as this
is more easily acceptable to my customer), but I had to abandon
bash does not properly handle sigchld when accessing fifos.  To
sum it up, the scripts are still written for bash's restrictions.

If I started from scratch, I'd use coprocesses.

>  That creates a
> two-way socket instead of separate fifos in the filesystem.  If it's
> important that the fifos be available to processes other than the
> parent and child, then you can't use coproc, but otherwise it's much
> easier to manage because (among other things) the coprocess starts with
> the socket already open.
> You can have multiple coprocesses by copying the magic 'p' descriptor
> to another descriptor with the exec builtin:
>     coproc ...
>     exec {in}<&p {out}>&p
> Now you can do (in the parent)
>     read -u $in ...
>     print -u $out ...
> and you can start another command with coproc without the first one
> getting EOF.  (You will need to stash the values of $in and $out
> before re-using those names in another exec.)

Interesting.  Thank you for that hint.  One problem with my zsh
setup is that it has been working very smoothly for several years
without noteworthy changes, so I hardly ever checkout all the new
and nifty features.  :-)

> } ---- sub script
> } 01 read REQUEST < "$1"
> } 02 echo answer > "$2"
> Of course with the coproc, these are stdin/stdout so you don't need
> $1 and $2 and redirections.  If for some reason you're counting on
> the script to have inherited the parent's stdin/out, you can't use
> coproc.

Actually, the script may exec a c-program that can not use stdin
and stdout for the command channels.  Is it possible to have the
coproc use separate descriptors for stdio and the coproc pipes?

> } 03 # do something
> } 04 while true; do
> } 05   if read -t REQUEST < "$1"; then
> } 06     echo answer > $2
> } 07     test x"$REQUEST" = xexit && exit
> } 08   else
> } 09     # do something else
> } 10     ...
> } 11   fi
> } 12 done
> } ----
> } 
> } Now, the problem is that input redirection in line 5 blocks until
> } the main script also opens the fifo.
> This problem disappears with a coproc, because stdin is already open.
> Just "read -t REQUEST" and you're done.

Yes, that's a strong reason to use coprocs.  I spent several days
to get reading and writing fifos right when there is a c-program
on the other end of the fifo.


Dominik ^_^  ^_^


Dominik Vogt

Messages sorted by: Reverse Date, Date, Thread, Author