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: 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>
44 #include <SPC/spc-proto.h>
48 ** Note that the close routines call the parent method AFTER the
49 ** work done for the child method. This is because the parent method
50 ** will do all the deallocation.
54 /*----------------------------------------------------------------------+*/
55 int close_local_channel_object(SPC_Channel_Ptr channel)
56 /*----------------------------------------------------------------------+*/
61 for(wirelist=channel->wire_list; wirelist; wirelist=wirelist->next){
62 spc_close(wirelist->fd[READ_SIDE]);
63 spc_close(wirelist->fd[WRITE_SIDE]);
64 SPC_XtRemoveInput(&wirelist->read_toolkit_id, SPC_Input);
65 SPC_XtRemoveInput(&wirelist->except_toolkit_id, SPC_Exception);
68 call_parent_method(channel, close, (channel), result);
76 /*----------------------------------------------------------------------+*/
77 int write_local_channel_object(SPC_Channel_Ptr channel,
80 /*----------------------------------------------------------------------+*/
85 call_parent_method(channel,
87 (channel, buffer, nbytes),
92 result = SPC_Write_Chars(channel->file_descs[STDIN], buffer, nbytes);
94 SPC_Error(SPC_Writing);
101 /* the function exec_proc_local_channel_object is defined in spc-exec.c */
103 /*----------------------------------------------------------------------+*/
104 int signal_local_channel_object (SPC_Channel_Ptr channel,
106 /*----------------------------------------------------------------------+*/
111 call_parent_method(channel, signal, (channel, sig), result);
113 if(result==SPC_ERROR)
116 if(sig == SIGKILL || IS_SPCIO_SIGNAL_PGRP(channel->IOMode))
117 result=kill(-(channel->pid), sig);
119 result=kill(channel->pid, sig);
122 return(errno!=ESRCH);
127 /*----------------------------------------------------------------------+*/
128 int local_channel_object_wait_for_termination(SPC_Channel_Ptr channel)
129 /*----------------------------------------------------------------------+*/
134 call_parent_method(channel, wait_for_termination, (channel), result);
136 if(result==SPC_ERROR)
139 /* Do we need to check for remote channel input here? */
141 while(IS_ACTIVE(channel)) {
144 /* the SIGCLD signal handler will take care of us here */
152 /*----------------------------------------------------------------------+*/
153 int remove_logfile_local_channel_object(SPC_Channel_Ptr channel)
154 /*----------------------------------------------------------------------+*/
158 call_parent_method(channel, remove_logfile, (channel), result);
160 if(unlink(channel->logfile)==ERROR) {
161 SPC_Error(SPC_Unlink_Logfile);
165 /* This is malloc'ed memory from open_noio_channel_object() and tempnam() */
166 XeFree(channel->logfile);
171 extern SPC_Channel_Ptr spc_activation_list;
173 /* All this routine does is to look up the channel, and
174 call the generic input handler routine */
176 /*----------------------------------------------------------------------+*/
177 void local_channel_object_input_handler(void * client_data,
179 SPCInputId * UNUSED_PARM(id))
180 /*----------------------------------------------------------------------+*/
183 /* WARNING!!! This routine is NOT XPG3 compliant. The timeval struct */
184 /* is the problem here. */
186 SPC_Channel_Ptr channel=(SPC_Channel_Ptr) client_data;
190 fd_set read_fd_vect, except_fd_vect;
191 SPC_Channel_Ptr tmp, this_ptr;
192 struct timeval timeout; /* Not part of XPG3 !!! */
194 /* This ^&@$#% select is here to get around an X toolkit bug */
196 FD_ZERO(&read_fd_vect);
197 FD_ZERO(&except_fd_vect);
199 FD_SET(fd, &read_fd_vect);
200 FD_SET(fd, &except_fd_vect);
205 #if defined(SVR4) || defined(__hpux) || defined(__OpenBSD__) || defined(__linux__)
206 select(max_fds, (fd_set*)&read_fd_vect, NULL, (fd_set*)&except_fd_vect, &timeout);
208 /* UX has select defined with int*, not fd_set* parms */
209 select(max_fds, (int*)&read_fd_vect, NULL, (int*)&except_fd_vect, &timeout);
211 if(! (FD_ISSET(fd, &read_fd_vect) || FD_ISSET(fd, &except_fd_vect))) {
212 return /* (FALSE) */;
215 /* The following is to get around an apparent Xt bug where sometimes
216 the client data pointer passed to me is not the one I was expecting.
219 tmp = spc_activation_list;
222 if((fd == Stdin(tmp)) || (fd == Stderr(tmp)))
229 if(this_ptr != channel)
232 if((connector=SPC_fd_to_connector(channel, fd)) == ERROR) {
233 SPC_Error(SPC_Bad_Fd);
234 return /* (SPC_ERROR) */;
236 len = SPC_Input_Handler(channel, connector);
240 int local_channel_object_send_eof(SPC_Channel_Ptr channel)
242 Wire *wire = channel->wires[STDIN];
244 spc_close(wire->fd[READ_SIDE]);
245 spc_close(wire->fd[WRITE_SIDE]);
246 SPC_XtRemoveInput(&wire->read_toolkit_id, SPC_Input);
247 SPC_XtRemoveInput(&wire->except_toolkit_id, SPC_Exception);