2 * File: spc-sm.c $XConsortium: spc-sm.c /main/4 1996/04/21 19:10:39 drk $
5 * (c) Copyright 1989, Hewlett-Packard Company, all rights reserved.
7 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
8 * (c) Copyright 1993, 1994 International Business Machines Corp. *
9 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
10 * (c) Copyright 1993, 1994 Novell, Inc. *
13 #include <bms/sbport.h> /* NOTE: sbport.h must be the first include. */
19 ** Definitions for blocking signals
24 static int (* spc_state_table[16]) (SPC_Channel_Ptr channel, int connector)= {
26 /* old_state new_state */
30 error_fun, /* 00 10 */
32 sigcld_with_reset, /* 01 00 */
34 error_fun, /* 01 10 */
35 error_fun, /* 01 11 */
36 connector_eof_with_reset, /* 10 00 */
37 error_fun, /* 10 01 */
39 error_fun, /* 10 11 */
41 connector_eof, /* 11 01 */
46 /*----------------------------------------------------------------------+*/
47 SPC_Change_State(SPC_Channel_Ptr channel,
51 /*----------------------------------------------------------------------+*/
54 int iomode=channel->IOMode;
55 int old_state=CHANNEL_STATE(iomode);
56 int new_state, state_index;
57 int (*fun)(SPC_Channel_Ptr, int);
60 sigset_t newsigmask, oldsigmask;
62 sigemptyset(&newsigmask);
63 sigemptyset(&oldsigmask);
65 /* Process don't cares */
66 sigaddset(&newsigmask, SIGCHLD);
67 sigprocmask(SIG_BLOCK, &newsigmask, &oldsigmask);
70 data_line=DATA_LINE(old_state);
71 if(process_line == -1)
72 process_line = PROC_LINE(old_state);
74 /* create new state */
76 new_state=MAKE_STATE(data_line, process_line);
78 /* If no state change, return */
80 if(new_state == old_state) {
81 sigprocmask(SIG_SETMASK, &oldsigmask, (sigset_t *)NULL);
85 /* Lookup & process transition function */
87 state_index=MAKE_STATE_INDEX(old_state, new_state);
89 fun=spc_state_table[state_index];
91 if(fun == error_fun) {
92 sigprocmask(SIG_SETMASK, &oldsigmask, (sigset_t *)NULL);
96 channel->IOMode=MAKE_CHANNEL_STATE(iomode, new_state);
98 sigprocmask(SIG_SETMASK, &oldsigmask, (sigset_t *)NULL);
102 funretval=((*fun)(channel, connector));
104 sigprocmask(SIG_SETMASK, &oldsigmask, (sigset_t *)NULL);
109 /* error_fun is not ever called. It is just a placeholder for an
110 error condition in the state table */
112 /*----------------------------------------------------------------------+*/
113 error_fun(SPC_Channel_Ptr UNUSED_PARM(channel),
114 int UNUSED_PARM(connector))
115 /*----------------------------------------------------------------------+*/
123 ** This routine is called when an EOF is detected on a specific
124 ** connector within a channel, but the channel still has a subprocess
125 ** associated with it. It will clear the data ready flag on the
126 ** indicated wire. After that, it will look at all the wires
127 ** associated with the channel and set the channel's data flag to the
128 ** inclusive OR of the individual wire's data flags.
132 /*----------------------------------------------------------------------+*/
133 connector_eof(SPC_Channel_Ptr channel,
135 /*----------------------------------------------------------------------+*/
137 Wire *wire=channel->wires[connector];
140 int iomode=channel->IOMode;
145 wire->flags &= ~SPCIO_DATA;
147 if(IS_SPCIO_STDOUT(iomode)) {
148 tmpwire=channel->wires[STDOUT];
149 channelflag |= IS_SPCIO_DATA(tmpwire->flags);
152 if(IS_SPCIO_STDERR(iomode) && IS_SPCIO_SEPARATE(iomode)) {
153 tmpwire=channel->wires[STDERR];
154 channelflag |= IS_SPCIO_DATA(tmpwire->flags);
158 channel->IOMode |= SPCIO_DATA;
160 channel->IOMode &= ~SPCIO_DATA;
167 ** This routine is called when there is no subprocess associated with
168 ** the channel, and an EOF is detected on a connector. It will first
169 ** call connector_eof on the channel/connector, and if the channel
170 ** does not have its data flag set, it will reset the channel.
176 /*----------------------------------------------------------------------+*/
177 connector_eof_with_reset(SPC_Channel_Ptr channel,
179 /*----------------------------------------------------------------------+*/
181 connector_eof(channel, connector);
182 if(!IS_DATA(channel))
190 ** This routine is called when the child associated with the channel
191 ** dies, and there is no data available to be read on the channel.
192 ** It will simply reset then channel.
196 /*----------------------------------------------------------------------+*/
197 sigcld_with_reset(SPC_Channel_Ptr channel,
198 int UNUSED_PARM(connector))
199 /*----------------------------------------------------------------------+*/
201 mempf0(channel, reset);