rsalz@uunet.uu.net (Rich Salz) (11/11/88)
Submitted-by: Kazumasa Utashiro <kddlab!sra.junet!utashiro> Posting-number: Volume 16, Issue 64 Archive-name: fep/part04 #!/bin/sh # to extract, remove the header and type "sh filename" if `test ! -s ./fep_defs.h` then echo "writing ./fep_defs.h" cat > ./fep_defs.h << '\End\Of\File\' /* Copyright (c) 1987, 1988 by Software Research Associates, Inc. */ #ifndef lint # define FEP_DEFS \ "$Header: fep_defs.h,v 4.0 88/08/05 20:21:51 utashiro Rel $ (SRA)" #endif lint #define MAXCOMLEN 512 /* maximum command length */ #define MAXARGS 64 /* maximum number of arguments */ #define ON 1 /* on switch */ #define OFF 0 /* off switch */ #define DFL_HISTLEN 100 /* default history length */ #define DFL_SHOWHIST 20 /* default show history length */ #define IGNORED 2 /* ignored */ #define PROCESSED 1 /* processed or not by history */ #define NOT_PROCESSED 0 /* built-in functions */ #define BS '\b' /* backspace character */ #define SP ' ' /* space character */ #define DEFAULT_DELIMITERS " \t" /* default delimiter character */ /* * Pseudo functions */ #define eq(a,b) (strcmp(a,b) == 0) #define abs(a) ((a)>0?(a):-(a)) #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) #ifdef KANJI # define isctlchar(c) (c && !iskanji(c) && (!(c&0140) || c=='\177')) # define iswordchar(c) (c && (iskanji(c) || isalnum(c) || iscntrl(c))) # define isWordchar(c) ((c) && !isspace((c))) #else KANJI # define isctlchar(c) (c && (!(c&0140) || c=='\177')) # define iswordchar(c) (isalnum(c) || iscntrl(c)) # define isWordchar(c) ((c) && !isspace((c))) #endif KANJI #define unctl(c) (((c)=='\177') ? '?' : ((c) >= 040) ? (c) : (c)|0100) #define toctrl(c) ((c)&~0100) #define INDIRECTED (1<<(sizeof(char*)*8-1)) /* this is actually 0x80000000 on 32 bit machine, that addresses kernel address space */ #define isIndirect(f) ((u_int)(f)&(u_int)INDIRECTED) #define setIndirect(f) (FUNC)((u_int)(f)|(u_int)INDIRECTED) #define maskIndirect(f) (FUNC *)((u_int)(f)&~(u_int)INDIRECTED) /* * Type of character */ #ifdef KANJI # define CHAR unsigned char # define CHARMASK 0377 #else KANJI # define CHAR char # define CHARMASK 0177 #endif KANJI /* * Only one machine I know alloca() works is vax. */ #ifdef vax # define ALLOCA #endif vax /* * Typedef's */ typedef int (*FUNC)(); /* pointer to funciton */ typedef enum { /* edit status */ EDITING, NOTEDITING } EDITSTATUS; typedef enum { /* edit mode */ NOTYET, EMACS, VI } EDITMODE; typedef struct { /* bind table entry type */ char *bt_s; FUNC bt_func; } BINDENT; typedef struct _var { char *v_name; char *v_value; char *v_help; struct _var *v_next; } VAR; typedef struct { char *buf; /* buffer */ char *last_buf; /* last i/o done pointer */ int b_max; /* max size */ int start; /* start point */ int next; /* next read point */ int count; /* count */ int hiwater; /* high water mark */ } BUFFER; #define buf_count(b) ((b)->count) #define buf_remain(b) ((b)->size - (b)->count) /* char buf_char (b, n) BUFFER *b; int n; { if (n >= 0) { if (n >= b->count) return ((char*)-1); return (b->buf[(b->start+n)%b->count]); } else { if (-n >= b->count) return (-1); if (b->next+n >= 0) return (b->buf[b->next+n]); else return (b->buf[b->next+n+b->count]); } } */ #define buf_char(b,n) \ (((n)>=0) \ ?(((n)>=(b)->count) \ ? ((char)-1) \ : ((b)->buf[((b)->start+n)%(b)->count])) \ :((-(n) > (b)->count) \ ?((char)-1) \ :((((b)->next+n) >= 0) \ ? ((b)->buf[(b)->next+(n)]) \ : ((b)->buf[(b)->next+n+(b)->count])))) \End\Of\File\ else echo "will not over write ./fep_defs.h" fi if `test ! -s ./fep_glob.h` then echo "writing ./fep_glob.h" cat > ./fep_glob.h << '\End\Of\File\' /* Copyright (c) 1987, 1988 by Software Research Associates, Inc. */ #ifndef lint # define FEP_GLOB \ "$Header: fep_glob.h,v 4.0 88/08/05 20:21:55 utashiro Rel $ (SRA)" #endif lint extern FUNC *curFuncTab; /* function table */ extern FUNC *altFuncTab; /* altanative function table */ extern int debug; /* debug flag */ extern char *prompt; /* prompt string */ extern char *delimiters; /* delimiter characters */ extern EDITMODE editmode; /* edit mode */ extern FILE *redirect_fp; /* FILE pointer for I/O redirection */ extern FILE *script_fp; /* FILE pointer for script */ extern int redirect_line; /* number of line for redirecting */ extern int redirect_pid; /* process id redirecting from */ extern int auto_tty_fix; /* fix tty mode automatically */ extern int tty_fix_bell; /* ring bell when tty mode is changed */ extern int Transparency; /* transparent flag */ extern EDITSTATUS editstatus; /* edit status */ extern BUFFER *output_buffer; /* output buffer */ extern int lines, columns; /* terminal sizes */ extern char *term_clear; /* terminal clear code */ /* * tty control caracters. * defined in fep_main.c */ extern struct tchars tchars_buf; extern struct ltchars ltchars_buf; extern struct sgttyb initial_ttymode; \End\Of\File\ else echo "will not over write ./fep_glob.h" fi if `test ! -s ./fep_funcs.h` then echo "writing ./fep_funcs.h" cat > ./fep_funcs.h << '\End\Of\File\' /* Copyright (c) 1987, 1988 by Software Research Associates, Inc. */ #ifndef lint # define FEP_FUNCS \ "$Header: fep_funcs.h,v 4.0 88/08/05 20:21:53 utashiro Rel $ (SRA)" #endif lint /* * command line edit functions */ int abort(); int backward_character(); int backward_word(); int backward_Word(); int beginning_of_line(); int clear_screen(); int delete_line(); int delete_next_character(); int delete_next_word(); int delete_next_Word(); int delete_previous_character(); int delete_previous_word(); int delete_previous_Word(); int delete_to_kill_buffer(); int terminate(); int end_of_line(); int expand_file_name(); int forward_character(); int forward_to_end_of_word(); int forward_to_end_of_Word(); int forward_word(); int forward_Word(); int ignore(); int insert_and_flush(); int insert_tab(); int kill_to_end_of_line(); int kill_to_top_of_line(); int list_file_name(); int literal_next(); int mark(); int new_line(); int next_history(); int previous_history(); int reprint(); int search_reverse(); int search_forward(); int self_insert(); int send_eof(); int show_bindings(); int show_history(); int toggle_transparency(); int fix_transparency(); int yank_from_kill_buffer(); int invoke_shell(); int show_help(); /* * Vi mode functions. */ int vi_num(); int vi_edit(); int vi_motion(); int vi_c(); int vi_d(); int vi_ins_edit(); int vi_new_line(); /* * fep builtin command functions. */ int suspend(); int bind_to_key(); int alias(); int unalias(); int set(); int unset(); int fep_chdir(); int fep_pwd(); int fep_history(); int show_bindings(); int fep_source(); int fep_command(); int fep_save_history(); int fep_start_script(); int fep_end_script(); int fep_read_history(); int fep_read_from_file(); int fep_read_from_command(); int fep_echo(); int fep_if(); int fep_else(); int fep_endif(); int fep_repaint(); #ifdef STAT int fep_showstat(); #endif /* * FunctionNameTable */ typedef struct { int (*func)(); char *name; char *help; } FunctionTableEnt; extern FunctionTableEnt FunctionNameTable[]; extern FunctionTableEnt BuiltinFuncTable[]; char *look_var(); char *push_condition(); char *pop_condition(); char *change_condition(); \End\Of\File\ else echo "will not over write ./fep_funcs.h" fi if `test ! -s ./fep_stat.h` then echo "writing ./fep_stat.h" cat > ./fep_stat.h << '\End\Of\File\' /* Copyright (c) 1987, 1988 by Software Research Associates, Inc. */ #ifndef lint # define FEP_STAT \ "$Header: fep_stat.h,v 4.0 88/08/05 20:21:58 utashiro Rel $ (SRA)" #endif lint extern long stat_obyte; extern long stat_ibyte; extern long stat_rerror; extern long stat_werror; extern long stat_nselect; struct statistics { char *info_name; long *info_valp; }; \End\Of\File\ else echo "will not over write ./fep_stat.h" fi if `test ! -s ./fep_main.c` then echo "writing ./fep_main.c" cat > ./fep_main.c << '\End\Of\File\' /* Copyright (c) 1987, 1988 by Software Research Associates, Inc. */ #ifndef lint static char rcsid[]= "$Header: fep_main.c,v 4.0 88/08/05 20:22:17 utashiro Rel $ (SRA)"; #endif lint #include <stdio.h> #include <signal.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <sys/file.h> #include <sgtty.h> #include <sys/time.h> #include <sys/resource.h> #include <sys/errno.h> #include "fep_defs.h" #include "fep_glob.h" #include "fep_funcs.h" #ifdef STAT #include "fep_stat.h" #endif #ifndef lint static char fep_defsrc[] = FEP_DEFS; static char fep_globrc[] = FEP_GLOB; static char fep_funcsrc[] = FEP_FUNCS; #ifdef STAT static char fep_statrc[] = FEP_STAT; #endif #endif lint char *myself; /* the command name */ char *prompt = ""; /* prompt string */ 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 */ int selectnfds; /* max (fileno(stdin), master) + 1*/ int child_pid; /* child pid */ int ptyflag = ON; /* flag to use pty or not */ 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 */ struct sgttyb initial_ttymode; /* initial tty mode */ struct sgttyb master_ttymode; /* master tty mode */ struct sgttyb slave_ttymode; /* slave tty mode */ int lines; /* terminal line size */ int columns; /* terminal coulumn size */ char *term_clear; /* terminal clear code */ FUNC sighup, sigchld, sigtstp; /* function buffer for signal */ struct tchars tchars_buf; /* tty characters */ struct ltchars ltchars_buf; /* tty characters */ 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 char master_tty[16]; /* master tty name */ char slave_tty[16]; /* slave tty name */ BUFFER iobuffer; /* buffer self */ BUFFER *output_buffer = &iobuffer; /* buffer pointer */ struct cmdinfo { char *command; char *prompt; char *delimiters; } cmdinfo_tab [] = { {"/bin/sh", "$ ", " \t()<>{};&|='\""}, {"sh", "$ ", " \t()<>{};&|='\""}, {"jsh", "$ ", " \t()<>{};&|='\""}, {"/bin/csh", "% ", " \t()<>{};&|='\""}, {"csh", "% ", " \t()<>{};&|='\""}, {"jcsh", "% ", " \t()<>{};&|='\""}, {"/usr/ucb/dbx", "(dbx) ", " \t>"}, {"dbx", "(dbx) ", " \t>"}, {"/etc/lpc", "lpc> ", " \t"}, {"lpc", "lpc> ", " \t"}, {"/usr/ucb/mail", "& ", " \t"}, {"mail", "& ", " \t"}, {"/usr/lib/sendmail", "> ", " \t"}, {"sendmail", "> ", " \t"}, {"/usr/sra/calc", "CALC: ", " \t"}, {"calc", "CALC: ", " \t"}, {0, 0} }; main(argc, argv) int argc; char *argv[]; { int i; char *cp; char *getenv(); char **commandv; char *allocAndCopyThere(); myself = argv[0]; /* * Initialize binding table */ init_bind_table (); /* * Set default variables before process arguments. */ set_default_vars (); /* * Look environment variable first. */ /* EDITMODE */ if ((cp=getenv("EDITMODE")) && (eq(cp,"emacs")||eq(cp,"vi"))) set_only_var ("editmode", cp); /* USER */ if (cp=getenv("USER")) set_only_var ("user", cp); /* HOME */ if (cp=getenv("HOME")) set_only_var ("home", cp); /* TERM */ if (cp=getenv("TERM")) set_only_var ("term", cp); /* SHELL */ if (cp=getenv("SHELL")) set_only_var ("shell", cp); /* * Check arguments. */ while (argv[1] && argv[1][0] == '-') { switch (argv[1][1]) { case '\0': /* - */ ptyflag = 0; break; case 'd': /* -d */ debug = ON; break; case 'e': /* -emacs */ if (strcmp (argv[1], "-emacs") == 0) set_only_var ("editmode", "emacs"); else goto DEFAULT; break; case 'h': /* -h */ if (argv[1][2] == '\0') { argv++; argc--; if (argc == 1) usageAndExit (); histlen = atoi (argv[1]); } else { histlen = atoi (&argv[1] + 2); } break; case 'p': /* -p */ if (argv[1][2] == '\0') { argv++; argc--; if (argc == 1) usageAndExit (); prompt = allocAndCopyThere (argv[1]); } else { prompt = allocAndCopyThere (argv[1] + 2); } break; case 'v': /* -vi */ if (strcmp (argv[1], "-vi") == 0) set_only_var ("editmode", "vi"); else goto DEFAULT; break; DEFAULT: default: printf ("Unknown option \"%s\"\n", argv[1]); } argv++; argc--; } fflush (stdout); if (argc < 2 && ptyflag) { usageAndExit (); } look_cmdinfo (argv[1]); /* * Set variable of command name. */ { char *cp = argv[1], *rindex(); if (any ('/', cp)) cp = rindex (cp, '/') + 1; set_var (cp, "1"); set_var ("command", cp); } commandv = &argv[1]; if (! isatty (0)) { execvp (*commandv, commandv, 0); perror (*commandv); exit (1); } get_pty_master (); fix_tty (); if (histlen < 0) { if (getenv ("HISTLEN")) histlen = atoi (getenv ("HISTLEN")); else histlen = DFL_HISTLEN; } /* * Initialize output buffer. */ output_buffer->buf = (char *) malloc (5120); if (output_buffer->buf <= 0) { fprintf (stderr, "Can't allocate enough momory\n"); kill_process (); exit (1); } output_buffer->b_max = 5120; output_buffer->hiwater = 4096; output_buffer->count = output_buffer->next = output_buffer->start = 0; init_hist (histlen); init_edit_params (); if (ptyflag) { child_pid = fork (); if (child_pid < 0) { perror ("fork"); kill_process (); exit (1); } if (child_pid == 0) exec_to_command (commandv); } fix_signal (); input_handler (); } fix_signal () { sighup = signal (SIGHUP, catchsig); sigchld = signal (SIGCHLD, catchsig); sigtstp = signal (SIGTSTP, SIG_IGN); } recover_signal () { (void) signal (SIGHUP, sighup); (void) signal (SIGCHLD, sigchld); (void) signal (SIGTSTP, sigtstp); } input_handler() { char *inputline; char *getline (); /* * Get slave tty descriptor for auto-tty-fix */ if ((slave = open (slave_tty, O_RDONLY)) < 0) perror ("open"); while (inputline = getline ()) { register int nbyte = strlen (inputline); /* * Write to master pty */ write (master, inputline, nbyte); /* * NOTE: * Saving command line to output buffer is done in getline(). * Because inputline here is converted by alias. */ #ifdef STAT stat_ibyte += nbyte; #endif /* * Write to script file. */ if (Transparency == OFF && script_fp) fwrite (inputline, sizeof(CHAR), strlen (inputline), script_fp); } terminate (); } #define INPUT_BUFFER_SIZE 1024 #ifdef USE_TIMEOUT /* * NOTE: * Now these time mechanism is not used. * Terminal status is get at every input from stdin. */ struct timeval timeout_0s = {0L, 0L}; struct timeval timeout_500ms = {0L, 500000L}; struct timeval timeout_1s = {1L, 0L}; struct timeval timeout_5s = {5L, 0L}; struct timeval timeout_10s = {10L, 0L}; struct timeval timeout_60s = {60L, 0L}; #define TIMEOUT_IMMID &timeout_500ms #define TIMEOUT_SOON &timeout_1s #define TIMEOUT_SHORT &timeout_5s #define TIMEOUT_MID &timeout_10s #define TIMEOUT_LONG &timeout_60s #define TIMEOUT_FOREVER (struct timeval *)0 #define TIMEOUT_NOBLOCK &timeout_0s struct timeval *timeout_list[] = { TIMEOUT_IMMID, TIMEOUT_SOON, TIMEOUT_SHORT, TIMEOUT_MID, TIMEOUT_LONG, TIMEOUT_FOREVER }; #else struct timeval timeout_0s = {0L, 0L}; #define TIMEOUT_FOREVER (struct timeval *)0 #define TIMEOUT_NOBLOCK &timeout_0s #endif struct timeval *notimeout[] = { TIMEOUT_FOREVER }; getcharacter() { char c; int n; /* char buf[INPUT_BUFFER_SIZE]; */ int nfound, readfd, writefd = 0, execptfd = 0; #ifdef USE_TIMEOUT struct timeval **timeout = auto_tty_fix ? timeout_list : notimeout; #else struct timeval **timeout = notimeout; #endif /* * Sorry, this cording depends to an implementation of getc(). */ # define CHAR_IN_BUFFER (stdin->_cnt) if (CHAR_IN_BUFFER) goto RETURNCHAR; RETRY: readfd = selectmask; #ifdef STAT stat_nselect++; #endif if ((nfound = select (selectnfds, &readfd, 0, 0, *timeout)) < 0) perror ("select"); /* * Found output from pty. */ if (readfd & mastermask) { int nbyte; /* * Read from pty. */ /* nbyte = read (master, buf, INPUT_BUFFER_SIZE); */ nbyte = buf_read (master, output_buffer); if (nbyte > 0) { /* * Write to stdout */ /* write (1, buf, nbyte); */ write (1, output_buffer->last_buf, nbyte); /* * Write to script file */ if (script_fp) /* fwrite (buf, sizeof(CHAR), nbyte, script_fp); */ fwrite (output_buffer->last_buf, sizeof(CHAR), nbyte, script_fp); #ifdef STAT stat_obyte += nbyte; #endif } else if (nbyte < 0) { perror ("read"); #ifdef STAT stat_rerror++; #endif } } /* * Found input from terminal */ if (CHAR_IN_BUFFER || readfd & stdinmask) { #ifndef USE_TIMEOUT /* * Look slave tty mode before every input. * This will be done only before real input from stdin, because * if character remained in FILE buffer, control goes to RETURNCHAR * label. */ if (auto_tty_fix) (void) fix_transparency (); #endif RETURNCHAR: if ((c = getc (stdin)) == EOF) { if (debug) printf ("EOF chatched\n"); terminate (); } else return (c & CHARMASK); } #ifdef USE_TIMEOUT /* * In the case of timeout. */ if (nfound == 0) { /* * Only to make sure */ if (!auto_tty_fix) { printf ("Timeout should not happen!!\n"); timeout = notimeout; goto RETRY; } (void) fix_transparency (); ++timeout; if (debug) errorBell(); } #endif goto RETRY; } int buf_read (fd, bp) int fd; /* file discriptor */ BUFFER *bp; /* buffer pointer */ { int nbyte; /* * save previous next pointer */ bp->last_buf = bp->buf + bp->next; /* * read from fd as possible */ nbyte = read (fd, bp->buf + bp->next, bp->b_max - bp->next); /* * move next read pointer */ bp->next += nbyte; /* * If count has not reached high-water mark, increment count * by read count, otherwise start pointer should be pushed by * next pointer. */ if (bp->count < bp->hiwater) bp->count += nbyte; else bp->start += nbyte; /* * If next pointer goes further than high-water mark, discard contents * after next pointer, and move start and next pointer to buffer top. */ if (bp->next > bp->hiwater) { bp->count = bp->next; bp->start = 0; bp->next = 0; } return (nbyte); } buf_put (bp, s) BUFFER *bp; /* buffer pointer */ char *s; /* string pointer */ { int nbyte; int slen; nbyte = strlen (s); while (nbyte > 0) { slen = min (bp->b_max - bp->next, nbyte); strncpy (bp->buf + bp->next, s, slen); s += slen; nbyte -= slen; bp->next += slen; if (bp->count < bp->hiwater) bp->count += slen; else bp->start += slen; if (bp->next > bp->hiwater) { bp->count = bp->next; bp->start = 0; bp->next = 0; } } } swallow_output() { /* char buf[INPUT_BUFFER_SIZE]; */ int readfd = mastermask; int r; int nbyte; int ncount = 10; while ( ncount-- && select (selectnfds, &readfd, 0, 0, TIMEOUT_NOBLOCK) > 0 && readfd & mastermask ) { /* nbyte = read (master, buf, INPUT_BUFFER_SIZE); */ nbyte = buf_read (master, output_buffer); if (nbyte > 0) { /* write (1, buf, nbyte); */ write (1, output_buffer->last_buf, nbyte); #ifdef STAT stat_obyte += nbyte; stat_nselect++; #endif /* * Write to script file */ if (script_fp) /* fwrite (buf, sizeof(CHAR), nbyte, script_fp); */ fwrite (output_buffer->last_buf, sizeof(CHAR), nbyte, script_fp); } else if (nbyte < 0) { perror ("read"); #ifdef STAT stat_rerror++; #endif } } return; } #include <sys/wait.h> catchsig() { union wait status; struct rusage ru; if (wait3 (&status.w_status, WNOHANG | WUNTRACED, &ru) != child_pid) return; if (WIFSTOPPED (status) /* || WIFSIGNALED (status) */) { if (debug) { message ("Child has sttoped!!\n"); } suspend (); return; } terminate (); } exec_to_command(argv) char *argv[]; { int t; /* * Disconnect control terminal */ t = open ("/dev/tty", 2); if (t >= 0) { ioctl (t, TIOCNOTTY, (char *) 0); (void) close (t); } get_pty_slave (); (void) close (master); dup2 (slave, 0); dup2 (slave, 1); dup2 (slave, 2); (void) close (slave); ioctl (0, TIOCSETN, (char *) & slave_ttymode); execvp (*argv, argv, 0); perror (*argv); exit (1); } fix_tty() { struct tchars tcbuf; struct ltchars lcbuf; master_ttymode = initial_ttymode; slave_ttymode = initial_ttymode; tcbuf = tchars_buf; lcbuf = ltchars_buf; master_ttymode.sg_flags |= CBREAK; master_ttymode.sg_flags &= ~ECHO; slave_ttymode.sg_erase = -1; slave_ttymode.sg_kill = -1; slave_ttymode.sg_flags &= ~(ECHO|CRMOD); tcbuf.t_intrc = -1; tcbuf.t_quitc = -1; tcbuf.t_eofc = -1; tcbuf.t_brkc = -1; lcbuf.t_suspc = -1; lcbuf.t_dsuspc = -1; lcbuf.t_rprntc = -1; lcbuf.t_flushc = -1; lcbuf.t_werasc = -1; lcbuf.t_lnextc = -1; ioctl (0, TIOCSETN, (char *) & master_ttymode); ioctl (0, TIOCSETC, (char *) & tcbuf); ioctl (0, TIOCSLTC, (char *) & lcbuf); } kill_process() { if (child_pid) (void) killpg (child_pid, SIGTERM); } terminate() { extern int errno; /* * Save history if 'history-file' is set */ { char *cp, *mk_home_relative(), *look_var(); char buf [256]; int num; if (look_var ("savehist") && (cp = look_var ("history-file"))) { num = lookd_var ("savehist"); strcpy (buf, mk_home_relative (cp)); save_history (buf, num); } } /* * If scripting, close script file. */ if (script_fp) fclose (script_fp); (void) signal (SIGCHLD, SIG_IGN); if (killpg (child_pid, SIGTERM) < 0 && errno != ESRCH) if (killpg (child_pid, SIGHUP) < 0) if (killpg (child_pid, SIGKILL) < 0) perror ("kill"); ioctl (0, TIOCSETN, (char *) & initial_ttymode); ioctl (0, TIOCSETC, (char *) & tchars_buf); ioctl (0, TIOCSLTC, (char *) & ltchars_buf); exit (0); } get_pty_master() { char c; struct stat stb; int i; if (ptyflag == 0) { master = 1; return; } for (c = 'p'; c <= 's'; c++) { for (i = 0; i < 16; i++) { sprintf (master_tty, "/dev/pty%c%x", c, i); master = open (master_tty, O_RDWR); if (master >= 0) { sprintf (slave_tty, "/dev/tty%c%x", c, i); goto FOUND; } } } /* * Can't get master tty */ if (master < 0) { fprintf (stderr, "Couldn't open pseudo tty\n"); kill_process (); exit (1); } FOUND: 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); #ifdef TIOCGWINSZ { struct winsize win; if (ioctl (0, TIOCGWINSZ, &win) >= 0) { lines = win.ws_row; columns = win.ws_col; } } #endif #ifdef KANJI # if defined(TIOCKGET) && defined(TIOCKSET) ioctl (0, TIOCKGET, (char *) &kmode_buf); # endif # if defined(TIOCKGETC) && defined(TIOCKSETC) ioctl (0, TIOCKGETC, (char *) &jtchars_buf); # endif #endif KANJI stdinmask = 1 << fileno (stdin); mastermask = 1 << master; selectmask = stdinmask | mastermask; selectnfds = max (fileno(stdin), master) + 1; return; } get_pty_slave() { slave = open (slave_tty, 2); if (slave < 0) { perror (slave_tty); exit (1); } 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); #ifdef KANJI # if defined(TIOCKGET) && defined(TIOCKSET) ioctl (slave, TIOCKSET, (char *) &kmode_buf); # endif # if defined(TIOCKGETC) && defined(TIOCKSETC) ioctl (slave, TIOCKSETC, (char *) &jtchars_buf); # endif #endif KANJI #ifdef TIOCSWINSZ { struct winsize win; win.ws_row = lines; win.ws_col = columns; (void) ioctl (slave, TIOCSWINSZ, &win); } #endif } recover_tty() { ioctl (0, TIOCSETN, (char *) & initial_ttymode); ioctl (0, TIOCSETC, (char *) & tchars_buf); ioctl (0, TIOCSLTC, (char *) & ltchars_buf); } suspend() { long pid; int (*func) (); int omask; extern int errno; 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)); kill (0, SIGTSTP); if (kill (child_pid, SIGCONT) < 0 && errno == ESRCH) { printf ("Where my child has gone?!\n"); terminate (); } killpg (child_pid, SIGCONT); kill (0, SIGCONT); signal (SIGCHLD, func); signal (SIGTSTP, SIG_IGN); sigblock (mask (SIGTSTP)); fix_tty (); if (look_var ("auto-repaint")) fep_repaint(0); } look_cmdinfo (command) char *command; { struct cmdinfo *p; char *allocAndCopyThere(); if (strcmp (prompt, "") != 0) return; for (p = cmdinfo_tab; p->command; p++) { if (strcmp (command, p->command) == 0) { prompt = allocAndCopyThere (p->prompt); set_var ("prompt", p->prompt); set_var ("delimiters", p->delimiters); break; } } } usageAndExit() { printf ("Usage: %s [-emacs|-vi] command\n", myself); exit (1); } \End\Of\File\ else echo "will not over write ./fep_main.c" fi echo "Finished archive 4 of 5" exit -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.