123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- /*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they will be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with these libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
- /*
- * File: spc-sm.c $XConsortium: spc-sm.c /main/4 1996/04/21 19:10:39 drk $
- * Language: C
- *
- * (c) Copyright 1989, Hewlett-Packard Company, all rights reserved.
- *
- * (c) Copyright 1993, 1994 Hewlett-Packard Company *
- * (c) Copyright 1993, 1994 International Business Machines Corp. *
- * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
- * (c) Copyright 1993, 1994 Novell, Inc. *
- */
- #include <bms/sbport.h> /* NOTE: sbport.h must be the first include. */
- #include <signal.h>
- #include <SPC/spcP.h>
- /*
- **
- ** Definitions for blocking signals
- **
- */
- static int (* spc_state_table[16]) (SPC_Channel_Ptr channel, int connector)= {
-
- /* old_state new_state */
-
- NULL, /* 00 00 */
- NULL, /* 00 01 */
- error_fun, /* 00 10 */
- NULL, /* 00 11 */
- sigcld_with_reset, /* 01 00 */
- NULL, /* 01 01 */
- error_fun, /* 01 10 */
- error_fun, /* 01 11 */
- connector_eof_with_reset, /* 10 00 */
- error_fun, /* 10 01 */
- NULL, /* 10 10 */
- error_fun, /* 10 11 */
- NULL, /* 11 00 */
- connector_eof, /* 11 01 */
- NULL, /* 11 10 */
- NULL /* 11 11 */
- };
- /*----------------------------------------------------------------------+*/
- int
- SPC_Change_State(SPC_Channel_Ptr channel,
- int connector,
- int data_line,
- int process_line)
- /*----------------------------------------------------------------------+*/
- {
- int iomode=channel->IOMode;
- int old_state=CHANNEL_STATE(iomode);
- int new_state, state_index;
- int (*fun)(SPC_Channel_Ptr, int);
- int funretval;
- sigset_t newsigmask, oldsigmask;
- sigemptyset(&newsigmask);
- sigemptyset(&oldsigmask);
- /* Process don't cares */
- sigaddset(&newsigmask, SIGCHLD);
- sigprocmask(SIG_BLOCK, &newsigmask, &oldsigmask);
- if(data_line == -1)
- data_line=DATA_LINE(old_state);
- if(process_line == -1)
- process_line = PROC_LINE(old_state);
- /* create new state */
-
- new_state=MAKE_STATE(data_line, process_line);
- /* If no state change, return */
-
- if(new_state == old_state) {
- sigprocmask(SIG_SETMASK, &oldsigmask, (sigset_t *)NULL);
- return TRUE;
- }
- /* Lookup & process transition function */
- state_index=MAKE_STATE_INDEX(old_state, new_state);
-
- fun=spc_state_table[state_index];
- if(fun == error_fun) {
- sigprocmask(SIG_SETMASK, &oldsigmask, (sigset_t *)NULL);
- return TRUE;
- }
-
- channel->IOMode=MAKE_CHANNEL_STATE(iomode, new_state);
- if(!fun) {
- sigprocmask(SIG_SETMASK, &oldsigmask, (sigset_t *)NULL);
- return TRUE;
- }
- funretval=((*fun)(channel, connector));
- sigprocmask(SIG_SETMASK, &oldsigmask, (sigset_t *)NULL);
- return funretval;
- }
- /* error_fun is not ever called. It is just a placeholder for an
- error condition in the state table */
- /*----------------------------------------------------------------------+*/
- int
- error_fun(SPC_Channel_Ptr UNUSED_PARM(channel),
- int UNUSED_PARM(connector))
- /*----------------------------------------------------------------------+*/
- {
- return(FALSE);
- }
- /*
- **
- ** This routine is called when an EOF is detected on a specific
- ** connector within a channel, but the channel still has a subprocess
- ** associated with it. It will clear the data ready flag on the
- ** indicated wire. After that, it will look at all the wires
- ** associated with the channel and set the channel's data flag to the
- ** inclusive OR of the individual wire's data flags.
- **
- */
- /*----------------------------------------------------------------------+*/
- int
- connector_eof(SPC_Channel_Ptr channel,
- int connector)
- /*----------------------------------------------------------------------+*/
- {
- Wire *wire=channel->wires[connector];
- Wire *tmpwire;
- int channelflag=0;
- int iomode=channel->IOMode;
- if(!wire)
- return(FALSE);
- wire->flags &= ~SPCIO_DATA;
- if(IS_SPCIO_STDOUT(iomode)) {
- tmpwire=channel->wires[STDOUT];
- channelflag |= IS_SPCIO_DATA(tmpwire->flags);
- }
- if(IS_SPCIO_STDERR(iomode) && IS_SPCIO_SEPARATE(iomode)) {
- tmpwire=channel->wires[STDERR];
- channelflag |= IS_SPCIO_DATA(tmpwire->flags);
- }
- if(channelflag)
- channel->IOMode |= SPCIO_DATA;
- else
- channel->IOMode &= ~SPCIO_DATA;
- return(TRUE);
- }
- /*
- **
- ** This routine is called when there is no subprocess associated with
- ** the channel, and an EOF is detected on a connector. It will first
- ** call connector_eof on the channel/connector, and if the channel
- ** does not have its data flag set, it will reset the channel.
- **
- */
-
- /*----------------------------------------------------------------------+*/
- int
- connector_eof_with_reset(SPC_Channel_Ptr channel,
- int connector)
- /*----------------------------------------------------------------------+*/
- {
- connector_eof(channel, connector);
- if(!IS_DATA(channel))
- XeSPCReset(channel);
- return(TRUE);
- }
- /*
- **
- ** This routine is called when the child associated with the channel
- ** dies, and there is no data available to be read on the channel.
- ** It will simply reset then channel.
- **
- */
- /*----------------------------------------------------------------------+*/
- int
- sigcld_with_reset(SPC_Channel_Ptr channel,
- int UNUSED_PARM(connector))
- /*----------------------------------------------------------------------+*/
- {
- mempf0(channel, reset);
- return(TRUE);
- }
|