home *** CD-ROM | disk | FTP | other *** search
- Subject: v16i064: Front end editor program, Part04/05
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- 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
-
-