Exemplo n.º 1
0
/*----------------------------------------------------------------------+*/
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;
  
}
Exemplo n.º 2
0
/*----------------------------------------------------------------------+*/
int pre_fork_channel_object(SPC_Channel_Ptr channel)
/*----------------------------------------------------------------------+*/
{
  Wire *wirelist;
  int  flag=0;
  
  /* Set all wires to be "data ready" */
  
  for(wirelist=channel->wire_list; wirelist; wirelist=wirelist->next) {
    wirelist->flags |= SPCIO_DATA;
    flag=1;
  }

  /* Move to the "Running & (possibly) data ready" state */
  
  SPC_Change_State(channel, 0, flag, 1);

  
  return(TRUE);
}
Exemplo n.º 3
0
/* This is the right way according to the Spec 1170 */
void SPC_Child_Terminated(int i)
/*----------------------------------------------------------------------+*/
{
  /* This catches signals for sub-process termination */
  int type, cause, status;
  pid_t wait_pid, pid;
  SPC_Channel_Ptr channel;
  protocol_request     req, *prot;
  buffered_data        data, *pdata;
  int length;
  int indx;
  int saved_errno = errno;

  prot  = (&req);
  pdata = (&data);

  prot->dataptr=pdata;

  wait_pid = -1;
  while(pid = waitpid(wait_pid, &status, WNOHANG)) {
    if((pid == -1 && errno == ECHILD) || pid == 0) {
      /* no more children.  Return */
      errno = saved_errno;
      return;
    }
    
    /* Okay, we got the process ID of a terminated child.  Find the
       channel associated with this PID. */
    channel=SPC_Find_PID(pid);
#ifdef DEBUG
    fprintf(stderr, (XeString)"got SIGCHLD, pid: %d, channel: %p\n", pid, channel);
#endif

    if(!channel) {
      continue;
    }

    _DtSvcProcessLock();
    /*
     * Look for this process in the pid list.  If found, mark it
     * as done.
     */
    if (SPC_pid_list != NULL) {
      for (indx=0; SPC_pid_list[indx] != NULL; indx++)
        if (SPC_pid_list[indx] == pid) {
	   SPC_pid_list[indx] = SPCD_DEAD_PROCESS;
	   break;
	}
    }
    _DtSvcProcessUnlock();

    /* We have the channel.  Mark it as being closed. */

    channel->status     = status;

    /* If we this channel is set up for synchronous termination,
       write the protocol request to record that this guy died.
       Otherwise, call the termination handler directly. */
    
    if(IS_SPCIO_SYNC_TERM(channel->IOMode)) {

      /* This code is basically what SPC_Write_Protocol_Request does.
	 It is replicated here because a call to SPC_W_P_R would have
	 to be re-enterant if we called it here, and SPC_W_P_R is not
	 re-enterant at this time. */
      
      SPC_Reset_Protocol_Ptr(prot, channel, APPLICATION_DIED, 0);
      pdata->len=WRITE_APPLICATION_DIED(pdata, status);
      length=WRITE_HEADER(pdata, channel->cid,
			  prot->request_type,
			  pdata->len,
			  0);
      pdata->data[length]=(XeChar)' ';
      length=pdata->len+REQUEST_HEADER_LENGTH;
      if(write(write_terminator->sid, pdata->data, length)==ERROR)
	SPC_Error(SPC_Internal_Error);
      pdata->offset=REQUEST_HEADER_LENGTH;
      print_protocol_request((XeString) (XeString)"  <-- INTERNAL APPLICATION_DIED", prot);
    }
    else {
      SPC_Change_State(channel, NULL, -1, 0);
      if(channel->Terminate_Handler) {
	XeSPCGetProcessStatus(channel, &type, &cause);
	(* channel->Terminate_Handler)
	  (channel, channel->pid, type, cause, channel->Terminate_Data);
      }
    }
    /* Loop around & get another PID */
  }
  errno = saved_errno;
}
Exemplo n.º 4
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);
}