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 librararies 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 /*----------------------------------------------------------------------+*/
69 SPC_Change_State(SPC_Channel_Ptr channel,
73 /*----------------------------------------------------------------------+*/
76 int iomode=channel->IOMode;
77 int old_state=CHANNEL_STATE(iomode);
78 int new_state, state_index;
79 int (*fun)(SPC_Channel_Ptr, int);
82 sigset_t newsigmask, oldsigmask;
84 sigemptyset(&newsigmask);
85 sigemptyset(&oldsigmask);
87 /* Process don't cares */
88 sigaddset(&newsigmask, SIGCHLD);
89 sigprocmask(SIG_BLOCK, &newsigmask, &oldsigmask);
92 data_line=DATA_LINE(old_state);
93 if(process_line == -1)
94 process_line = PROC_LINE(old_state);
96 /* create new state */
98 new_state=MAKE_STATE(data_line, process_line);
100 /* If no state change, return */
102 if(new_state == old_state) {
103 sigprocmask(SIG_SETMASK, &oldsigmask, (sigset_t *)NULL);
107 /* Lookup & process transition function */
109 state_index=MAKE_STATE_INDEX(old_state, new_state);
111 fun=spc_state_table[state_index];
113 if(fun == error_fun) {
114 sigprocmask(SIG_SETMASK, &oldsigmask, (sigset_t *)NULL);
118 channel->IOMode=MAKE_CHANNEL_STATE(iomode, new_state);
120 sigprocmask(SIG_SETMASK, &oldsigmask, (sigset_t *)NULL);
124 funretval=((*fun)(channel, connector));
126 sigprocmask(SIG_SETMASK, &oldsigmask, (sigset_t *)NULL);
131 /* error_fun is not ever called. It is just a placeholder for an
132 error condition in the state table */
134 /*----------------------------------------------------------------------+*/
135 error_fun(SPC_Channel_Ptr UNUSED_PARM(channel),
136 int UNUSED_PARM(connector))
137 /*----------------------------------------------------------------------+*/
145 ** This routine is called when an EOF is detected on a specific
146 ** connector within a channel, but the channel still has a subprocess
147 ** associated with it. It will clear the data ready flag on the
148 ** indicated wire. After that, it will look at all the wires
149 ** associated with the channel and set the channel's data flag to the
150 ** inclusive OR of the individual wire's data flags.
154 /*----------------------------------------------------------------------+*/
155 connector_eof(SPC_Channel_Ptr channel,
157 /*----------------------------------------------------------------------+*/
159 Wire *wire=channel->wires[connector];
162 int iomode=channel->IOMode;
167 wire->flags &= ~SPCIO_DATA;
169 if(IS_SPCIO_STDOUT(iomode)) {
170 tmpwire=channel->wires[STDOUT];
171 channelflag |= IS_SPCIO_DATA(tmpwire->flags);
174 if(IS_SPCIO_STDERR(iomode) && IS_SPCIO_SEPARATE(iomode)) {
175 tmpwire=channel->wires[STDERR];
176 channelflag |= IS_SPCIO_DATA(tmpwire->flags);
180 channel->IOMode |= SPCIO_DATA;
182 channel->IOMode &= ~SPCIO_DATA;
189 ** This routine is called when there is no subprocess associated with
190 ** the channel, and an EOF is detected on a connector. It will first
191 ** call connector_eof on the channel/connector, and if the channel
192 ** does not have its data flag set, it will reset the channel.
198 /*----------------------------------------------------------------------+*/
199 connector_eof_with_reset(SPC_Channel_Ptr channel,
201 /*----------------------------------------------------------------------+*/
203 connector_eof(channel, connector);
204 if(!IS_DATA(channel))
212 ** This routine is called when the child associated with the channel
213 ** dies, and there is no data available to be read on the channel.
214 ** It will simply reset then channel.
218 /*----------------------------------------------------------------------+*/
219 sigcld_with_reset(SPC_Channel_Ptr channel,
220 int UNUSED_PARM(connector))
221 /*----------------------------------------------------------------------+*/
223 mempf0(channel, reset);