コード例 #1
0
ファイル: signals.c プロジェクト: Distrotech/texinfo
void
signal_unblock_winch (void)
{
#if defined (SIGWINCH)
  sigwinch_block_count--;
  if (sigwinch_block_count == 0)
    UNBLOCK_SIGNAL (SIGWINCH);
#endif
}
コード例 #2
0
ファイル: tty.c プロジェクト: james-m-henderson/scsh
static int allocate_master(const char ** slave_name, const char** clone) {
    int master_fd = -1;
    static const char * const clones[] =
    /* Different pty master clone devices */
        {
            "/dev/ptmx",      /* Various systems */
            "/dev/ptm/clone", /* HPUX */
            "/dev/ptc",       /* AIX */
            "/dev/ptmx_bsd"   /* Tru64 */
        };

#ifdef HAVE_GETPT /* glibc */
    master_fd = getpt ();
    if (master_fd >= 0)
        return master_fd;
#endif /* HAVE_GETPT */


#if defined(HAVE_OPENPTY) /* BSD, Tru64, glibc */
    {
        int slave_fd = -1;
        int rc;
        BLOCK_SIGNAL (SIGCHLD);
        rc = openpty (&master_fd, &slave_fd, NULL, NULL, NULL);
        UNBLOCK_SIGNAL (SIGCHLD);
        if (rc == 0)
        {
            *slave_name = ttyname (slave_fd);
            retry_close (slave_fd);
            return master_fd;
        }
        else
        {
            if (master_fd >= 0)
                retry_close (master_fd);
            if (slave_fd >= 0)
                retry_close (slave_fd);
        }
    }
#endif /* HAVE_OPENPTY */

#if defined(HAVE__GETPTY) && defined (O_NDELAY) /* SGI */
    master_fd = -1;
    BLOCK_SIGNAL (SIGCHLD);
    *slave_name = _getpty (&master_fd, O_RDWR | O_NDELAY, 0600, 0);
    UNBLOCK_SIGNAL (SIGCHLD);
    if (master_fd >= 0 && *slave_name != NULL)
        return master_fd;
#endif /* HAVE__GETPTY */

    /* Master clone devices are available on most systems */
    {
        int i;
        for (i = 0; i < countof (clones); i++)
        {
            *clone = clones[i];
            master_fd = open ((char *) *clone, // TODO: retry open
                              O_RDWR | O_NONBLOCK, 0);
            if (master_fd >= 0)
                return master_fd;
        }
        *clone = NULL;
    }
    return -1;
}
コード例 #3
0
ファイル: tty.c プロジェクト: james-m-henderson/scsh
/* Open an available pty, returning a file descriptor.
   Return -1 on failure. */
s48_ref_t allocate_pty(s48_call_t call) {
    /* Unix98 standardized grantpt, unlockpt, and ptsname, but not the
       functions required to open a master pty in the first place :-(

       Modern Unix systems all seems to have convenience methods to open
       a master pty fd in one function call, but there is little
       agreement on how to do it.

       allocate_pty() tries all the different known easy ways of opening
       a pty.  In case of failure, we resort to the old BSD-style pty
       grovelling code in allocate_pty_the_old_fashioned_way(). */
    int master_fd = -1;
    const char *slave_name = NULL;
    const char* clone = NULL;
    int off = 0;

    s48_ref_t scm_slave_name = s48_unspecific_2(call);

    master_fd = allocate_master(&slave_name, &clone);

    if (master_fd == -1)
        return s48_false_2(call);

    if (slave_name == NULL){
        slave_name = allocate_slave_name(master_fd, clone);

        if (slave_name == NULL){
            retry_close (master_fd);
            return s48_false_2(call);
        }
    }
    scm_slave_name = s48_enter_byte_string_2(call, (char *) slave_name);

#ifdef TIOCPKT
    /* In some systems (Linux through 2.0.0, at least), packet mode doesn't
       get cleared when a pty is closed, so we need to clear it here.
       Linux pre2.0.13 contained an attempted fix for this (from Ted Ts'o,
       [email protected]), but apparently it messed up rlogind and telnetd, so he
       removed the fix in pre2.0.14.     - [email protected]
    */
    ioctl (master_fd, TIOCPKT, (char *)&off);
#endif /* TIOCPKT */

    /* We jump through some hoops to frob the pty.
       It's not obvious that checking the return code here is useful. */

    /* "The grantpt() function will fail if it is unable to successfully
       invoke the setuid root program.  It may also fail if the
       application has installed a signal handler to catch SIGCHLD
       signals." */
#if defined (HAVE_GRANTPT) || defined (HAVE_UNLOCKPT)
    BLOCK_SIGNAL (SIGCHLD);

#if defined (HAVE_GRANTPT)
    grantpt (master_fd);
#endif /* HAVE_GRANTPT */

#if defined (HAVE_UNLOCKPT)
    unlockpt (master_fd);
#endif

    UNBLOCK_SIGNAL (SIGCHLD);
#endif /* HAVE_GRANTPT || HAVE_UNLOCKPT */

    fcntl(master_fd, F_SETFL, O_NONBLOCK);

    return s48_cons_2(call, s48_enter_long_2(call, master_fd), scm_slave_name);
}
コード例 #4
0
ファイル: signals.c プロジェクト: 2014-class/freerouter
static RETSIGTYPE
info_signal_proc (int sig)
{
  signal_info *old_signal_handler = NULL;

#if !defined (HAVE_SIGACTION)
  /* best effort: first increment this counter and later block signals */
  if (term_conf_busy)
    return;
  term_conf_busy++;
#if defined (HAVE_SIGPROCMASK) || defined (HAVE_SIGSETMASK)
    {
      sigset_t nvar, ovar;
      sigemptyset (&nvar);
      mask_termsig (&nvar);
      sigprocmask (SIG_BLOCK, &nvar, &ovar);
    }
#endif /* HAVE_SIGPROCMASK || HAVE_SIGSETMASK */
#endif /* !HAVE_SIGACTION */
  switch (sig)
    {
#if defined (SIGTSTP)
    case SIGTSTP:
    case SIGTTOU:
    case SIGTTIN:
#endif
#if defined (SIGQUIT)
    case SIGQUIT:
#endif
#if defined (SIGINT)
    case SIGINT:
#endif
      {
#if defined (SIGTSTP)
        if (sig == SIGTSTP)
          old_signal_handler = &old_TSTP;
        if (sig == SIGTTOU)
          old_signal_handler = &old_TTOU;
        if (sig == SIGTTIN)
          old_signal_handler = &old_TTIN;
#endif /* SIGTSTP */
#if defined (SIGQUIT)
        if (sig == SIGQUIT)
          old_signal_handler = &old_QUIT;
#endif /* SIGQUIT */
#if defined (SIGINT)
        if (sig == SIGINT)
          old_signal_handler = &old_INT;
#endif /* SIGINT */

        /* For stop signals, restore the terminal IO, leave the cursor
           at the bottom of the window, and stop us. */
        terminal_goto_xy (0, screenheight - 1);
        terminal_clear_to_eol ();
        fflush (stdout);
        terminal_unprep_terminal ();
	restore_termsig (sig, old_signal_handler);
	UNBLOCK_SIGNAL (sig);
	kill (getpid (), sig);

        /* The program is returning now.  Restore our signal handler,
           turn on terminal handling, redraw the screen, and place the
           cursor where it belongs. */
        terminal_prep_terminal ();
	set_termsig (sig, old_signal_handler);
	/* window size might be changed while sleeping */
	reset_info_window_sizes ();
      }
      break;

#if defined (SIGWINCH) || defined (SIGUSR1)
#ifdef SIGWINCH
    case SIGWINCH:
#endif
#ifdef SIGUSR1
    case SIGUSR1:
#endif
      {
	/* Turn off terminal IO, tell our parent that the window has changed,
	   then reinitialize the terminal and rebuild our windows. */
#ifdef SIGWINCH
	if (sig == SIGWINCH)
	  old_signal_handler = &old_WINCH;
#endif
#ifdef SIGUSR1
	if (sig == SIGUSR1)
	  old_signal_handler = &old_USR1;
#endif
	terminal_goto_xy (0, 0);
	fflush (stdout);
	terminal_unprep_terminal (); /* needless? */
	restore_termsig (sig, old_signal_handler);
	UNBLOCK_SIGNAL (sig);
	kill (getpid (), sig);

	/* After our old signal handler returns... */
	set_termsig (sig, old_signal_handler); /* needless? */
	terminal_prep_terminal ();
	reset_info_window_sizes ();
      }
      break;
#endif /* SIGWINCH || SIGUSR1 */
    }
#if !defined (HAVE_SIGACTION)
  /* at this time it is safer to perform unblock after decrement */
  term_conf_busy--;
#if defined (HAVE_SIGPROCMASK) || defined (HAVE_SIGSETMASK)
    {
      sigset_t nvar, ovar;
      sigemptyset (&nvar);
      mask_termsig (&nvar);
      sigprocmask (SIG_UNBLOCK, &nvar, &ovar);
    }
#endif /* HAVE_SIGPROCMASK || HAVE_SIGSETMASK */
#endif /* !HAVE_SIGACTION */
}