/*----------------------------------------------------------------------+*/ void SPC_Channel_Terminated(SPC_Channel_Ptr channel) /*----------------------------------------------------------------------+*/ { int type, cause; SPC_Change_State(channel, 0, -1, 0); /* Set the close timeout. If we are on a PTY, we will return after two seconds if we are waiting for EOF */ channel->close_timeout=2; if(IS_DATA(channel) && (channel->Input_Handler)) { while(IS_SPCIO_DATA(channel->wires[STDOUT]->flags)) SPC_Input_Handler(channel, STDOUT); while(IS_SPCIO_DATA(channel->wires[STDERR]->flags)) SPC_Input_Handler(channel, STDERR); } if(channel->Terminate_Handler) { XeSPCGetProcessStatus(channel, &type, &cause); (* channel->Terminate_Handler) (channel, channel->pid, type, cause, channel->Terminate_Data); } channel->close_timeout=0; }
/*----------------------------------------------------------------------+*/ int read_pty_channel_object(SPC_Channel_Ptr channel, int connector, /* STDOUT or STDERR */ XeString buffer, int nbytes) /*----------------------------------------------------------------------+*/ #ifdef __hpux_pty { int result, select_value; struct fd_set read_mask, except_mask; int fd=channel->file_descs[connector]; struct request_info req_info; struct timeval timeout, *timeptr; int i; call_parent_method(channel, read, (channel, connector, buffer, nbytes), result); if(result==SPC_ERROR) return(SPC_ERROR); if(!IS_SPCIO_DATA(channel->wires[connector]->flags)) return(0); FD_ZERO(&read_mask); FD_ZERO(&except_mask); FD_SET(fd, &read_mask); FD_SET(fd, &except_mask); if(channel->close_timeout) { timeout.tv_sec=channel->close_timeout; timeout.tv_usec=0; timeptr = (&timeout); } else timeptr=NULL; do select_value=select(fd+1, &read_mask, NULL, &except_mask, timeptr); while(select_value==ERROR && errno==EINTR); if(select_value==ERROR) { SPC_Error(SPC_Bad_Select); return(SPC_ERROR); } /* If there is anything to read, read it & return */ IS_FD_SET(&read_mask, result); if(result) { do { result = read(fd, buffer, nbytes); } while (result<0 && errno == EINTR); if(result==ERROR) { SPC_Error(SPC_Reading); return(SPC_ERROR); } return(result); } /* Nothing to read. We either timed out or got an exception. */ if(select_value != 0) { /* We got an exception */ ioctl(fd, TIOCREQGET, &req_info); /* Clear the request (Not really necessary in the case of a close, but do it anyway) */ ioctl(fd, TIOCREQSET, &req_info); } if((select_value == 0) || (req_info.request == TIOCCLOSE)) { /* Close, disable trapping on this fd & return EOF. We regard a timeout as being the same as a close. */ SPC_Disable_Trapping(fd); SPC_Change_State(channel, connector, 0, -1); return(0); } else /* Otherwise (open or IOCTL), return -1 */ return(EXCEPT_FLAG); }