diff options
| author | tv <tv@iiso> | 2011-09-20 02:17:23 +0200 | 
|---|---|---|
| committer | tv <tv@iiso> | 2011-09-20 02:17:23 +0200 | 
| commit | e1089de23a7e3b316e0c06b4e60c7f6e05d8d5dd (patch) | |
| tree | 8121c6eeab0aa5ad4af3d04bf70f4ce23ab42c45 /hyper | |
| parent | 0a5e023f09d53a4bc784865005003768bf21b877 (diff) | |
//hyper/process/spawn: initial commit
Diffstat (limited to 'hyper')
| -rwxr-xr-x | hyper/process/spawn | 70 | 
1 files changed, 70 insertions, 0 deletions
diff --git a/hyper/process/spawn b/hyper/process/spawn new file mode 100755 index 00000000..a0043ec7 --- /dev/null +++ b/hyper/process/spawn @@ -0,0 +1,70 @@ +#! /bin/sh +# +# spawn [command [argument ...]] +# +spawn() { +  set -euf + +  # create and change working directory +  wd=`mktemp -d` +  defer rmdir $wd +  cd $wd + +  # create named pipes for the child process's stdio +  mkfifo 0 1 2 +  defer rm 0 1 2 + +  # spawn child process +  (exec 0>&- 1>&- 2>&- 0<>0 1<>1 2<>2 "$@") & +  pid=$! + +  # setup a trap to kill the child process if this (parent) process dies +  defer kill $pid + +  # write child process's pid  +  echo $pid >pid +  defer rm pid + +  # create dummy directory for easier debugging +  mkdir -vp /tmp/dummy +  ln -vsnf $wd/0 $wd/1 $wd/2 $wd/pid /tmp/dummy/ +  defer rm -v /tmp/dummy/0 /tmp/dummy/1 /tmp/dummy/2 /tmp/dummy/pid + +  # wait for the child process's  +  set +e +  wait $pid +  code=$? +  set -e + +  # the child is already dead +  cancel kill $pid + +  # return the same way wait did +  (exit $code) +} + +# +# defer [command [argument ...]] +# +# Defer execution of a command.  Deferred commands are executed in LIFO +# order immediately before the script terminates.  See (golang's defer +# statement for more information how this should work). +# +defer() { +  defer="$*${defer+ +$defer}" +  trap "$defer" EXIT +} + +# +# cancel [command [argument ...]] +# +# Cancel a deferred command.  The arguments have to match exactly a +# prior defer call or else chaos and mayhem shall haunt thee and shi- +# +cancel() { +  defer="`echo "$defer" | grep -Fxv "$*"`" +  trap "$defer" EXIT +} + +spawn "$@"  | 
