aboutsummaryrefslogtreecommitdiffstats
path: root/examples/functions/coproc.bash
blob: 61dc8d7464dd826d49cee7ecd7293b467799b944 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# coprocess.bash
#
# vi:set sts=2 sw=2 ai:
#

coprocess_pid=

#
# coprocess - Start, control, and end coprocesses.
#
function coprocess ()
{
  while (( $# > 0 )) ; do
    case "$1" in
      #
      # coprocess close
      #
      c|cl|clo|clos|close)
	shift
	exec 61>&- 62<&-
	coprocess_pid=
	if [ "$1" = "-SIGPIPE" ] ; then
	  # Only print message in an interactive shell
	  case "$-" in
	    *i*)
	      echo 'SIGPIPE' >&2
	      ;;
	  esac
	  return 1
	fi
	return 0
	;;

      #
      # coprocess open
      #
      o|op|ope|open)
	shift
	local fifo="/var/tmp/coprocess.$$.$RANDOM"

	local cmd="/bin/bash"
	if (( $# > 0 )) ; then
	  cmd="$@"
	fi

	mkfifo "$fifo.in" || return $?
	mkfifo "$fifo.out" || {
	  ret=$?
	  rm -f "$fifo.in"
	  return $?
	}

	( "$@" <$fifo.in >$fifo.out ; rm -f "$fifo.in" "$fifo.out" ) &
	coprocess_pid=$!
	exec 61>$fifo.in 62<$fifo.out
	return 0
	;;

      #
      # coprocess print - write to the coprocess
      #
      p|pr|pri|prin|print)
	shift
	local old_trap=$(trap -p SIGPIPE)
	trap 'coprocess close -SIGPIPE' SIGPIPE
	if [ $# -eq 1 ] && [ "$1" = "--stdin" ] ; then
	  cat >&61
	else
	  echo "$@" >&61
	fi
	local ret=$?
	eval "$old_trap"
	return $ret
	;;

      #
      # coprocess read - read from the coprocess
      #
      r|re|rea|read)
	shift
	local old_trap=$(trap -p SIGPIPE)
	trap '_coprocess_close -SIGPIPE' SIGPIPE
	builtin read "$@" <&62
	local ret=$?
	eval "$old_trap"
	return $ret
	;;

      s|st|sta|stat|statu|status)
	if [ -z "$coprocess_pid" ] ; then
	  echo 'no active coprocess'
	  return 1
	else
	  echo "  coprocess is active [$coprocess_pid]"
	  return 0
	fi
	;;

      *)
	coprocess print "$@"
	return $?
	;;
    esac
    shift
  done
  coprocess status
  return $?
}