$NetBSD: patch-aj,v 1.12 2012/03/05 12:16:00 obache Exp $ --- fep_main.c.orig 1993-06-10 02:53:06.000000000 +0000 +++ fep_main.c 2011-09-29 20:16:05.000000000 +0000 @@ -6,15 +6,27 @@ -#endif lint +#endif /* lint */ #include #include #include #include #include -#include +#ifdef TERMIOS +#include +#include +#include +#ifdef __sun +#include +#endif +#ifndef _POSIX_VDISABLE +#define _POSIX_VDISABLE '\0' +#endif +#else #include +#include +#endif #include #include -#include +#include #include "fep_defs.h" #include "fep_glob.h" @@ -30,7 +42,7 @@ static char rcsid[]= #ifdef STAT static char fep_statrc[] = FEP_STAT; #endif -#endif lint +#endif /* lint */ char *myself; /* the command name */ char *prompt = ""; /* prompt string */ @@ -38,9 +50,9 @@ char *delimiters = DEFAULT_DELIMITERS; /* delimiter characters */ int master; /* file discriptor for pty master */ int slave; /* file discriptor for pty slave */ -int mastermask; /* 1<_cnt) - if (CHAR_IN_BUFFER) - goto RETURNCHAR; + FD_ZERO(&writefd); + FD_ZERO(&exceptfd); RETRY: readfd = selectmask; @@ -409,13 +430,13 @@ RETRY: while ((nfound = select (selectnfds, &readfd, 0, 0, *timeout)) < 0) if (errno != EINTR) { perror ("select"); - terminate(); + terminate(1); } /* * Found output from pty. */ - if (readfd & mastermask) { + if (FD_ISSET(master, &readfd)) { int nbyte; /* @@ -451,7 +472,7 @@ RETRY: /* * Found input from terminal */ - if (CHAR_IN_BUFFER || readfd & stdinmask) { + if (FD_ISSET(fileno(stdin), &readfd)) { #ifndef USE_TIMEOUT /* @@ -467,8 +488,8 @@ RETRY: RETURNCHAR: if ((c = getc (stdin)) == EOF) { if (debug) - printf ("EOF chatched\n"); - terminate (); + printf ("EOF catched\n"); + terminate (1); } else return (c & CHARMASK); @@ -504,7 +525,7 @@ int set_buffer (bp, size) BUFFER *bp; int size; { - char *newbuf, *malloc(), *realloc(); + char *newbuf; if (bp->b_buf) newbuf = (char *) realloc (bp->b_buf, size); @@ -596,7 +617,7 @@ buf_put (bp, s) swallow_output() { - int readfd = mastermask; + fd_set readfd = mastermask; int r; int nbyte; int ncount = 10; @@ -604,7 +625,7 @@ swallow_output() while ( ncount-- && select (selectnfds, &readfd, 0, 0, TIMEOUT_NOBLOCK) > 0 && - readfd & mastermask + FD_ISSET(master, &mastermask) ) { nbyte = buf_read (master, output_buffer); if (nbyte > 0) { @@ -636,21 +657,23 @@ swallow_output() #include #endif -catchsig() +void +catchsig(n) + int n; { - union wait status; + int status; struct rusage ru; if (wait3 (&status, WNOHANG | WUNTRACED, &ru) != child_pid) return; if (WIFSTOPPED (status) /* || WIFSIGNALED (status) */) { if (debug) { - message ("Child has sttoped!!\n"); + message ("Child has stopped!!\n"); } suspend (); return; } - terminate (); + terminate (WEXITSTATUS(status)); } exec_to_command(argv) @@ -675,13 +698,37 @@ exec_to_command(argv) dup2 (slave, 2); (void) close (slave); +#ifdef TERMIOS + tcsetattr(0, TCSANOW, &slave_ttymode); +#elif defined(TIOCSETN) ioctl (0, TIOCSETN, (char *) & slave_ttymode); - +#endif execvp (*argv, argv, 0); perror (*argv); exit (1); } +#ifdef TERMIOS +fix_tty() +{ + int i; + master_ttymode = initial_ttymode; + slave_ttymode = initial_ttymode; + master_ttymode.c_lflag &= ~(ECHO|ECHOE|ECHOK|ICANON); + + for (i = 0; i < NCCS; i++) + master_ttymode.c_cc[i] = _POSIX_VDISABLE; + + master_ttymode.c_cc[VMIN] = 1; + master_ttymode.c_cc[VTIME] = 0; + slave_ttymode.c_lflag &= ~(ECHO|ECHOE|ECHOK); + slave_ttymode.c_iflag &= ~(ICRNL); + slave_ttymode.c_oflag &= ~(ONLCR); + tcsetattr(0, TCSANOW, &master_ttymode); +} + +#elif defined(TIOCSETN) + fix_tty() { struct tchars tcbuf; @@ -719,6 +766,7 @@ fix_tty() ioctl (0, TIOCSETC, (char *) & tcbuf); ioctl (0, TIOCSLTC, (char *) & lcbuf); } +#endif kill_process() { @@ -727,9 +775,10 @@ kill_process() (void) killpg (child_pid, SIGTERM); } -terminate() +void +terminate(n) + int n; { - extern int errno; /* * Save history if 'history-file' is set @@ -759,10 +808,14 @@ terminate() if (killpg (child_pid, SIGKILL) < 0) perror ("kill"); +#ifdef TERMIOS + tcsetattr(0, TCSANOW, &initial_ttymode); +#elif defined(TIOCSETN) ioctl (0, TIOCSETN, (char *) & initial_ttymode); ioctl (0, TIOCSETC, (char *) & tchars_buf); ioctl (0, TIOCSLTC, (char *) & ltchars_buf); - exit (0); +#endif + exit (n); } get_pty_master() @@ -775,6 +828,41 @@ get_pty_master() master = 1; return; } +#ifdef HAVE_PTMX + if ((master = open("/dev/ptmx", O_RDWR)) == -1) { + perror ("Couldn't open pseudo tty"); + kill_process (); + exit (1); + } + if (grantpt (master) == -1) { + perror ("grantpt"); + kill_process (); + exit (1); + } + if (unlockpt (master) == -1) { + perror ("grantpt"); + kill_process (); + exit (1); + } + { +#ifdef __linux__ + if (ptsname_r (master, slave_tty, sizeof(slave_tty)) == -1) { + perror ("ptsname_r"); + kill_process (); + exit (1); + } +#else + char *ptr; + if ((ptr = ptsname (master)) == NULL) { + perror ("ptsname"); + kill_process (); + exit (1); + } + (void)strncpy (slave_tty, ptr, sizeof(slave_tty)); + slave_tty[sizeof(slave_tty) - 1] = '\0'; +#endif + } +#else for (c = 'p'; c <= 's'; c++) { for (i = 0; i < 16; i++) { sprintf (master_tty, "/dev/pty%c%x", c, i); @@ -796,11 +884,16 @@ get_pty_master() } FOUND: +#endif +#ifdef TERMIOS + tcgetattr(0, &initial_ttymode); +#elif defined(TIOCSETN) ioctl (0, TIOCGETP, (char *) &initial_ttymode); ioctl (0, TIOCGETC, (char *) &tchars_buf); ioctl (0, TIOCGETD, (char *) &line_desc); ioctl (0, TIOCGLTC, (char *) <chars_buf); ioctl (0, TIOCLGET, (char *) &lmode_buf); +#endif #ifdef TIOCGWINSZ { @@ -820,11 +913,15 @@ get_pty_master() # if defined(TIOCKGETC) && defined(TIOCKSETC) ioctl (0, TIOCKGETC, (char *) &jtchars_buf); # endif -#endif KANJI +#endif /* KANJI */ - stdinmask = 1 << fileno (stdin); - mastermask = 1 << master; - selectmask = stdinmask | mastermask; + FD_ZERO(&stdinmask); + FD_ZERO(&mastermask); + FD_ZERO(&selectmask); + FD_SET(fileno(stdin), &stdinmask); + FD_SET(master, &mastermask); + FD_SET(fileno(stdin), &selectmask); + FD_SET(master, &selectmask); selectnfds = max (fileno(stdin), master) + 1; return; @@ -838,11 +935,20 @@ get_pty_slave() perror (slave_tty); exit (1); } + if (setsid() == -1) + perror ("setsid"); + if (ioctl (slave, TIOCSCTTY, 1) == -1) + perror ("ioctl"); + +#ifdef TERMIOS + tcsetattr(slave, TCSANOW, &initial_ttymode); +#elif defined(TIOCSETN) ioctl (slave, TIOCSETN, (char *) &initial_ttymode); ioctl (slave, TIOCSETC, (char *) &tchars_buf); ioctl (slave, TIOCSLTC, (char *) <chars_buf); ioctl (slave, TIOCLSET, (char *) &lmode_buf); ioctl (slave, TIOCSETD, (char *) &line_desc); +#endif #ifdef KANJI # if defined(TIOCKGET) && defined(TIOCKSET) @@ -851,7 +957,7 @@ get_pty_slave() # if defined(TIOCKGETC) && defined(TIOCKSETC) ioctl (slave, TIOCKSETC, (char *) &jtchars_buf); # endif -#endif KANJI +#endif /* KANJI */ #ifdef TIOCSWINSZ { @@ -866,37 +972,40 @@ get_pty_slave() recover_tty() { - +#ifdef TERMIOS + tcsetattr(0, TCSANOW, &initial_ttymode); +#elif defined(TIOCSETN) ioctl (0, TIOCSETN, (char *) & initial_ttymode); ioctl (0, TIOCSETC, (char *) & tchars_buf); ioctl (0, TIOCSLTC, (char *) & ltchars_buf); +#endif } suspend() { long pid; - void (*func) (); - int omask; - extern int errno; + void (*func) (int); + sigset_t set, oset; pid = getpid (); /* reset signal handler so kill below stops us */ func = signal (SIGCHLD, SIG_IGN); signal (SIGTSTP, SIG_DFL); recover_tty(); -#define mask(s) (1 << ((s)-1)) - omask = sigsetmask (sigblock (0) & ~mask (SIGTSTP)); + sigemptyset(&set); + sigaddset(&set, SIGTSTP); + sigprocmask (SIG_BLOCK, &set, &oset); kill (0, SIGTSTP); if (kill (child_pid, SIGCONT) < 0 && errno == ESRCH) { printf ("Where my child has gone?!\n"); - terminate (); + terminate (1); } killpg (child_pid, SIGCONT); kill (0, SIGCONT); signal (SIGCHLD, func); signal (SIGTSTP, SIG_IGN); - sigblock (mask (SIGTSTP)); + sigprocmask (SIG_BLOCK, &set, &oset); fix_tty (); if (look_var ("auto-repaint")) fep_repaint(0); @@ -933,7 +1042,7 @@ usageAndExit() /* * Propagate window size changes to the slave tty. */ -sigwinch() +void sigwinch(int num) { #ifdef TIOCGWINSZ /* 4.3BSD */ struct winsize win;