81ef29ab40
OS X patch program.
475 lines
11 KiB
Text
475 lines
11 KiB
Text
$NetBSD: patch-aj,v 1.9 2006/01/17 21:23:01 kristerw Exp $
|
|
|
|
--- fep_main.c.orig 1993-06-10 02:53:06.000000000 +0000
|
|
+++ fep_main.c 2006-01-03 18:13:49.000000000 +0000
|
|
@@ -6 +6 @@
|
|
-#endif lint
|
|
+#endif /* lint */
|
|
@@ -10,11 +10,20 @@
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/ioctl.h>
|
|
-#include <sys/file.h>
|
|
+#ifdef TERMIOS
|
|
+#include <stdlib.h>
|
|
+#include <fcntl.h>
|
|
+#include <termios.h>
|
|
+#ifndef _POSIX_VDISABLE
|
|
+#define _POSIX_VDISABLE '\0'
|
|
+#endif
|
|
+#else
|
|
#include <sgtty.h>
|
|
+#include <sys/file.h>
|
|
+#endif
|
|
#include <sys/time.h>
|
|
#include <sys/resource.h>
|
|
-#include <sys/errno.h>
|
|
+#include <errno.h>
|
|
|
|
#include "fep_defs.h"
|
|
#include "fep_glob.h"
|
|
@@ -30,7 +39,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 +47,9 @@ char *delimiters = DEFAULT_DELIMITERS;
|
|
/* delimiter characters */
|
|
int master; /* file discriptor for pty master */
|
|
int slave; /* file discriptor for pty slave */
|
|
-int mastermask; /* 1<<master */
|
|
-int stdinmask; /* 1<<fileno(stdin) */
|
|
-int selectmask; /* stdinmask | mastermask */
|
|
+fd_set mastermask; /* 1<<master */
|
|
+fd_set stdinmask; /* 1<<fileno(stdin) */
|
|
+fd_set selectmask; /* stdinmask | mastermask */
|
|
int selectnfds; /* max (fileno(stdin), master) + 1*/
|
|
int child_pid; /* child pid */
|
|
int ptyflag = ON; /* flag to use pty or not */
|
|
@@ -48,27 +57,34 @@ int histlen = -1; /* history length */
|
|
int debug = OFF; /* debug switch */
|
|
int auto_tty_fix = ON; /* fix tty mode automaticaly */
|
|
FILE *script_fp = NULL; /* script file pointer */
|
|
-int catchsig(); /* function take care SIGCHILD */
|
|
+void catchsig __P((int)); /* function take care SIGCHILD */
|
|
|
|
-struct sgttyb initial_ttymode; /* initial tty mode */
|
|
-struct sgttyb master_ttymode; /* master tty mode */
|
|
-struct sgttyb slave_ttymode; /* slave tty mode */
|
|
+#ifdef TERMIOS
|
|
+#define ttystruct termios
|
|
+#elif defined(TIOCSETN)
|
|
+#define ttystruct sgttyb
|
|
+#endif
|
|
+struct ttystruct initial_ttymode; /* initial tty mode */
|
|
+struct ttystruct master_ttymode; /* master tty mode */
|
|
+struct ttystruct slave_ttymode; /* slave tty mode */
|
|
|
|
int lines; /* terminal line size */
|
|
int columns; /* terminal coulumn size */
|
|
char *term_clear; /* terminal clear code */
|
|
|
|
-void (*sighup)(), (*sigchld)(), (*sigtstp)();
|
|
+void (*sighup) __P((int)), (*sigchld) __P((int)), (*sigtstp) __P((int));
|
|
/* function buffer for signal */
|
|
|
|
+#ifdef TIOCSETN
|
|
struct tchars tchars_buf; /* tty characters */
|
|
struct ltchars ltchars_buf; /* tty characters */
|
|
+#endif
|
|
int lmode_buf; /* local mode */
|
|
int line_desc; /* line descipline */
|
|
#ifdef KANJI
|
|
struct jtchars jtchars_buf; /* kanji tty characters */
|
|
int kmode_buf; /* kanji mode */
|
|
-#endif KANJI
|
|
+#endif /* KANJI */
|
|
|
|
char master_tty[16]; /* master tty name */
|
|
char slave_tty[16]; /* slave tty name */
|
|
@@ -112,6 +128,10 @@ main(argc, argv)
|
|
|
|
myself = argv[0];
|
|
|
|
+ setvbuf(stdin, NULL, _IONBF, 0);
|
|
+ setvbuf(stdout, NULL, _IONBF, 0);
|
|
+ setvbuf(stderr, NULL, _IONBF, 0);
|
|
+
|
|
/*
|
|
* Initialize binding table
|
|
*/
|
|
@@ -172,7 +192,7 @@ main(argc, argv)
|
|
histlen = atoi (argv[1]);
|
|
}
|
|
else {
|
|
- histlen = atoi (&argv[1] + 2);
|
|
+ histlen = atoi (argv[1] + 2);
|
|
}
|
|
break;
|
|
|
|
@@ -276,7 +296,7 @@ DEFAULT:
|
|
fix_signal ()
|
|
{
|
|
#ifdef SIGWINCH
|
|
- int sigwinch();
|
|
+ void sigwinch __P((int));
|
|
#endif
|
|
|
|
sighup = signal (SIGHUP, terminate);
|
|
@@ -336,7 +356,7 @@ input_handler()
|
|
if (Through == OFF && Transparency == OFF && script_fp)
|
|
fwrite (inputline, sizeof(CHAR), strlen (inputline), script_fp);
|
|
}
|
|
- terminate ();
|
|
+ terminate (0);
|
|
}
|
|
|
|
#define INPUT_BUFFER_SIZE 1024
|
|
@@ -384,21 +404,19 @@ getcharacter()
|
|
{
|
|
char c;
|
|
int n;
|
|
- int nfound, readfd, writefd = 0, execptfd = 0;
|
|
+ int nfound;
|
|
+ fd_set readfd, writefd, exceptfd;
|
|
#ifdef USE_TIMEOUT
|
|
struct timeval **timeout = auto_tty_fix ? timeout_list : notimeout;
|
|
#else
|
|
struct timeval **timeout = notimeout;
|
|
#endif
|
|
- extern int errno;
|
|
-
|
|
|
|
/*
|
|
* Sorry, this cording depends to an implementation of getc().
|
|
*/
|
|
-# define CHAR_IN_BUFFER (stdin->_cnt)
|
|
- if (CHAR_IN_BUFFER)
|
|
- goto RETURNCHAR;
|
|
+ FD_ZERO(&writefd);
|
|
+ FD_ZERO(&exceptfd);
|
|
|
|
RETRY:
|
|
readfd = selectmask;
|
|
@@ -409,13 +427,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 +469,7 @@ RETRY:
|
|
/*
|
|
* Found input from terminal
|
|
*/
|
|
- if (CHAR_IN_BUFFER || readfd & stdinmask) {
|
|
+ if (FD_ISSET(fileno(stdin), &readfd)) {
|
|
|
|
#ifndef USE_TIMEOUT
|
|
/*
|
|
@@ -467,8 +485,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 +522,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 +614,7 @@ buf_put (bp, s)
|
|
|
|
swallow_output()
|
|
{
|
|
- int readfd = mastermask;
|
|
+ fd_set readfd = mastermask;
|
|
int r;
|
|
int nbyte;
|
|
int ncount = 10;
|
|
@@ -604,7 +622,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 +654,23 @@ swallow_output()
|
|
#include <sys/m_wait.h>
|
|
#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 +695,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 +763,7 @@ fix_tty()
|
|
ioctl (0, TIOCSETC, (char *) & tcbuf);
|
|
ioctl (0, TIOCSLTC, (char *) & lcbuf);
|
|
}
|
|
+#endif
|
|
|
|
kill_process()
|
|
{
|
|
@@ -727,9 +772,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 +805,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 +825,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 +881,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 +910,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 +932,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 +954,7 @@ get_pty_slave()
|
|
# if defined(TIOCKGETC) && defined(TIOCKSETC)
|
|
ioctl (slave, TIOCKSETC, (char *) &jtchars_buf);
|
|
# endif
|
|
-#endif KANJI
|
|
+#endif /* KANJI */
|
|
|
|
#ifdef TIOCSWINSZ
|
|
{
|
|
@@ -866,18 +969,20 @@ 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) ();
|
|
+ void (*func) __P((int));
|
|
int omask;
|
|
- extern int errno;
|
|
|
|
pid = getpid ();
|
|
/* reset signal handler so kill below stops us */
|
|
@@ -890,7 +995,7 @@ suspend()
|
|
|
|
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);
|
|
@@ -933,7 +1038,7 @@ usageAndExit()
|
|
/*
|
|
* Propagate window size changes to the slave tty.
|
|
*/
|
|
-sigwinch()
|
|
+sigwinch(int num)
|
|
{
|
|
#ifdef TIOCGWINSZ /* 4.3BSD */
|
|
struct winsize win;
|