2 * File: local.c $TOG: local.c /main/5 1999/10/14 15:05:57 mgreess $
5 * (c) Copyright 1989, Hewlett-Packard Company, all rights reserved.
7 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
8 * (c) Copyright 1993, 1994 International Business Machines Corp. *
9 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
10 * (c) Copyright 1993, 1994 Novell, Inc. *
13 #define __need_timeval /* Needed for "struct timeval" from <time.h>. */
16 #include <bms/sbport.h>
18 #include <sys/time.h> /* For declaration of select(). */
26 #include <SPC/spc-proto.h>
30 ** Note that the close routines call the parent method AFTER the
31 ** work done for the child method. This is because the parent method
32 ** will do all the deallocation.
36 /*----------------------------------------------------------------------+*/
37 int close_local_channel_object(SPC_Channel_Ptr channel)
38 /*----------------------------------------------------------------------+*/
43 for(wirelist=channel->wire_list; wirelist; wirelist=wirelist->next){
44 spc_close(wirelist->fd[READ_SIDE]);
45 spc_close(wirelist->fd[WRITE_SIDE]);
46 SPC_XtRemoveInput(&wirelist->read_toolkit_id, SPC_Input);
47 SPC_XtRemoveInput(&wirelist->except_toolkit_id, SPC_Exception);
50 call_parent_method(channel, close, (channel), result);
58 /*----------------------------------------------------------------------+*/
59 int write_local_channel_object(SPC_Channel_Ptr channel,
62 /*----------------------------------------------------------------------+*/
67 call_parent_method(channel,
69 (channel, buffer, nbytes),
74 result = SPC_Write_Chars(channel->file_descs[STDIN], buffer, nbytes);
76 SPC_Error(SPC_Writing);
83 /* the function exec_proc_local_channel_object is defined in spc-exec.c */
85 /*----------------------------------------------------------------------+*/
86 int signal_local_channel_object (SPC_Channel_Ptr channel,
88 /*----------------------------------------------------------------------+*/
93 call_parent_method(channel, signal, (channel, sig), result);
98 if(sig == SIGKILL || IS_SPCIO_SIGNAL_PGRP(channel->IOMode))
99 result=kill(-(channel->pid), sig);
101 result=kill(channel->pid, sig);
104 return(errno!=ESRCH);
109 /*----------------------------------------------------------------------+*/
110 int local_channel_object_wait_for_termination(SPC_Channel_Ptr channel)
111 /*----------------------------------------------------------------------+*/
116 call_parent_method(channel, wait_for_termination, (channel), result);
118 if(result==SPC_ERROR)
121 /* Do we need to check for remote channel input here? */
123 while(IS_ACTIVE(channel)) {
126 /* the SIGCLD signal handler will take care of us here */
134 /*----------------------------------------------------------------------+*/
135 remove_logfile_local_channel_object(SPC_Channel_Ptr channel)
136 /*----------------------------------------------------------------------+*/
140 call_parent_method(channel, remove_logfile, (channel), result);
142 if(unlink(channel->logfile)==ERROR) {
143 SPC_Error(SPC_Unlink_Logfile);
147 /* This is malloc'ed memory from open_noio_channel_object() and tempnam() */
148 XeFree(channel->logfile);
153 extern SPC_Channel_Ptr spc_activation_list;
155 /* All this routine does is to look up the channel, and
156 call the generic input handler routine */
158 /*----------------------------------------------------------------------+*/
159 void local_channel_object_input_handler(void * client_data,
161 SPCInputId * UNUSED_PARM(id))
162 /*----------------------------------------------------------------------+*/
165 /* WARNING!!! This routine is NOT XPG3 compliant. The timeval struct */
166 /* is the problem here. */
168 SPC_Channel_Ptr channel=(SPC_Channel_Ptr) client_data;
172 fd_set read_fd_vect, except_fd_vect;
173 SPC_Channel_Ptr tmp, this_ptr;
174 struct timeval timeout; /* Not part of XPG3 !!! */
176 /* This ^&@$#% select is here to get around an X toolkit bug */
178 FD_ZERO(&read_fd_vect);
179 FD_ZERO(&except_fd_vect);
181 FD_SET(fd, &read_fd_vect);
182 FD_SET(fd, &except_fd_vect);
187 #if defined(SVR4) || defined(__osf__) || defined(__hpux)
188 select(max_fds, (fd_set*)&read_fd_vect, NULL, (fd_set*)&except_fd_vect, &timeout);
190 /* UX has select defined with int*, not fd_set* parms */
191 select(max_fds, (int*)&read_fd_vect, NULL, (int*)&except_fd_vect, &timeout);
193 if(! (FD_ISSET(fd, &read_fd_vect) || FD_ISSET(fd, &except_fd_vect))) {
194 return /* (FALSE) */;
197 /* The following is to get around an apparent Xt bug where sometimes
198 the client data pointer passed to me is not the one I was expecting.
201 tmp = spc_activation_list;
204 if((fd == Stdin(tmp)) || (fd == Stderr(tmp)))
211 if(this_ptr != channel)
214 if((connector=SPC_fd_to_connector(channel, fd)) == ERROR) {
215 SPC_Error(SPC_Bad_Fd);
216 return /* (SPC_ERROR) */;
218 len = SPC_Input_Handler(channel, connector);
222 int local_channel_object_send_eof(SPC_Channel_Ptr channel)
224 Wire *wire = channel->wires[STDIN];
226 spc_close(wire->fd[READ_SIDE]);
227 spc_close(wire->fd[WRITE_SIDE]);
228 SPC_XtRemoveInput(&wire->read_toolkit_id, SPC_Input);
229 SPC_XtRemoveInput(&wire->except_toolkit_id, SPC_Exception);