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: local.c $TOG: local.c /main/5 1999/10/14 15:05:57 mgreess $
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 #define __need_timeval /* Needed for "struct timeval" from <time.h>. */
38 #include <bms/sbport.h>
40 #include <sys/time.h> /* For declaration of select(). */
48 #include <SPC/spc-proto.h>
52 ** Note that the close routines call the parent method AFTER the
53 ** work done for the child method. This is because the parent method
54 ** will do all the deallocation.
58 /*----------------------------------------------------------------------+*/
59 int close_local_channel_object(SPC_Channel_Ptr channel)
60 /*----------------------------------------------------------------------+*/
65 for(wirelist=channel->wire_list; wirelist; wirelist=wirelist->next){
66 spc_close(wirelist->fd[READ_SIDE]);
67 spc_close(wirelist->fd[WRITE_SIDE]);
68 SPC_XtRemoveInput(&wirelist->read_toolkit_id, SPC_Input);
69 SPC_XtRemoveInput(&wirelist->except_toolkit_id, SPC_Exception);
72 call_parent_method(channel, close, (channel), result);
80 /*----------------------------------------------------------------------+*/
81 int write_local_channel_object(SPC_Channel_Ptr channel,
84 /*----------------------------------------------------------------------+*/
89 call_parent_method(channel,
91 (channel, buffer, nbytes),
96 result = SPC_Write_Chars(channel->file_descs[STDIN], buffer, nbytes);
98 SPC_Error(SPC_Writing);
105 /* the function exec_proc_local_channel_object is defined in spc-exec.c */
107 /*----------------------------------------------------------------------+*/
108 int signal_local_channel_object (SPC_Channel_Ptr channel,
110 /*----------------------------------------------------------------------+*/
115 call_parent_method(channel, signal, (channel, sig), result);
117 if(result==SPC_ERROR)
120 if(sig == SIGKILL || IS_SPCIO_SIGNAL_PGRP(channel->IOMode))
121 result=kill(-(channel->pid), sig);
123 result=kill(channel->pid, sig);
126 return(errno!=ESRCH);
131 /*----------------------------------------------------------------------+*/
132 int local_channel_object_wait_for_termination(SPC_Channel_Ptr channel)
133 /*----------------------------------------------------------------------+*/
138 call_parent_method(channel, wait_for_termination, (channel), result);
140 if(result==SPC_ERROR)
143 /* Do we need to check for remote channel input here? */
145 while(IS_ACTIVE(channel)) {
148 /* the SIGCLD signal handler will take care of us here */
156 /*----------------------------------------------------------------------+*/
157 remove_logfile_local_channel_object(SPC_Channel_Ptr channel)
158 /*----------------------------------------------------------------------+*/
162 call_parent_method(channel, remove_logfile, (channel), result);
164 if(unlink(channel->logfile)==ERROR) {
165 SPC_Error(SPC_Unlink_Logfile);
169 /* This is malloc'ed memory from open_noio_channel_object() and tempnam() */
170 XeFree(channel->logfile);
175 extern SPC_Channel_Ptr spc_activation_list;
177 /* All this routine does is to look up the channel, and
178 call the generic input handler routine */
180 /*----------------------------------------------------------------------+*/
181 void local_channel_object_input_handler(void * client_data,
183 SPCInputId * UNUSED_PARM(id))
184 /*----------------------------------------------------------------------+*/
187 /* WARNING!!! This routine is NOT XPG3 compliant. The timeval struct */
188 /* is the problem here. */
190 SPC_Channel_Ptr channel=(SPC_Channel_Ptr) client_data;
194 fd_set read_fd_vect, except_fd_vect;
195 SPC_Channel_Ptr tmp, this_ptr;
196 struct timeval timeout; /* Not part of XPG3 !!! */
198 /* This ^&@$#% select is here to get around an X toolkit bug */
200 FD_ZERO(&read_fd_vect);
201 FD_ZERO(&except_fd_vect);
203 FD_SET(fd, &read_fd_vect);
204 FD_SET(fd, &except_fd_vect);
209 #if defined(SVR4) || defined(__osf__) || defined(__hpux)
210 select(max_fds, (fd_set*)&read_fd_vect, NULL, (fd_set*)&except_fd_vect, &timeout);
212 /* UX has select defined with int*, not fd_set* parms */
213 select(max_fds, (int*)&read_fd_vect, NULL, (int*)&except_fd_vect, &timeout);
215 if(! (FD_ISSET(fd, &read_fd_vect) || FD_ISSET(fd, &except_fd_vect))) {
216 return /* (FALSE) */;
219 /* The following is to get around an apparent Xt bug where sometimes
220 the client data pointer passed to me is not the one I was expecting.
223 tmp = spc_activation_list;
226 if((fd == Stdin(tmp)) || (fd == Stderr(tmp)))
233 if(this_ptr != channel)
236 if((connector=SPC_fd_to_connector(channel, fd)) == ERROR) {
237 SPC_Error(SPC_Bad_Fd);
238 return /* (SPC_ERROR) */;
240 len = SPC_Input_Handler(channel, connector);
244 int local_channel_object_send_eof(SPC_Channel_Ptr channel)
246 Wire *wire = channel->wires[STDIN];
248 spc_close(wire->fd[READ_SIDE]);
249 spc_close(wire->fd[WRITE_SIDE]);
250 SPC_XtRemoveInput(&wire->read_toolkit_id, SPC_Input);
251 SPC_XtRemoveInput(&wire->except_toolkit_id, SPC_Exception);