1# coprocess.bash
2#
3# vi:set sts=2 sw=2 ai:
4#
5
6coprocess_pid=
7
8#
9# coprocess - Start, control, and end coprocesses.
10#
11function coprocess ()
12{
13  while (( $# > 0 )) ; do
14    case "$1" in
15      #
16      # coprocess close
17      #
18      c|cl|clo|clos|close)
19	shift
20	exec 61>&- 62<&-
21	coprocess_pid=
22	if [ "$1" = "-SIGPIPE" ] ; then
23	  # Only print message in an interactive shell
24	  case "$-" in
25	    *i*)
26	      echo 'SIGPIPE' >&2
27	      ;;
28	  esac
29	  return 1
30	fi
31	return 0
32	;;
33
34      #
35      # coprocess open
36      #
37      o|op|ope|open)
38	shift
39	local fifo="/var/tmp/coprocess.$$.$RANDOM"
40
41	local cmd="/bin/bash"
42	if (( $# > 0 )) ; then
43	  cmd="$@"
44	fi
45
46	mkfifo "$fifo.in" || return $?
47	mkfifo "$fifo.out" || {
48	  ret=$?
49	  rm -f "$fifo.in"
50	  return $?
51	}
52
53	( "$@" <$fifo.in >$fifo.out ; rm -f "$fifo.in" "$fifo.out" ) &
54	coprocess_pid=$!
55	exec 61>$fifo.in 62<$fifo.out
56	return 0
57	;;
58
59      #
60      # coprocess print - write to the coprocess
61      #
62      p|pr|pri|prin|print)
63	shift
64	local old_trap=$(trap -p SIGPIPE)
65	trap 'coprocess close -SIGPIPE' SIGPIPE
66	if [ $# -eq 1 ] && [ "$1" = "--stdin" ] ; then
67	  cat >&61
68	else
69	  echo "$@" >&61
70	fi
71	local ret=$?
72	eval "$old_trap"
73	return $ret
74	;;
75
76      #
77      # coprocess read - read from the coprocess
78      #
79      r|re|rea|read)
80	shift
81	local old_trap=$(trap -p SIGPIPE)
82	trap '_coprocess_close -SIGPIPE' SIGPIPE
83	builtin read "$@" <&62
84	local ret=$?
85	eval "$old_trap"
86	return $ret
87	;;
88
89      s|st|sta|stat|statu|status)
90	if [ -z "$coprocess_pid" ] ; then
91	  echo 'no active coprocess'
92	  return 1
93	else
94	  echo "  coprocess is active [$coprocess_pid]"
95	  return 0
96	fi
97	;;
98
99      *)
100	coprocess print "$@"
101	return $?
102	;;
103    esac
104    shift
105  done
106  coprocess status
107  return $?
108}
109