Example #1
0
int
main (int argc, char* argv[])
{
  struct termios oldtm;
  fd_set sel, sel0;
  int status;
  char* newarg0;

  /* SIGINT and SIGBREAK are indistinctive under cygwin environment. */
  /* Using Win32API to handle SIGINT.                              */
  SetConsoleCtrlHandler (ctrl_handler, TRUE);

  if (argc < 1)
    {
      fprintf (stderr, "Unable to get arg[0].");
      exit (1);
    }

  newarg0 = real_command_name (argv[0]);
  if (newarg0)
    {
      argv[0] = newarg0;
      exec_target (argv);     /* This sets globals masterfd, child_pid */
    }
  else if (argc > 1)
    {
      exec_target (argv + 1); /* This sets globals masterfd, child_pid */
    }
  else
    {
      fprintf (stderr, "Unable to get arg[1].");
      exit (1);
    }

  setup_tty_attributes ();

  FD_ZERO (&sel0);
  FD_SET (masterfd, &sel0);
  FD_SET (0, &sel0);

  /* communication loop */
  while (1)
    {
      char buf[BUFSIZE];
      int ret;

      sel = sel0;
      if (select (FD_SETSIZE, &sel, NULL, NULL, NULL) <= 0)
	break;

      if (FD_ISSET (masterfd, &sel))
	{
	  ret = read (masterfd, buf, BUFSIZE);
	  if (ret > 0)
	      write (1, buf, ret);
	  else
	    break;
	}
      else if (FD_ISSET (0, &sel))
	{
	  ret = read (0, buf, BUFSIZE);
	  if (ret > 0)
	      write (masterfd, buf, ret);
	  else
	    {
	      FD_CLR (0, &sel0);
	      close (masterfd);
	    }
	}
    }

  restore_tty_attributes ();

  kill (child_pid, SIGKILL);
  waitpid (child_pid, &status, 0);
  return WEXITSTATUS (status);
}
Example #2
0
int main(int argc, char* argv[])
{
  fd_set sel, sel0;
  int status;
  int pty_alloc_only = FALSE;
  char* newarg0;

  /* SIGINT and SIGBREAK are indistinctive under cygwin environment. */
  /* Using Win32API to handle SIGINT.                               */
  SetConsoleCtrlHandler(ctrl_handler, TRUE);

  if (argc < 1) {
    fputs("Unable to get arg[0].", stderr);
    exit(EXIT_FAILURE);
  }

  newarg0 = real_command_name(argv[0]);

  if (newarg0)
    argv[0] = newarg0;
  else if (argc >=2)
    argv++;
  else
    pty_alloc_only = TRUE;

  if (isatty(STDIN_FILENO) && !pty_alloc_only) {
    execvp(argv[0], argv);
    fprintf(stderr, "Failed to execute \"%s\": %s\n", argv[0], strerror(errno));
    exit(EXIT_FAILURE);
  }

  master_fd = open_master_pty();

  child_pid = exec_target(master_fd, argv, pty_alloc_only);

  setup_signal_handlers();

  FD_ZERO(&sel0);
  FD_SET(master_fd, &sel0);
  FD_SET(STDIN_FILENO, &sel0);

  /* communication loop */
  while (1) {
    char buf[BUFSIZE];
    int ret;

    if (sig_winch_caught == TRUE) {
      sig_winch_caught = FALSE;
      if (child_pid != -1 && resize_tty_window(master_fd, sig_window_size) == 0)
	kill(child_pid, SIGWINCH);
    }

    sel = sel0;
    if (select (FD_SETSIZE, &sel, NULL, NULL, NULL) <= 0) {
      if(errno == EINTR)
	continue;
      else
	break;
    }

    if (FD_ISSET(master_fd, &sel)) {
      ret = safe_read(master_fd, buf, BUFSIZE);
      if (ret > 0) {
	if (safe_write_full(STDOUT_FILENO, buf, ret) < 0)
	  break;
      }
      else
	break;
    }
    else if (FD_ISSET(STDIN_FILENO, &sel)) {
      ret = safe_read(STDIN_FILENO, buf, BUFSIZE);
      if (ret > 0) {
	if (safe_write_full_checking_eof(master_fd, buf, ret) < 0)
	  break;
      } else {
	FD_CLR(STDIN_FILENO, &sel0);
	close(master_fd);
      }
    }
  }

  if (pty_alloc_only) {
    kill(child_pid, SIGKILL);
    status = 0;
  } else {
    while(waitpid(child_pid, &status, 0) < 0 && errno == EINTR)
      ;

    if (WIFEXITED(status))
      status = WEXITSTATUS(status);
    else if(WIFSIGNALED(status)) /* ntemacs cannot distinct killed by signal */
      status = 0x80 +  WTERMSIG(status);
  }

  return status;
}