2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
24 * File: spc-sm.c $XConsortium: spc-sm.c /main/4 1996/04/21 19:10:39 drk $
27 * (c) Copyright 1989, Hewlett-Packard Company, all rights reserved.
29 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
30 * (c) Copyright 1993, 1994 International Business Machines Corp. *
31 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
32 * (c) Copyright 1993, 1994 Novell, Inc. *
35 #include <bms/sbport.h> /* NOTE: sbport.h must be the first include. */
41 ** Definitions for blocking signals
46 static int (* spc_state_table[16]) (SPC_Channel_Ptr channel, int connector)= {
48 /* old_state new_state */
52 error_fun, /* 00 10 */
54 sigcld_with_reset, /* 01 00 */
56 error_fun, /* 01 10 */
57 error_fun, /* 01 11 */
58 connector_eof_with_reset, /* 10 00 */
59 error_fun, /* 10 01 */
61 error_fun, /* 10 11 */
63 connector_eof, /* 11 01 */
68 /*----------------------------------------------------------------------+*/
70 SPC_Change_State(SPC_Channel_Ptr channel,
74 /*----------------------------------------------------------------------+*/
77 int iomode=channel->IOMode;
78 int old_state=CHANNEL_STATE(iomode);
79 int new_state, state_index;
80 int (*fun)(SPC_Channel_Ptr, int);
83 sigset_t newsigmask, oldsigmask;
85 sigemptyset(&newsigmask);
86 sigemptyset(&oldsigmask);
88 /* Process don't cares */
89 sigaddset(&newsigmask, SIGCHLD);
90 sigprocmask(SIG_BLOCK, &newsigmask, &oldsigmask);
93 data_line=DATA_LINE(old_state);
94 if(process_line == -1)
95 process_line = PROC_LINE(old_state);
97 /* create new state */
99 new_state=MAKE_STATE(data_line, process_line);
101 /* If no state change, return */
103 if(new_state == old_state) {
104 sigprocmask(SIG_SETMASK, &oldsigmask, (sigset_t *)NULL);
108 /* Lookup & process transition function */
110 state_index=MAKE_STATE_INDEX(old_state, new_state);
112 fun=spc_state_table[state_index];
114 if(fun == error_fun) {
115 sigprocmask(SIG_SETMASK, &oldsigmask, (sigset_t *)NULL);
119 channel->IOMode=MAKE_CHANNEL_STATE(iomode, new_state);
121 sigprocmask(SIG_SETMASK, &oldsigmask, (sigset_t *)NULL);
125 funretval=((*fun)(channel, connector));
127 sigprocmask(SIG_SETMASK, &oldsigmask, (sigset_t *)NULL);
132 /* error_fun is not ever called. It is just a placeholder for an
133 error condition in the state table */
135 /*----------------------------------------------------------------------+*/
137 error_fun(SPC_Channel_Ptr UNUSED_PARM(channel),
138 int UNUSED_PARM(connector))
139 /*----------------------------------------------------------------------+*/
147 ** This routine is called when an EOF is detected on a specific
148 ** connector within a channel, but the channel still has a subprocess
149 ** associated with it. It will clear the data ready flag on the
150 ** indicated wire. After that, it will look at all the wires
151 ** associated with the channel and set the channel's data flag to the
152 ** inclusive OR of the individual wire's data flags.
156 /*----------------------------------------------------------------------+*/
158 connector_eof(SPC_Channel_Ptr channel,
160 /*----------------------------------------------------------------------+*/
162 Wire *wire=channel->wires[connector];
165 int iomode=channel->IOMode;
170 wire->flags &= ~SPCIO_DATA;
172 if(IS_SPCIO_STDOUT(iomode)) {
173 tmpwire=channel->wires[STDOUT];
174 channelflag |= IS_SPCIO_DATA(tmpwire->flags);
177 if(IS_SPCIO_STDERR(iomode) && IS_SPCIO_SEPARATE(iomode)) {
178 tmpwire=channel->wires[STDERR];
179 channelflag |= IS_SPCIO_DATA(tmpwire->flags);
183 channel->IOMode |= SPCIO_DATA;
185 channel->IOMode &= ~SPCIO_DATA;
192 ** This routine is called when there is no subprocess associated with
193 ** the channel, and an EOF is detected on a connector. It will first
194 ** call connector_eof on the channel/connector, and if the channel
195 ** does not have its data flag set, it will reset the channel.
201 /*----------------------------------------------------------------------+*/
203 connector_eof_with_reset(SPC_Channel_Ptr channel,
205 /*----------------------------------------------------------------------+*/
207 connector_eof(channel, connector);
208 if(!IS_DATA(channel))
216 ** This routine is called when the child associated with the channel
217 ** dies, and there is no data available to be read on the channel.
218 ** It will simply reset then channel.
222 /*----------------------------------------------------------------------+*/
224 sigcld_with_reset(SPC_Channel_Ptr channel,
225 int UNUSED_PARM(connector))
226 /*----------------------------------------------------------------------+*/
228 mempf0(channel, reset);