spc-sm.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  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)
  10. * any later version.
  11. *
  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
  16. * details.
  17. *
  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
  22. */
  23. /*
  24. * File: spc-sm.c $XConsortium: spc-sm.c /main/4 1996/04/21 19:10:39 drk $
  25. * Language: C
  26. *
  27. * (c) Copyright 1989, Hewlett-Packard Company, all rights reserved.
  28. *
  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. *
  33. */
  34. #include <bms/sbport.h> /* NOTE: sbport.h must be the first include. */
  35. #include <signal.h>
  36. #include <SPC/spcP.h>
  37. /*
  38. **
  39. ** Definitions for blocking signals
  40. **
  41. */
  42. static int (* spc_state_table[16]) (SPC_Channel_Ptr channel, int connector)= {
  43. /* old_state new_state */
  44. NULL, /* 00 00 */
  45. NULL, /* 00 01 */
  46. error_fun, /* 00 10 */
  47. NULL, /* 00 11 */
  48. sigcld_with_reset, /* 01 00 */
  49. NULL, /* 01 01 */
  50. error_fun, /* 01 10 */
  51. error_fun, /* 01 11 */
  52. connector_eof_with_reset, /* 10 00 */
  53. error_fun, /* 10 01 */
  54. NULL, /* 10 10 */
  55. error_fun, /* 10 11 */
  56. NULL, /* 11 00 */
  57. connector_eof, /* 11 01 */
  58. NULL, /* 11 10 */
  59. NULL /* 11 11 */
  60. };
  61. /*----------------------------------------------------------------------+*/
  62. int
  63. SPC_Change_State(SPC_Channel_Ptr channel,
  64. int connector,
  65. int data_line,
  66. int process_line)
  67. /*----------------------------------------------------------------------+*/
  68. {
  69. int iomode=channel->IOMode;
  70. int old_state=CHANNEL_STATE(iomode);
  71. int new_state, state_index;
  72. int (*fun)(SPC_Channel_Ptr, int);
  73. int funretval;
  74. sigset_t newsigmask, oldsigmask;
  75. sigemptyset(&newsigmask);
  76. sigemptyset(&oldsigmask);
  77. /* Process don't cares */
  78. sigaddset(&newsigmask, SIGCHLD);
  79. sigprocmask(SIG_BLOCK, &newsigmask, &oldsigmask);
  80. if(data_line == -1)
  81. data_line=DATA_LINE(old_state);
  82. if(process_line == -1)
  83. process_line = PROC_LINE(old_state);
  84. /* create new state */
  85. new_state=MAKE_STATE(data_line, process_line);
  86. /* If no state change, return */
  87. if(new_state == old_state) {
  88. sigprocmask(SIG_SETMASK, &oldsigmask, (sigset_t *)NULL);
  89. return TRUE;
  90. }
  91. /* Lookup & process transition function */
  92. state_index=MAKE_STATE_INDEX(old_state, new_state);
  93. fun=spc_state_table[state_index];
  94. if(fun == error_fun) {
  95. sigprocmask(SIG_SETMASK, &oldsigmask, (sigset_t *)NULL);
  96. return TRUE;
  97. }
  98. channel->IOMode=MAKE_CHANNEL_STATE(iomode, new_state);
  99. if(!fun) {
  100. sigprocmask(SIG_SETMASK, &oldsigmask, (sigset_t *)NULL);
  101. return TRUE;
  102. }
  103. funretval=((*fun)(channel, connector));
  104. sigprocmask(SIG_SETMASK, &oldsigmask, (sigset_t *)NULL);
  105. return funretval;
  106. }
  107. /* error_fun is not ever called. It is just a placeholder for an
  108. error condition in the state table */
  109. /*----------------------------------------------------------------------+*/
  110. int
  111. error_fun(SPC_Channel_Ptr UNUSED_PARM(channel),
  112. int UNUSED_PARM(connector))
  113. /*----------------------------------------------------------------------+*/
  114. {
  115. return(FALSE);
  116. }
  117. /*
  118. **
  119. ** This routine is called when an EOF is detected on a specific
  120. ** connector within a channel, but the channel still has a subprocess
  121. ** associated with it. It will clear the data ready flag on the
  122. ** indicated wire. After that, it will look at all the wires
  123. ** associated with the channel and set the channel's data flag to the
  124. ** inclusive OR of the individual wire's data flags.
  125. **
  126. */
  127. /*----------------------------------------------------------------------+*/
  128. int
  129. connector_eof(SPC_Channel_Ptr channel,
  130. int connector)
  131. /*----------------------------------------------------------------------+*/
  132. {
  133. Wire *wire=channel->wires[connector];
  134. Wire *tmpwire;
  135. int channelflag=0;
  136. int iomode=channel->IOMode;
  137. if(!wire)
  138. return(FALSE);
  139. wire->flags &= ~SPCIO_DATA;
  140. if(IS_SPCIO_STDOUT(iomode)) {
  141. tmpwire=channel->wires[STDOUT];
  142. channelflag |= IS_SPCIO_DATA(tmpwire->flags);
  143. }
  144. if(IS_SPCIO_STDERR(iomode) && IS_SPCIO_SEPARATE(iomode)) {
  145. tmpwire=channel->wires[STDERR];
  146. channelflag |= IS_SPCIO_DATA(tmpwire->flags);
  147. }
  148. if(channelflag)
  149. channel->IOMode |= SPCIO_DATA;
  150. else
  151. channel->IOMode &= ~SPCIO_DATA;
  152. return(TRUE);
  153. }
  154. /*
  155. **
  156. ** This routine is called when there is no subprocess associated with
  157. ** the channel, and an EOF is detected on a connector. It will first
  158. ** call connector_eof on the channel/connector, and if the channel
  159. ** does not have its data flag set, it will reset the channel.
  160. **
  161. */
  162. /*----------------------------------------------------------------------+*/
  163. int
  164. connector_eof_with_reset(SPC_Channel_Ptr channel,
  165. int connector)
  166. /*----------------------------------------------------------------------+*/
  167. {
  168. connector_eof(channel, connector);
  169. if(!IS_DATA(channel))
  170. XeSPCReset(channel);
  171. return(TRUE);
  172. }
  173. /*
  174. **
  175. ** This routine is called when the child associated with the channel
  176. ** dies, and there is no data available to be read on the channel.
  177. ** It will simply reset then channel.
  178. **
  179. */
  180. /*----------------------------------------------------------------------+*/
  181. int
  182. sigcld_with_reset(SPC_Channel_Ptr channel,
  183. int UNUSED_PARM(connector))
  184. /*----------------------------------------------------------------------+*/
  185. {
  186. mempf0(channel, reset);
  187. return(TRUE);
  188. }