From 4eaab145eb8bccf7e332dc1c75dea7d47ef18c86 Mon Sep 17 00:00:00 2001 From: Sami Kerola Date: Mon, 8 Oct 2012 08:08:17 +0100 Subject: more: fix coding style Signed-off-by: Sami Kerola --- text-utils/more.c | 3408 ++++++++++++++++++++++++++--------------------------- 1 file changed, 1694 insertions(+), 1714 deletions(-) (limited to 'text-utils/more.c') diff --git a/text-utils/more.c b/text-utils/more.c index 58c99cca6..d05639384 100644 --- a/text-utils/more.c +++ b/text-utils/more.c @@ -15,30 +15,33 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -/* -** more.c - General purpose tty output filter and file perusal program -** -** by Eric Shienbrood, UC Berkeley -** -** modified by Geoff Peck, UCB to add underlining, single spacing -** modified by John Foderaro, UCB to add -c and MORE environment variable -** modified by Erik Troan to be more posix and so compile -** on linux/axp. -** modified by Kars de Jong to use terminfo instead -** of termcap. - 1999-02-22 Arkadiusz Mi¶kiewicz - - added Native Language Support - 1999-03-19 Arnaldo Carvalho de Melo - - more nls translatable strings - 1999-05-09 aeb - applied a RedHat patch (setjmp->sigsetjmp); without it - a second ^Z would fail. - 1999-05-09 aeb - undone Kars' work, so that more works without - libcurses (and hence can be in /bin with libcurses being in /usr/lib - which may not be mounted). However, when termcap is not present curses - can still be used. - 2010-10-21 Davidlohr Bueso - - modified mem allocation handling for util-linux -*/ +/* more.c - General purpose tty output filter and file perusal program + * + * by Eric Shienbrood, UC Berkeley + * + * modified by Geoff Peck + * UCB to add underlining, single spacing + * modified by John Foderaro + * UCB to add -c and MORE environment variable + * modified by Erik Troan + * to be more posix and so compile on linux/axp. + * modified by Kars de Jong + * to use terminfo instead of termcap. + * 1999-02-22 Arkadiusz Mi¶kiewicz + * added Native Language Support + * 1999-03-19 Arnaldo Carvalho de Melo + * more nls translatable strings + * 1999-05-09 aeb + * applied a RedHat patch (setjmp->sigsetjmp); without it a second + * ^Z would fail. + * 1999-05-09 aeb + * undone Kars' work, so that more works without libcurses (and + * hence can be in /bin with libcurses being in + * /usr/lib which may not be mounted). However, when termcap is not + * present curses can still be used. + * 2010-10-21 Davidlohr Bueso + * modified mem allocation handling for util-linux + */ #include #include @@ -66,10 +69,10 @@ #include #ifndef XTABS -#define XTABS TAB3 -#endif /* XTABS */ +# define XTABS TAB3 +#endif -#define VI "vi" /* found on the user's path */ +#define VI "vi" /* found on the user's path */ #define Fopen(s,m) (Currline = 0,file_pos=0,fopen(s,m)) #define Ftell(f) file_pos @@ -89,37 +92,37 @@ void doclear(void); void cleareol(void); void clreos(void); void home(void); -void more_error (char *mess); -void do_shell (char *filename); -int colon (char *filename, int cmd, int nlines); -int expand (char **outbuf, char *inbuf); +void more_error(char *mess); +void do_shell(char *filename); +int colon(char *filename, int cmd, int nlines); +int expand(char **outbuf, char *inbuf); void argscan(char *s); -void rdline (register FILE *f); +void rdline(register FILE *f); void copy_file(register FILE *f); void search(char buf[], FILE *file, register int n); -void skipf (register int nskip); +void skipf(register int nskip); void skiplns(register int n, register FILE *f); -void screen (register FILE *f, register int num_lines); -int command (char *filename, register FILE *f); -void erasep (register int col); -void show (register char ch); +void screen(register FILE *f, register int num_lines); +int command(char *filename, register FILE *f); +void erasep(register int col); +void show(register char ch); void set_tty(void); void reset_tty(void); -void ttyin (char buf[], register int nmax, char pchar); -int number(char *cmd); -int readch (void); -int get_line(register FILE *f, int *length); -void prbuf (register char *s, register int n); -void execute (char *filename, char *cmd, ...); -FILE *checkf (char *, int *); +void ttyin(char buf[], register int nmax, char pchar); +int number(char *cmd); +int readch(void); +int get_line(register FILE *f, int *length); +void prbuf(register char *s, register int n); +void execute(char *filename, char *cmd, ...); +FILE *checkf(char *, int *); void prepare_line_buffer(void); -#define TBUFSIZ 1024 -#define LINSIZ 256 /* minimal Line buffer size */ +#define TBUFSIZ 1024 +#define LINSIZ 256 /* minimal Line buffer size */ #define ctrl(letter) (letter & 077) -#define RUBOUT '\177' -#define ESC '\033' -#define QUIT '\034' +#define RUBOUT '\177' +#define ESC '\033' +#define QUIT '\034' #define SCROLL_LEN 11 #define LINES_PER_PAGE 24 #define NUM_COLUMNS 80 @@ -129,419 +132,440 @@ void prepare_line_buffer(void); #define COMMAND_BUF 200 #define REGERR_BUF NUM_COLUMNS -struct termios otty, savetty0; -long file_pos, file_size; -int fnum, no_intty, no_tty, slow_tty; -int dum_opt, dlines; -void onquit(int), onsusp(int), chgwinsz(int), end_it(int); -int nscroll = SCROLL_LEN; /* Number of lines scrolled by 'd' */ -int fold_opt = 1; /* Fold long lines */ -int stop_opt = 1; /* Stop after form feeds */ -int ssp_opt = 0; /* Suppress white space */ -int ul_opt = 1; /* Underline as best we can */ -int promptlen; -int Currline; /* Line we are currently at */ -int startup = 1; -int firstf = 1; -int notell = 1; -int docrterase = 0; -int docrtkill = 0; -int bad_so; /* True if overwriting does not turn - off standout */ -int inwait, Pause, errors; -int within; /* true if we are within a file, - false if we are between files */ -int hard, dumb, noscroll, hardtabs, clreol, eatnl; -int catch_susp; /* We should catch the SIGTSTP signal */ -char **fnames; /* The list of file names */ -int nfiles; /* Number of files left to process */ -char *shell; /* The name of the shell to use */ -int shellp; /* A previous shell command exists */ -sigjmp_buf restore; -char *Line; /* Line buffer */ -size_t LineLen; /* size of Line buffer */ -int Lpp = LINES_PER_PAGE; /* lines per page */ -char *Clear; /* clear screen */ -char *eraseln; /* erase line */ -char *Senter, *Sexit; /* enter and exit standout mode */ -char *ULenter, *ULexit; /* enter and exit underline mode */ -char *chUL; /* underline character */ -char *chBS; /* backspace character */ -char *Home; /* go to home */ -char *cursorm; /* cursor movement */ -char cursorhome[40]; /* contains cursor movement to home */ -char *EodClr; /* clear rest of screen */ -int Mcol = NUM_COLUMNS; /* number of columns */ -int Wrap = 1; /* set if automargins */ -int soglitch; /* terminal has standout mode glitch */ -int ulglitch; /* terminal has underline mode glitch */ -int pstate = 0; /* current UL state */ -static int magic(FILE *, char *); -char *previousre; /* previous search() buf[] item */ +struct termios otty, savetty0; +long file_pos, file_size; +int fnum, no_intty, no_tty, slow_tty; +int dum_opt, dlines; +void onquit(int), onsusp(int), chgwinsz(int), end_it(int); +int nscroll = SCROLL_LEN; /* Number of lines scrolled by 'd' */ +int fold_opt = 1; /* Fold long lines */ +int stop_opt = 1; /* Stop after form feeds */ +int ssp_opt = 0; /* Suppress white space */ +int ul_opt = 1; /* Underline as best we can */ +int promptlen; +int Currline; /* Line we are currently at */ +int startup = 1; +int firstf = 1; +int notell = 1; +int docrterase = 0; +int docrtkill = 0; +int bad_so; /* True if overwriting does not turn + off standout */ +int inwait, Pause, errors; +int within; /* true if we are within a file, + false if we are between files */ +int hard, dumb, noscroll, hardtabs, clreol, eatnl; +int catch_susp; /* We should catch the SIGTSTP signal */ +char **fnames; /* The list of file names */ +int nfiles; /* Number of files left to process */ +char *shell; /* The name of the shell to use */ +int shellp; /* A previous shell command exists */ +sigjmp_buf restore; +char *Line; /* Line buffer */ +size_t LineLen; /* size of Line buffer */ +int Lpp = LINES_PER_PAGE; /* lines per page */ +char *Clear; /* clear screen */ +char *eraseln; /* erase line */ +char *Senter, *Sexit; /* enter and exit standout mode */ +char *ULenter, *ULexit; /* enter and exit underline mode */ +char *chUL; /* underline character */ +char *chBS; /* backspace character */ +char *Home; /* go to home */ +char *cursorm; /* cursor movement */ +char cursorhome[40]; /* contains cursor movement to home */ +char *EodClr; /* clear rest of screen */ +int Mcol = NUM_COLUMNS; /* number of columns */ +int Wrap = 1; /* set if automargins */ +int soglitch; /* terminal has standout mode glitch */ +int ulglitch; /* terminal has underline mode glitch */ +int pstate = 0; /* current UL state */ +static int magic(FILE *, char *); +char *previousre; /* previous search() buf[] item */ struct { - long chrctr, line; + long chrctr, line; } context, screen_start; -extern char PC; /* pad character */ +extern char PC; /* pad character */ #ifdef HAVE_NCURSES_H # include #elif defined(HAVE_NCURSES_NCURSES_H) # include -#endif /* HAVE_NCURSES_H */ +#endif #if defined(HAVE_NCURSES_H) || defined(HAVE_NCURSES_NCURSES_H) -# include /* include after */ - -#define TERM_AUTO_RIGHT_MARGIN "am" -#define TERM_CEOL "xhp" -#define TERM_CLEAR "clear" -#define TERM_CLEAR_TO_LINE_END "el" -#define TERM_CLEAR_TO_SCREEN_END "ed" -#define TERM_COLS "cols" -#define TERM_CURSOR_ADDRESS "cup" -#define TERM_EAT_NEW_LINE "xenl" -#define TERM_ENTER_UNDERLINE "smul" -#define TERM_EXIT_STANDARD_MODE "rmso" -#define TERM_EXIT_UNDERLINE "rmul" -#define TERM_HARD_COPY "hc" -#define TERM_HOME "home" -#define TERM_LINE_DOWN "cud1" -#define TERM_LINES "lines" -#define TERM_OVER_STRIKE "os" -#define TERM_PAD_CHAR "pad" -#define TERM_STANDARD_MODE "smso" -#define TERM_STD_MODE_GLITCH "xmc" -#define TERM_UNDERLINE_CHAR "uc" -#define TERM_UNDERLINE "ul" - -static void my_putstring(char *s) { - tputs (s, fileno(stdout), putchar); /* putp(s); */ +# include /* include after */ + +# define TERM_AUTO_RIGHT_MARGIN "am" +# define TERM_CEOL "xhp" +# define TERM_CLEAR "clear" +# define TERM_CLEAR_TO_LINE_END "el" +# define TERM_CLEAR_TO_SCREEN_END "ed" +# define TERM_COLS "cols" +# define TERM_CURSOR_ADDRESS "cup" +# define TERM_EAT_NEW_LINE "xenl" +# define TERM_ENTER_UNDERLINE "smul" +# define TERM_EXIT_STANDARD_MODE "rmso" +# define TERM_EXIT_UNDERLINE "rmul" +# define TERM_HARD_COPY "hc" +# define TERM_HOME "home" +# define TERM_LINE_DOWN "cud1" +# define TERM_LINES "lines" +# define TERM_OVER_STRIKE "os" +# define TERM_PAD_CHAR "pad" +# define TERM_STANDARD_MODE "smso" +# define TERM_STD_MODE_GLITCH "xmc" +# define TERM_UNDERLINE_CHAR "uc" +# define TERM_UNDERLINE "ul" + +static void my_putstring(char *s) +{ + tputs(s, fileno(stdout), putchar); /* putp(s); */ } -static void my_setupterm(char *term, int fildes, int *errret) { - setupterm(term, fildes, errret); +static void my_setupterm(char *term, int fildes, int *errret) +{ + setupterm(term, fildes, errret); } -static int my_tgetnum(char *s) { - return tigetnum(s); +static int my_tgetnum(char *s) +{ + return tigetnum(s); } -static int my_tgetflag(char *s) { - return tigetflag(s); +static int my_tgetflag(char *s) +{ + return tigetflag(s); } -static char *my_tgetstr(char *s) { - return tigetstr(s); +static char *my_tgetstr(char *s) +{ + return tigetstr(s); } -static char *my_tgoto(char *cap, int col, int row) { - return tparm(cap, col, row); +static char *my_tgoto(char *cap, int col, int row) +{ + return tparm(cap, col, row); } -#elif defined(HAVE_LIBTERMCAP) /* !ncurses */ - -#include - -#define TERM_AUTO_RIGHT_MARGIN "am" -#define TERM_CEOL "xs" -#define TERM_CLEAR "cl" -#define TERM_CLEAR_TO_LINE_END "ce" -#define TERM_CLEAR_TO_SCREEN_END "cd" -#define TERM_COLS "co" -#define TERM_CURSOR_ADDRESS "cm" -#define TERM_EAT_NEW_LINE "xn" -#define TERM_ENTER_UNDERLINE "us" -#define TERM_EXIT_STANDARD_MODE "se" -#define TERM_EXIT_UNDERLINE "ue" -#define TERM_HARD_COPY "hc" -#define TERM_HOME "ho" -#define TERM_LINE_DOWN "le" -#define TERM_LINES "li" -#define TERM_OVER_STRIKE "os" -#define TERM_PAD_CHAR "pc" -#define TERM_STANDARD_MODE "so" -#define TERM_STD_MODE_GLITCH "sg" -#define TERM_UNDERLINE_CHAR "uc" -#define TERM_UNDERLINE "ul" +#elif defined(HAVE_LIBTERMCAP) /* ncurses not found */ + +# include + +# define TERM_AUTO_RIGHT_MARGIN "am" +# define TERM_CEOL "xs" +# define TERM_CLEAR "cl" +# define TERM_CLEAR_TO_LINE_END "ce" +# define TERM_CLEAR_TO_SCREEN_END "cd" +# define TERM_COLS "co" +# define TERM_CURSOR_ADDRESS "cm" +# define TERM_EAT_NEW_LINE "xn" +# define TERM_ENTER_UNDERLINE "us" +# define TERM_EXIT_STANDARD_MODE "se" +# define TERM_EXIT_UNDERLINE "ue" +# define TERM_HARD_COPY "hc" +# define TERM_HOME "ho" +# define TERM_LINE_DOWN "le" +# define TERM_LINES "li" +# define TERM_OVER_STRIKE "os" +# define TERM_PAD_CHAR "pc" +# define TERM_STANDARD_MODE "so" +# define TERM_STD_MODE_GLITCH "sg" +# define TERM_UNDERLINE_CHAR "uc" +# define TERM_UNDERLINE "ul" char termbuffer[TERMINAL_BUF]; char tcbuffer[TERMINAL_BUF]; char *strbuf = termbuffer; -static void my_putstring(char *s) { - tputs (s, fileno(stdout), putchar); +static void my_putstring(char *s) +{ + tputs(s, fileno(stdout), putchar); } -static void my_setupterm(char *term, int fildes, int *errret) { - *errret = tgetent(tcbuffer, term); +static void my_setupterm(char *term, int fildes, int *errret) +{ + *errret = tgetent(tcbuffer, term); } -static int my_tgetnum(char *s) { - return tgetnum(s); +static int my_tgetnum(char *s) +{ + return tgetnum(s); } -static int my_tgetflag(char *s) { - return tgetflag(s); +static int my_tgetflag(char *s) +{ + return tgetflag(s); } -static char *my_tgetstr(char *s) { - return tgetstr(s, &strbuf); +static char *my_tgetstr(char *s) +{ + return tgetstr(s, &strbuf); } -static char *my_tgoto(char *cap, int col, int row) { - return tgoto(cap, col, row); +static char *my_tgoto(char *cap, int col, int row) +{ + return tgoto(cap, col, row); } -#endif /* HAVE_LIBTERMCAP */ +#endif /* HAVE_LIBTERMCAP */ -static void __attribute__ ((__noreturn__)) usage(FILE *out) +static void __attribute__((__noreturn__)) usage(FILE *out) { - fprintf(out, - _("Usage: %s [options] file...\n\n"), - program_invocation_short_name); - fprintf(out, - _("Options:\n" - " -d display help instead of ring bell\n" - " -f count logical, rather than screen lines\n" - " -l suppress pause after form feed\n" - " -p suppress scroll, clean screen and display text\n" - " -c suppress scroll, display text and clean line ends\n" - " -u suppress underlining\n" - " -s squeeze multiple blank lines into one\n" - " -NUM specify the number of lines per screenful\n" - " +NUM display file beginning from line number NUM\n" - " +/STRING display file beginning from search string match\n" - " -V output version information and exit\n")); - exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS); + fprintf(out, + _("Usage: %s [options] file...\n\n"), + program_invocation_short_name); + fprintf(out, + _("Options:\n" + " -d display help instead of ring bell\n" + " -f count logical, rather than screen lines\n" + " -l suppress pause after form feed\n" + " -p suppress scroll, clean screen and display text\n" + " -c suppress scroll, display text and clean line ends\n" + " -u suppress underlining\n" + " -s squeeze multiple blank lines into one\n" + " -NUM specify the number of lines per screenful\n" + " +NUM display file beginning from line number NUM\n" + " +/STRING display file beginning from search string match\n" + " -V output version information and exit\n")); + exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS); } -int main(int argc, char **argv) { - FILE *f; - char *s; - int ch; - int left; - int prnames = 0; - int initopt = 0; - int srchopt = 0; - int clearit = 0; - int initline = 0; - char *initbuf = NULL; - - setlocale(LC_ALL, ""); - bindtextdomain(PACKAGE, LOCALEDIR); - textdomain(PACKAGE); - atexit(close_stdout); - - nfiles = argc; - fnames = argv; - setlocale(LC_ALL, ""); - initterm (); - - /* Auto set no scroll on when binary is called page */ - if (!(strcmp(program_invocation_short_name, "page"))) - noscroll++; - - prepare_line_buffer(); - - nscroll = Lpp/2 - 1; - if (nscroll <= 0) - nscroll = 1; - - if ((s = getenv("MORE")) != NULL) - argscan(s); - - while (--nfiles > 0) { - if ((ch = (*++fnames)[0]) == '-') { - argscan(*fnames+1); +int main(int argc, char **argv) +{ + FILE *f; + char *s; + int ch; + int left; + int prnames = 0; + int initopt = 0; + int srchopt = 0; + int clearit = 0; + int initline = 0; + char *initbuf = NULL; + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + atexit(close_stdout); + + nfiles = argc; + fnames = argv; + setlocale(LC_ALL, ""); + initterm(); + + /* Auto set no scroll on when binary is called page */ + if (!(strcmp(program_invocation_short_name, "page"))) + noscroll++; + + prepare_line_buffer(); + + nscroll = Lpp / 2 - 1; + if (nscroll <= 0) + nscroll = 1; + + if ((s = getenv("MORE")) != NULL) + argscan(s); + + while (--nfiles > 0) { + if ((ch = (*++fnames)[0]) == '-') { + argscan(*fnames + 1); + } else if (ch == '+') { + s = *fnames; + if (*++s == '/') { + srchopt++; + initbuf = xstrdup(s + 1); + } else { + initopt++; + for (initline = 0; *s != '\0'; s++) + if (isdigit(*s)) + initline = + initline * 10 + *s - '0'; + --initline; + } + } else + break; } - else if (ch == '+') { - s = *fnames; - if (*++s == '/') { - srchopt++; - initbuf = xstrdup(s + 1); - } - else { - initopt++; - for (initline = 0; *s != '\0'; s++) - if (isdigit (*s)) - initline = initline*10 + *s -'0'; - --initline; - } + /* allow clreol only if Home and eraseln and EodClr strings are + * defined, and in that case, make sure we are in noscroll mode */ + if (clreol) { + if ((Home == NULL) || (*Home == '\0') || + (eraseln == NULL) || (*eraseln == '\0') || + (EodClr == NULL) || (*EodClr == '\0')) + clreol = 0; + else + noscroll = 1; } - else break; - } - /* allow clreol only if Home and eraseln and EodClr strings are - * defined, and in that case, make sure we are in noscroll mode - */ - if (clreol) { - if((Home == NULL) || (*Home == '\0') || - (eraseln == NULL) || (*eraseln == '\0') || - (EodClr == NULL) || (*EodClr == '\0') ) - clreol = 0; - else noscroll = 1; - } - if (dlines == 0) - dlines = Lpp - 1; /* was: Lpp - (noscroll ? 1 : 2) */ - left = dlines; - if (nfiles > 1) - prnames++; - if (!no_intty && nfiles == 0) - usage(stderr); - else - f = stdin; - if (!no_tty) { - signal(SIGQUIT, onquit); - signal(SIGINT, end_it); + if (dlines == 0) + dlines = Lpp - 1; /* was: Lpp - (noscroll ? 1 : 2) */ + left = dlines; + if (nfiles > 1) + prnames++; + if (!no_intty && nfiles == 0) + usage(stderr); + else + f = stdin; + if (!no_tty) { + signal(SIGQUIT, onquit); + signal(SIGINT, end_it); #ifdef SIGWINCH - signal(SIGWINCH, chgwinsz); -#endif /* SIGWINCH */ - if (signal (SIGTSTP, SIG_IGN) == SIG_DFL) { - signal(SIGTSTP, onsusp); - catch_susp++; - } - stty (fileno(stderr), &otty); - } - if (no_intty) { - if (no_tty) - copy_file (stdin); - else { - if ((ch = Getc (f)) == '\f') - doclear(); - else { - Ungetc (ch, f); - if (noscroll && (ch != EOF)) { - if (clreol) - home (); - else - doclear (); + signal(SIGWINCH, chgwinsz); +#endif + if (signal(SIGTSTP, SIG_IGN) == SIG_DFL) { + signal(SIGTSTP, onsusp); + catch_susp++; } - } - if (srchopt) - { - previousre = xstrdup(initbuf); - search (initbuf, stdin, 1); - if (noscroll) - left--; - } - else if (initopt) - skiplns (initline, stdin); - screen (stdin, left); + stty(fileno(stderr), &otty); } - no_intty = 0; - prnames++; - firstf = 0; - } - - while (fnum < nfiles) { - if ((f = checkf (fnames[fnum], &clearit)) != NULL) { - context.line = context.chrctr = 0; - Currline = 0; - if (firstf) sigsetjmp (restore, 1); - if (firstf) { - firstf = 0; - if (srchopt) { - previousre = xstrdup(initbuf); - search (initbuf, f, 1); - if (noscroll) - left--; - } - else if (initopt) - skiplns (initline, f); - } - else if (fnum < nfiles && !no_tty) { - sigsetjmp (restore, 1); - left = command (fnames[fnum], f); - } - if (left != 0) { - if ((noscroll || clearit) && (file_size != LONG_MAX)) { - if (clreol) - home (); - else - doclear (); - } - if (prnames) { - if (bad_so) - erasep (0); - if (clreol) - cleareol (); - putsout("::::::::::::::"); - if (promptlen > 14) - erasep (14); - putchar('\n'); - if(clreol) cleareol(); - puts(fnames[fnum]); - if(clreol) cleareol(); - puts("::::::::::::::"); - if (left > Lpp - 4) - left = Lpp - 4; - } + if (no_intty) { if (no_tty) - copy_file (f); + copy_file(stdin); else { - within++; - screen(f, left); - within = 0; + if ((ch = Getc(f)) == '\f') + doclear(); + else { + Ungetc(ch, f); + if (noscroll && (ch != EOF)) { + if (clreol) + home(); + else + doclear(); + } + } + if (srchopt) { + previousre = xstrdup(initbuf); + search(initbuf, stdin, 1); + if (noscroll) + left--; + } else if (initopt) + skiplns(initline, stdin); + screen(stdin, left); + } + no_intty = 0; + prnames++; + firstf = 0; + } + + while (fnum < nfiles) { + if ((f = checkf(fnames[fnum], &clearit)) != NULL) { + context.line = context.chrctr = 0; + Currline = 0; + if (firstf) + sigsetjmp(restore, 1); + if (firstf) { + firstf = 0; + if (srchopt) { + previousre = xstrdup(initbuf); + search(initbuf, f, 1); + if (noscroll) + left--; + } else if (initopt) + skiplns(initline, f); + } else if (fnum < nfiles && !no_tty) { + sigsetjmp(restore, 1); + left = command(fnames[fnum], f); + } + if (left != 0) { + if ((noscroll || clearit) + && (file_size != LONG_MAX)) { + if (clreol) + home(); + else + doclear(); + } + if (prnames) { + if (bad_so) + erasep(0); + if (clreol) + cleareol(); + putsout("::::::::::::::"); + if (promptlen > 14) + erasep(14); + putchar('\n'); + if (clreol) + cleareol(); + puts(fnames[fnum]); + if (clreol) + cleareol(); + puts("::::::::::::::"); + if (left > Lpp - 4) + left = Lpp - 4; + } + if (no_tty) + copy_file(f); + else { + within++; + screen(f, left); + within = 0; + } + } + sigsetjmp(restore, 1); + fflush(stdout); + fclose(f); + screen_start.line = screen_start.chrctr = 0L; + context.line = context.chrctr = 0L; } - } - sigsetjmp (restore, 1); - fflush(stdout); - fclose(f); - screen_start.line = screen_start.chrctr = 0L; - context.line = context.chrctr = 0L; + fnum++; + firstf = 0; } - fnum++; - firstf = 0; - } - free (previousre); - free (initbuf); - reset_tty (); - exit(EXIT_SUCCESS); + free(previousre); + free(initbuf); + reset_tty(); + exit(EXIT_SUCCESS); } -void argscan(char *s) { +void argscan(char *s) +{ int seen_num = 0; while (*s != '\0') { switch (*s) { - case '0': case '1': case '2': - case '3': case '4': case '5': - case '6': case '7': case '8': - case '9': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': if (!seen_num) { dlines = 0; seen_num = 1; } - dlines = dlines*10 + *s - '0'; + dlines = dlines * 10 + *s - '0'; break; - case 'd': + case 'd': dum_opt = 1; break; - case 'l': + case 'l': stop_opt = 0; break; - case 'f': + case 'f': fold_opt = 0; break; - case 'p': + case 'p': noscroll++; break; - case 'c': + case 'c': clreol++; break; - case 's': + case 's': ssp_opt = 1; break; - case 'u': + case 'u': ul_opt = 0; break; - case '-': case ' ': case '\t': + case '-': + case ' ': + case '\t': + break; + case 'V': + printf(_("more (%s)\n"), PACKAGE_STRING); + exit(EXIT_SUCCESS); break; - case 'V': - printf(_("more (%s)\n"), PACKAGE_STRING); - exit(EXIT_SUCCESS); - break; - default: - warnx(_("unknown option -%s"), s); + default: + warnx(_("unknown option -%s"), s); usage(stderr); break; } @@ -549,57 +573,46 @@ void argscan(char *s) { } } - -/* -** Check whether the file named by fs is an ASCII file which the user may -** access. If it is, return the opened file. Otherwise return NULL. -*/ - -FILE * -checkf (fs, clearfirst) - register char *fs; - int *clearfirst; +/* Check whether the file named by fs is an ASCII file which the user may + * access. If it is, return the opened file. Otherwise return NULL. */ +FILE *checkf(register char *fs, int *clearfirst) { struct stat stbuf; register FILE *f; int c; - if (stat (fs, &stbuf) == -1) { + if (stat(fs, &stbuf) == -1) { (void)fflush(stdout); if (clreol) - cleareol (); + cleareol(); perror(fs); - return((FILE *)NULL); + return ((FILE *)NULL); } if ((stbuf.st_mode & S_IFMT) == S_IFDIR) { printf(_("\n*** %s: directory ***\n\n"), fs); - return((FILE *)NULL); + return ((FILE *)NULL); } if ((f = Fopen(fs, "r")) == NULL) { (void)fflush(stdout); perror(fs); - return((FILE *)NULL); + return ((FILE *)NULL); } if (magic(f, fs)) - return((FILE *)NULL); - fcntl(fileno(f), F_SETFD, FD_CLOEXEC ); + return ((FILE *)NULL); + fcntl(fileno(f), F_SETFD, FD_CLOEXEC); c = Getc(f); *clearfirst = (c == '\f'); - Ungetc (c, f); + Ungetc(c, f); if ((file_size = stbuf.st_size) == 0) file_size = LONG_MAX; - return(f); + return (f); } -/* - * magic -- - * check for file magic numbers. This code would best be shared with - * the file(1) program or, perhaps, more should not try to be so smart. - */ -static int -magic(f, fs) - FILE *f; - char *fs; +/* magic -- + * check for file magic numbers. This code would best be shared + * with the file(1) program or, perhaps, more should not try to be + * so smart. */ +static int magic(FILE *f, char *fs) { signed char twobytes[2]; @@ -608,930 +621,900 @@ magic(f, fs) return 0; if (fread(twobytes, 2, 1, f) == 1) { - switch(twobytes[0] + (twobytes[1]<<8)) { + switch (twobytes[0] + (twobytes[1] << 8)) { case 0407: /* a.out obj */ case 0410: /* a.out exec */ case 0413: /* a.out demand exec */ case 0405: case 0411: case 0177545: - case 0x457f: /* simple ELF detection */ - printf(_("\n******** %s: Not a text file ********\n\n"), fs); + case 0x457f: /* simple ELF detection */ + printf(_("\n******** %s: Not a text file ********\n\n"), + fs); (void)fclose(f); return 1; } } - (void)fseek(f, 0L, SEEK_SET); /* rewind() not necessary */ + (void)fseek(f, 0L, SEEK_SET); /* rewind() not necessary */ return 0; } -/* -** Print out the contents of the file f, one screenful at a time. -*/ - +/* Print out the contents of the file f, one screenful at a time. */ #define STOP -10 - -void screen (register FILE *f, register int num_lines) +void screen(register FILE *f, register int num_lines) { - register int c; - register int nchars; - int length; /* length of current line */ - static int prev_len = 1; /* length of previous line */ - - for (;;) { - while (num_lines > 0 && !Pause) { - if ((nchars = get_line (f, &length)) == EOF) - { - if (clreol) - clreos(); - return; - } - if (ssp_opt && length == 0 && prev_len == 0) - continue; - prev_len = length; - if (bad_so || ((Senter && *Senter == ' ') && (promptlen > 0))) - erasep (0); - /* must clear before drawing line since tabs on some terminals - * do not erase what they tab over. - */ - if (clreol) - cleareol (); - prbuf (Line, length); - if (nchars < promptlen) - erasep (nchars); /* erasep () sets promptlen to 0 */ - else promptlen = 0; - /* is this needed? - * if (clreol) - * cleareol(); * must clear again in case we wrapped * - */ - if (nchars < Mcol || !fold_opt) - prbuf("\n", 1); /* will turn off UL if necessary */ - if (nchars == STOP) - break; - num_lines--; - } - if (pstate) { - my_putstring (ULexit); - pstate = 0; - } - fflush(stdout); - if ((c = Getc(f)) == EOF) - { - if (clreol) - clreos (); - return; - } + register int c; + register int nchars; + int length; /* length of current line */ + static int prev_len = 1; /* length of previous line */ - if (Pause && clreol) - clreos (); - Ungetc (c, f); - sigsetjmp (restore, 1); - Pause = 0; startup = 0; - if ((num_lines = command (NULL, f)) == 0) - return; - if (hard && promptlen > 0) - erasep (0); - if (noscroll && num_lines >= dlines) - { - if (clreol) - home(); - else - doclear (); + for (;;) { + while (num_lines > 0 && !Pause) { + if ((nchars = get_line(f, &length)) == EOF) { + if (clreol) + clreos(); + return; + } + if (ssp_opt && length == 0 && prev_len == 0) + continue; + prev_len = length; + if (bad_so + || ((Senter && *Senter == ' ') && (promptlen > 0))) + erasep(0); + /* must clear before drawing line since tabs on + * some terminals do not erase what they tab + * over. */ + if (clreol) + cleareol(); + prbuf(Line, length); + if (nchars < promptlen) + erasep(nchars); /* erasep () sets promptlen to 0 */ + else + promptlen = 0; + /* is this needed? + * if (clreol) + * cleareol(); * must clear again in case we wrapped * + */ + if (nchars < Mcol || !fold_opt) + prbuf("\n", 1); /* will turn off UL if necessary */ + if (nchars == STOP) + break; + num_lines--; + } + if (pstate) { + my_putstring(ULexit); + pstate = 0; + } + fflush(stdout); + if ((c = Getc(f)) == EOF) { + if (clreol) + clreos(); + return; + } + + if (Pause && clreol) + clreos(); + Ungetc(c, f); + sigsetjmp(restore, 1); + Pause = 0; + startup = 0; + if ((num_lines = command(NULL, f)) == 0) + return; + if (hard && promptlen > 0) + erasep(0); + if (noscroll && num_lines >= dlines) { + if (clreol) + home(); + else + doclear(); + } + screen_start.line = Currline; + screen_start.chrctr = Ftell(f); } - screen_start.line = Currline; - screen_start.chrctr = Ftell (f); - } } -/* -** Come here if a quit signal is received -*/ - -void onquit(int dummy __attribute__ ((__unused__))) +/* Come here if a quit signal is received */ +void onquit(int dummy __attribute__((__unused__))) { - signal(SIGQUIT, SIG_IGN); - if (!inwait) { - putchar ('\n'); - if (!startup) { - signal(SIGQUIT, onquit); - siglongjmp (restore, 1); + signal(SIGQUIT, SIG_IGN); + if (!inwait) { + putchar('\n'); + if (!startup) { + signal(SIGQUIT, onquit); + siglongjmp(restore, 1); + } else + Pause++; + } else if (!dum_opt && notell) { + promptlen += fprintf(stderr, _("[Use q or Q to quit]")); + notell = 0; } - else - Pause++; - } - else if (!dum_opt && notell) { - promptlen += fprintf(stderr, _("[Use q or Q to quit]")); - notell = 0; - } - signal(SIGQUIT, onquit); + signal(SIGQUIT, onquit); } -/* -** Come here if a signal for a window size change is received -*/ - +/* Come here if a signal for a window size change is received */ #ifdef SIGWINCH -void chgwinsz(int dummy __attribute__ ((__unused__))) +void chgwinsz(int dummy __attribute__((__unused__))) { - struct winsize win; - - signal(SIGWINCH, SIG_IGN); - if (ioctl(fileno(stdout), TIOCGWINSZ, &win) != -1) { - if (win.ws_row != 0) { - Lpp = win.ws_row; - nscroll = Lpp/2 - 1; - if (nscroll <= 0) - nscroll = 1; - dlines = Lpp - 1; /* was: Lpp - (noscroll ? 1 : 2) */ + struct winsize win; + + signal(SIGWINCH, SIG_IGN); + if (ioctl(fileno(stdout), TIOCGWINSZ, &win) != -1) { + if (win.ws_row != 0) { + Lpp = win.ws_row; + nscroll = Lpp / 2 - 1; + if (nscroll <= 0) + nscroll = 1; + dlines = Lpp - 1; /* was: Lpp - (noscroll ? 1 : 2) */ + } + if (win.ws_col != 0) + Mcol = win.ws_col; } - if (win.ws_col != 0) - Mcol = win.ws_col; - } - (void) signal(SIGWINCH, chgwinsz); + (void)signal(SIGWINCH, chgwinsz); } -#endif /* SIGWINCH */ +#endif /* SIGWINCH */ -/* -** Clean up terminal state and exit. Also come here if interrupt signal received -*/ - -void __attribute__((__noreturn__)) -end_it (int dummy __attribute__ ((__unused__))) +/* Clean up terminal state and exit. Also come here if interrupt signal received */ +void __attribute__((__noreturn__)) end_it(int dummy __attribute__((__unused__))) { - reset_tty (); - if (clreol) { - putchar ('\r'); - clreos (); - fflush (stdout); - } - else if (!clreol && (promptlen > 0)) { - kill_line (); - fflush (stdout); - } - else - putcerr('\n'); - _exit(EXIT_SUCCESS); + reset_tty(); + if (clreol) { + putchar('\r'); + clreos(); + fflush(stdout); + } else if (!clreol && (promptlen > 0)) { + kill_line(); + fflush(stdout); + } else + putcerr('\n'); + _exit(EXIT_SUCCESS); } -void copy_file(register FILE *f) { - register int c; +void copy_file(register FILE *f) +{ + register int c; - while ((c = getc(f)) != EOF) - putchar(c); + while ((c = getc(f)) != EOF) + putchar(c); } #define ringbell() putcerr('\007') -static void prompt (char *filename) +static void prompt(char *filename) { - if (clreol) - cleareol (); - else if (promptlen > 0) - kill_line (); - if (!hard) { - promptlen = 0; - if (Senter && Sexit) { - my_putstring (Senter); - promptlen += (2 * soglitch); - } if (clreol) - cleareol (); - promptlen += printf(_("--More--")); - if (filename != NULL) { - promptlen += printf(_("(Next file: %s)"), filename); - } else if (!no_intty) { - promptlen += printf("(%d%%)", (int) ((file_pos * 100) / file_size)); - } - if (dum_opt) { - promptlen += printf(_("[Press space to continue, 'q' to quit.]")); - } - if (Senter && Sexit) - my_putstring (Sexit); - if (clreol) - clreos (); - fflush(stdout); - } - else - ringbell(); - inwait++; + cleareol(); + else if (promptlen > 0) + kill_line(); + if (!hard) { + promptlen = 0; + if (Senter && Sexit) { + my_putstring(Senter); + promptlen += (2 * soglitch); + } + if (clreol) + cleareol(); + promptlen += printf(_("--More--")); + if (filename != NULL) { + promptlen += printf(_("(Next file: %s)"), filename); + } else if (!no_intty) { + promptlen += + printf("(%d%%)", + (int)((file_pos * 100) / file_size)); + } + if (dum_opt) { + promptlen += + printf(_("[Press space to continue, 'q' to quit.]")); + } + if (Senter && Sexit) + my_putstring(Sexit); + if (clreol) + clreos(); + fflush(stdout); + } else + ringbell(); + inwait++; } void prepare_line_buffer(void) { - char *nline; - size_t nsz = Mcol * 4; + char *nline; + size_t nsz = Mcol * 4; - if (LineLen >= nsz) - return; + if (LineLen >= nsz) + return; - if (nsz < LINSIZ) - nsz = LINSIZ; + if (nsz < LINSIZ) + nsz = LINSIZ; - nline = xrealloc(Line, nsz); - Line = nline; - LineLen = nsz; + nline = xrealloc(Line, nsz); + Line = nline; + LineLen = nsz; } -/* - * Get a logical line - */ - +/* Get a logical line */ int get_line(register FILE *f, int *length) { - int c; - char *p; - int column; - static int colflg; + int c; + char *p; + int column; + static int colflg; #ifdef HAVE_WIDECHAR - size_t i; - wchar_t wc; - int wc_width; - mbstate_t state, state_bak; /* Current status of the stream. */ - char mbc[MB_LEN_MAX]; /* Buffer for one multibyte char. */ - size_t mblength; /* Byte length of multibyte char. */ - size_t mbc_pos = 0; /* Position of the MBC. */ - int use_mbc_buffer_flag = 0; /* If 1, mbc has data. */ - int break_flag = 0; /* If 1, exit while(). */ - long file_pos_bak = Ftell (f); - - memset (&state, '\0', sizeof (mbstate_t)); -#endif /* HAVE_WIDECHAR */ - - prepare_line_buffer(); - - p = Line; - column = 0; - c = Getc (f); - if (colflg && c == '\n') { - Currline++; - c = Getc (f); - } - while (p < &Line[LineLen - 1]) { + size_t i; + wchar_t wc; + int wc_width; + mbstate_t state, state_bak; /* Current status of the stream. */ + char mbc[MB_LEN_MAX]; /* Buffer for one multibyte char. */ + size_t mblength; /* Byte length of multibyte char. */ + size_t mbc_pos = 0; /* Position of the MBC. */ + int use_mbc_buffer_flag = 0; /* If 1, mbc has data. */ + int break_flag = 0; /* If 1, exit while(). */ + long file_pos_bak = Ftell(f); + + memset(&state, '\0', sizeof(mbstate_t)); +#endif + + prepare_line_buffer(); + + p = Line; + column = 0; + c = Getc(f); + if (colflg && c == '\n') { + Currline++; + c = Getc(f); + } + while (p < &Line[LineLen - 1]) { #ifdef HAVE_WIDECHAR - if (fold_opt && use_mbc_buffer_flag && MB_CUR_MAX > 1) { - use_mbc_buffer_flag = 0; - state_bak = state; - mbc[mbc_pos++] = c; -process_mbc: - mblength = mbrtowc (&wc, mbc, mbc_pos, &state); - - switch (mblength) { - case (size_t)-2: /* Incomplete multibyte character. */ - use_mbc_buffer_flag = 1; - state = state_bak; - break; - - case (size_t)-1: /* Invalid as a multibyte character. */ - *p++ = mbc[0]; - state = state_bak; - column++; - file_pos_bak++; - - if (column >= Mcol) { - Fseek (f, file_pos_bak); - } else { - memmove (mbc, mbc + 1, --mbc_pos); - if (mbc_pos > 0) { - mbc[mbc_pos] = '\0'; - goto process_mbc; - } - } - break; + if (fold_opt && use_mbc_buffer_flag && MB_CUR_MAX > 1) { + use_mbc_buffer_flag = 0; + state_bak = state; + mbc[mbc_pos++] = c; + process_mbc: + mblength = mbrtowc(&wc, mbc, mbc_pos, &state); + + switch (mblength) { + case (size_t)-2: /* Incomplete multibyte character. */ + use_mbc_buffer_flag = 1; + state = state_bak; + break; + + case (size_t)-1: /* Invalid as a multibyte character. */ + *p++ = mbc[0]; + state = state_bak; + column++; + file_pos_bak++; + + if (column >= Mcol) { + Fseek(f, file_pos_bak); + } else { + memmove(mbc, mbc + 1, --mbc_pos); + if (mbc_pos > 0) { + mbc[mbc_pos] = '\0'; + goto process_mbc; + } + } + break; + + default: + wc_width = wcwidth(wc); + + if (column + wc_width > Mcol) { + Fseek(f, file_pos_bak); + break_flag = 1; + } else { + for (i = 0; i < mbc_pos; i++) + *p++ = mbc[i]; + if (wc_width > 0) + column += wc_width; + } + } - default: - wc_width = wcwidth (wc); + if (break_flag || column >= Mcol) + break; - if (column + wc_width > Mcol) { - Fseek (f, file_pos_bak); - break_flag = 1; - } else { - for (i = 0; i < mbc_pos; i++) - *p++ = mbc[i]; - if (wc_width > 0) - column += wc_width; + c = Getc(f); + continue; + } +#endif /* HAVE_WIDECHAR */ + if (c == EOF) { + if (p > Line) { + *p = '\0'; + *length = p - Line; + return (column); + } + *length = p - Line; + return (EOF); + } + if (c == '\n') { + Currline++; + break; } - } - - if (break_flag || column >= Mcol) - break; - - c = Getc (f); - continue; - } -#endif /* HAVE_WIDECHAR */ - if (c == EOF) { - if (p > Line) { - *p = '\0'; - *length = p - Line; - return (column); - } - *length = p - Line; - return (EOF); - } - if (c == '\n') { - Currline++; - break; - } - *p++ = c; + *p++ = c; #if 0 - if (c == '\033') { /* ESC */ - c = Getc(f); - while (c > ' ' && c < '0' && p < &Line[LineLen - 1]) { - *p++ = c; + if (c == '\033') { /* ESC */ c = Getc(f); + while (c > ' ' && c < '0' && p < &Line[LineLen - 1]) { + *p++ = c; + c = Getc(f); + } + if (c >= '0' && c < '\177' && p < &Line[LineLen - 1]) { + *p++ = c; + c = Getc(f); + continue; + } } - if (c >= '0' && c < '\177' && p < &Line[LineLen - 1]) { - *p++ = c; - c = Getc(f); - continue; +#endif /* 0 */ + if (c == '\t') { + if (!hardtabs || (column < promptlen && !hard)) { + if (hardtabs && eraseln && !dumb) { + column = 1 + (column | 7); + my_putstring(eraseln); + promptlen = 0; + } else { + for (--p; p < &Line[LineLen - 1];) { + *p++ = ' '; + if ((++column & 7) == 0) + break; + } + if (column >= promptlen) + promptlen = 0; + } + } else + column = 1 + (column | 7); + } else if (c == '\b' && column > 0) { + column--; + } else if (c == '\r') { + int next = Getc(f); + if (next == '\n') { + p--; + Currline++; + break; + } + Ungetc(next, f); + column = 0; + } else if (c == '\f' && stop_opt) { + p[-1] = '^'; + *p++ = 'L'; + column += 2; + Pause++; + } else if (c == EOF) { + *length = p - Line; + return (column); + } else { +#ifdef HAVE_WIDECHAR + if (fold_opt && MB_CUR_MAX > 1) { + memset(mbc, '\0', MB_LEN_MAX); + mbc_pos = 0; + mbc[mbc_pos++] = c; + state_bak = state; + + mblength = mbrtowc(&wc, mbc, mbc_pos, &state); + /* The value of mblength is always less than 2 here. */ + switch (mblength) { + case (size_t)-2: + p--; + file_pos_bak = Ftell(f) - 1; + state = state_bak; + use_mbc_buffer_flag = 1; + break; + + case (size_t)-1: + state = state_bak; + column++; + break; + + default: + wc_width = wcwidth(wc); + if (wc_width > 0) + column += wc_width; + } + } else +#endif /* HAVE_WIDECHAR */ + { + if (isprint(c)) + column++; + } } + + if (column >= Mcol && fold_opt) + break; + c = Getc(f); } -#endif /* 0 */ - if (c == '\t') { - if (!hardtabs || (column < promptlen && !hard)) { - if (hardtabs && eraseln && !dumb) { - column = 1 + (column | 7); - my_putstring (eraseln); - promptlen = 0; + if (column >= Mcol && Mcol > 0) { + if (!Wrap) { + *p++ = '\n'; } - else { - for (--p; p < &Line[LineLen - 1];) { - *p++ = ' '; - if ((++column & 7) == 0) - break; - } - if (column >= promptlen) promptlen = 0; - } - } else - column = 1 + (column | 7); - } else if (c == '\b' && column > 0) { - column--; - } else if (c == '\r') { - int next = Getc(f); - if (next == '\n') { - p--; - Currline++; - break; - } - Ungetc(next,f); - column = 0; - } else if (c == '\f' && stop_opt) { - p[-1] = '^'; - *p++ = 'L'; - column += 2; - Pause++; - } else if (c == EOF) { - *length = p - Line; - return (column); - } else { -#ifdef HAVE_WIDECHAR - if (fold_opt && MB_CUR_MAX > 1) { - memset (mbc, '\0', MB_LEN_MAX); - mbc_pos = 0; - mbc[mbc_pos++] = c; - state_bak = state; - - mblength = mbrtowc (&wc, mbc, mbc_pos, &state); - - /* The value of mblength is always less than 2 here. */ - switch (mblength) { - case (size_t)-2: - p--; - file_pos_bak = Ftell (f) - 1; - state = state_bak; - use_mbc_buffer_flag = 1; - break; - - case (size_t)-1: - state = state_bak; - column++; - break; - - default: - wc_width = wcwidth (wc); - if (wc_width > 0) - column += wc_width; - } - } else -#endif /* HAVE_WIDECHAR */ - { - if (isprint(c)) - column++; - } } - - if (column >= Mcol && fold_opt) - break; - c = Getc (f); - } - if (column >= Mcol && Mcol > 0) { - if (!Wrap) { - *p++ = '\n'; + colflg = column == Mcol && fold_opt; + if (colflg && eatnl && Wrap) { + *p++ = '\n'; /* simulate normal wrap */ } - } - colflg = column == Mcol && fold_opt; - if (colflg && eatnl && Wrap) { - *p++ = '\n'; /* simulate normal wrap */ - } - *length = p - Line; - *p = 0; - return (column); + *length = p - Line; + *p = 0; + return (column); } -/* -** Erase the rest of the prompt, assuming we are starting at column col. -*/ - -void erasep (register int col) +/* Erase the rest of the prompt, assuming we are starting at column col. */ +void erasep(register int col) { - if (promptlen == 0) - return; - if (hard) { - putchar ('\n'); - } - else { - if (col == 0) - putchar ('\r'); - if (!dumb && eraseln) - my_putstring (eraseln); - else - for (col = promptlen - col; col > 0; col--) - putchar (' '); - } - promptlen = 0; + if (promptlen == 0) + return; + if (hard) { + putchar('\n'); + } else { + if (col == 0) + putchar('\r'); + if (!dumb && eraseln) + my_putstring(eraseln); + else + for (col = promptlen - col; col > 0; col--) + putchar(' '); + } + promptlen = 0; } -/* -** Erase the current line entirely -*/ - +/* Erase the current line entirely */ void kill_line() { - erasep(0); - if (!eraseln || dumb) - putchar('\r'); + erasep(0); + if (!eraseln || dumb) + putchar('\r'); } -/* - * force clear to end of line - */ +/* force clear to end of line */ void cleareol() { - my_putstring(eraseln); + my_putstring(eraseln); } void clreos() { - my_putstring(EodClr); + my_putstring(EodClr); } /* Print a buffer of n characters */ - -void prbuf (register char *s, register int n) +void prbuf(register char *s, register int n) { - register char c; /* next output character */ - register int state; /* next output char's UL state */ + register char c; /* next output character */ + register int state; /* next output char's UL state */ #define wouldul(s,n) ((n) >= 2 && (((s)[0] == '_' && (s)[1] == '\b') || ((s)[1] == '\b' && (s)[2] == '_'))) - while (--n >= 0) - if (!ul_opt) - putchar (*s++); - else { - if (*s == ' ' && pstate == 0 && ulglitch && wouldul(s+1, n-1)) { - s++; - continue; - } - if ((state = wouldul(s, n)) != 0) { - c = (*s == '_')? s[2] : *s ; - n -= 2; - s += 3; - } else - c = *s++; - if (state != pstate) { - if (c == ' ' && state == 0 && ulglitch && wouldul(s, n-1)) - state = 1; - else - my_putstring(state ? ULenter : ULexit); - } - if (c != ' ' || pstate == 0 || state != 0 || ulglitch == 0) + while (--n >= 0) + if (!ul_opt) + putchar(*s++); + else { + if (*s == ' ' && pstate == 0 && ulglitch + && wouldul(s + 1, n - 1)) { + s++; + continue; + } + if ((state = wouldul(s, n)) != 0) { + c = (*s == '_') ? s[2] : *s; + n -= 2; + s += 3; + } else + c = *s++; + if (state != pstate) { + if (c == ' ' && state == 0 && ulglitch + && wouldul(s, n - 1)) + state = 1; + else + my_putstring(state ? ULenter : ULexit); + } + if (c != ' ' || pstate == 0 || state != 0 + || ulglitch == 0) #ifdef HAVE_WIDECHAR - { - wchar_t wc; - size_t mblength; - mbstate_t mbstate; - memset (&mbstate, '\0', sizeof (mbstate_t)); - s--; n++; - mblength = mbrtowc (&wc, s, n, &mbstate); - if (mblength == (size_t) -2 || mblength == (size_t) -1) - mblength = 1; - while (mblength--) - putchar (*s++); - n += mblength; - } + { + wchar_t wc; + size_t mblength; + mbstate_t mbstate; + memset(&mbstate, '\0', sizeof(mbstate_t)); + s--; + n++; + mblength = mbrtowc(&wc, s, n, &mbstate); + if (mblength == (size_t)-2 + || mblength == (size_t)-1) + mblength = 1; + while (mblength--) + putchar(*s++); + n += mblength; + } #else - putchar(c); -#endif /* HAVE_WIDECHAR */ - if (state && *chUL) { - putsout(chBS); - my_putstring(chUL); - } - pstate = state; - } + putchar(c); +#endif /* HAVE_WIDECHAR */ + if (state && *chUL) { + putsout(chBS); + my_putstring(chUL); + } + pstate = state; + } } -/* -** Clear the screen -*/ -void -doclear() +/* Clear the screen */ +void doclear() { - if (Clear && !hard) { - my_putstring(Clear); - - /* Put out carriage return so that system doesn't - ** get confused by escape sequences when expanding tabs - */ - putchar ('\r'); - promptlen = 0; - } + if (Clear && !hard) { + my_putstring(Clear); + /* Put out carriage return so that system doesn't get + * confused by escape sequences when expanding tabs */ + putchar('\r'); + promptlen = 0; + } } -/* - * Go to home position - */ -void -home() +/* Go to home position */ +void home() { - my_putstring(Home); + my_putstring(Home); } static int lastcmd, lastarg, lastp; static int lastcolon; char shell_line[SHELL_LINE]; -/* -** Read a command and do it. A command consists of an optional integer -** argument followed by the command character. Return the number of lines -** to display in the next screenful. If there is nothing more to display -** in the current file, zero is returned. -*/ - -int command (char *filename, register FILE *f) +/* Read a command and do it. A command consists of an optional integer + * argument followed by the command character. Return the number of + * lines to display in the next screenful. If there is nothing more to + * display in the current file, zero is returned. */ +int command(char *filename, register FILE *f) { - register int nlines; - register int retval = 0; - register int c; - char colonch; - int done; - char comchar, cmdbuf[INIT_BUF]; + register int nlines; + register int retval = 0; + register int c; + char colonch; + int done; + char comchar, cmdbuf[INIT_BUF]; #define ret(val) retval=val;done++;break - done = 0; - if (!errors) - prompt (filename); - else - errors = 0; - for (;;) { - nlines = number (&comchar); - lastp = colonch = 0; - if (comchar == '.') { /* Repeat last command */ - lastp++; - comchar = lastcmd; - nlines = lastarg; - if (lastcmd == ':') - colonch = lastcolon; - } - lastcmd = comchar; - lastarg = nlines; - if ((cc_t) comchar == otty.c_cc[VERASE]) { - kill_line (); - prompt (filename); - continue; - } - switch (comchar) { - case ':': - retval = colon (filename, colonch, nlines); - if (retval >= 0) - done++; - break; - case 'b': - case ctrl('B'): - { - register int initline; - - if (no_intty) { - ringbell(); - return (-1); + done = 0; + if (!errors) + prompt(filename); + else + errors = 0; + for (;;) { + nlines = number(&comchar); + lastp = colonch = 0; + if (comchar == '.') { /* Repeat last command */ + lastp++; + comchar = lastcmd; + nlines = lastarg; + if (lastcmd == ':') + colonch = lastcolon; } + lastcmd = comchar; + lastarg = nlines; + if ((cc_t) comchar == otty.c_cc[VERASE]) { + kill_line(); + prompt(filename); + continue; + } + switch (comchar) { + case ':': + retval = colon(filename, colonch, nlines); + if (retval >= 0) + done++; + break; + case 'b': + case ctrl('B'): + { + register int initline; + + if (no_intty) { + ringbell(); + return (-1); + } + + if (nlines == 0) + nlines++; + + putchar('\r'); + erasep(0); + putchar('\n'); + if (clreol) + cleareol(); + if (nlines != 1) + printf(_("...back %d pages"), nlines); + else + putsout(_("...back 1 page")); + if (clreol) + cleareol(); + putchar('\n'); + + initline = Currline - dlines * (nlines + 1); + if (!noscroll) + --initline; + if (initline < 0) + initline = 0; + Fseek(f, 0L); + Currline = 0; /* skiplns() will make Currline correct */ + skiplns(initline, f); + if (!noscroll) { + ret(dlines + 1); + } else { + ret(dlines); + } + } + case ' ': + case 'z': + if (nlines == 0) + nlines = dlines; + else if (comchar == 'z') + dlines = nlines; + ret(nlines); + case 'd': + case ctrl('D'): + if (nlines != 0) + nscroll = nlines; + ret(nscroll); + case 'q': + case 'Q': + end_it(0); + case 's': + case 'f': + case ctrl('F'): + if (nlines == 0) + nlines++; + if (comchar == 'f') + nlines *= dlines; + putchar('\r'); + erasep(0); + putchar('\n'); + if (clreol) + cleareol(); + if (nlines == 1) + putsout(_("...skipping one line")); + else + printf(_("...skipping %d lines"), nlines); - if (nlines == 0) nlines++; - - putchar ('\r'); - erasep (0); - putchar('\n'); - if (clreol) - cleareol (); - if (nlines != 1) - printf(_("...back %d pages"), nlines); - else - putsout(_("...back 1 page")); - if (clreol) - cleareol (); - putchar('\n'); + if (clreol) + cleareol(); + putchar('\n'); - initline = Currline - dlines * (nlines + 1); - if (! noscroll) - --initline; - if (initline < 0) initline = 0; - Fseek(f, 0L); - Currline = 0; /* skiplns() will make Currline correct */ - skiplns(initline, f); - if (! noscroll) { - ret(dlines + 1); - } - else { - ret(dlines); - } - } - case ' ': - case 'z': - if (nlines == 0) nlines = dlines; - else if (comchar == 'z') dlines = nlines; - ret (nlines); - case 'd': - case ctrl('D'): - if (nlines != 0) nscroll = nlines; - ret (nscroll); - case 'q': - case 'Q': - end_it (0); - case 's': - case 'f': - case ctrl('F'): - if (nlines == 0) nlines++; - if (comchar == 'f') - nlines *= dlines; - putchar ('\r'); - erasep (0); - putchar('\n'); - if (clreol) - cleareol (); - if (nlines == 1) - putsout(_("...skipping one line")); - else - printf(_("...skipping %d lines"), nlines); - - if (clreol) - cleareol (); - putchar('\n'); - - while (nlines > 0) { - while ((c = Getc (f)) != '\n') - if (c == EOF) { - retval = 0; - done++; - goto endsw; - } - Currline++; - nlines--; - } - ret (dlines); - case '\n': - if (nlines != 0) - dlines = nlines; - else - nlines = 1; - ret (nlines); - case '\f': - if (!no_intty) { - doclear (); - Fseek (f, screen_start.chrctr); - Currline = screen_start.line; - ret (dlines); - } - else { - ringbell(); - break; - } - case '\'': - if (!no_intty) { - kill_line (); - putsout(_("\n***Back***\n\n")); - Fseek (f, context.chrctr); - Currline = context.line; - ret (dlines); - } - else { - ringbell(); - break; - } - case '=': - kill_line (); - promptlen = printf("%d", Currline); - fflush (stdout); - break; - case 'n': - if (!previousre) { - more_error (_("No previous regular expression")); - break; - } - lastp++; - /* fallthrough */ - case '/': - if (nlines == 0) nlines++; - kill_line (); - putchar('/'); - promptlen = 1; - fflush (stdout); - if (lastp) { - putcerr('\r'); - search (previousre, f, nlines); - } - else { - ttyin (cmdbuf, sizeof(cmdbuf)-2, '/'); - putcerr('\r'); - free (previousre); - previousre = xstrdup(cmdbuf); - search (cmdbuf, f, nlines); - } - ret (dlines-1); - case '!': - do_shell (filename); - break; - case '?': - case 'h': - if (noscroll) doclear(); - putsout(_("\n" -"Most commands optionally preceded by integer argument k. " -"Defaults in brackets.\n" -"Star (*) indicates argument becomes new default.\n")); - puts("---------------------------------------" - "----------------------------------------"); - putsout(_( -" Display next k lines of text [current screen size]\n" -"z Display next k lines of text [current screen size]*\n" -" Display next k lines of text [1]*\n" -"d or ctrl-D Scroll k lines [current scroll size, initially 11]*\n" -"q or Q or Exit from more\n" -"s Skip forward k lines of text [1]\n" -"f Skip forward k screenfuls of text [1]\n" -"b or ctrl-B Skip backwards k screenfuls of text [1]\n" -"' Go to place where previous search started\n" -"= Display current line number\n" -"/ Search for kth occurrence of regular expression [1]\n" -"n Search for kth occurrence of last r.e [1]\n" -"! or :! Execute in a subshell\n" -"v Start up /usr/bin/vi at current line\n" -"ctrl-L Redraw screen\n" -":n Go to kth next file [1]\n" -":p Go to kth previous file [1]\n" -":f Display current file name and line number\n" -". Repeat previous command\n")); - puts("---------------------------------------" - "----------------------------------------"); - prompt(filename); - break; - case 'v': /* This case should go right before default */ - if (!no_intty) { - /* - * Earlier: call vi +n file. This also works for emacs. - * POSIX: call vi -c n file (when editor is vi or ex). - */ - char *editor, *p; - int n = (Currline - dlines <= 0 ? 1 : - Currline - (dlines + 1) / 2); - int split = 0; - - editor = getenv("VISUAL"); - if (editor == NULL || *editor == '\0') - editor = getenv("EDITOR"); - if (editor == NULL || *editor == '\0') - editor = VI; - - p = strrchr(editor, '/'); - if (p) - p++; - else - p = editor; - if (!strcmp(p, "vi") || !strcmp(p, "ex")) { - sprintf(cmdbuf, "-c %d", n); - split = 1; - } else { - sprintf(cmdbuf, "+%d", n); - } - - kill_line(); - printf("%s %s %s", editor, cmdbuf, fnames[fnum]); - if (split) { - cmdbuf[2] = 0; - execute(filename, editor, editor, cmdbuf, - cmdbuf+3, fnames[fnum], (char *)0); - } else - execute(filename, editor, editor, - cmdbuf, fnames[fnum], (char *)0); - break; - } - /* fall through */ - default: - if (dum_opt) { - kill_line (); - if (Senter && Sexit) { - my_putstring (Senter); - promptlen = printf(_("[Press 'h' for instructions.]")) - + 2 * soglitch; - my_putstring (Sexit); + while (nlines > 0) { + while ((c = Getc(f)) != '\n') + if (c == EOF) { + retval = 0; + done++; + goto endsw; + } + Currline++; + nlines--; + } + ret(dlines); + case '\n': + if (nlines != 0) + dlines = nlines; + else + nlines = 1; + ret(nlines); + case '\f': + if (!no_intty) { + doclear(); + Fseek(f, screen_start.chrctr); + Currline = screen_start.line; + ret(dlines); + } else { + ringbell(); + break; + } + case '\'': + if (!no_intty) { + kill_line(); + putsout(_("\n***Back***\n\n")); + Fseek(f, context.chrctr); + Currline = context.line; + ret(dlines); + } else { + ringbell(); + break; + } + case '=': + kill_line(); + promptlen = printf("%d", Currline); + fflush(stdout); + break; + case 'n': + if (!previousre) { + more_error(_("No previous regular expression")); + break; + } + lastp++; + /* fall through */ + case '/': + if (nlines == 0) + nlines++; + kill_line(); + putchar('/'); + promptlen = 1; + fflush(stdout); + if (lastp) { + putcerr('\r'); + search(previousre, f, nlines); + } else { + ttyin(cmdbuf, sizeof(cmdbuf) - 2, '/'); + putcerr('\r'); + free(previousre); + previousre = xstrdup(cmdbuf); + search(cmdbuf, f, nlines); + } + ret(dlines - 1); + case '!': + do_shell(filename); + break; + case '?': + case 'h': + if (noscroll) + doclear(); + putsout(_("\n" + "Most commands optionally preceded by integer argument k. " + "Defaults in brackets.\n" + "Star (*) indicates argument becomes new default.\n")); + puts("---------------------------------------" + "----------------------------------------"); + putsout(_ + (" Display next k lines of text [current screen size]\n" + "z Display next k lines of text [current screen size]*\n" + " Display next k lines of text [1]*\n" + "d or ctrl-D Scroll k lines [current scroll size, initially 11]*\n" + "q or Q or Exit from more\n" + "s Skip forward k lines of text [1]\n" + "f Skip forward k screenfuls of text [1]\n" + "b or ctrl-B Skip backwards k screenfuls of text [1]\n" + "' Go to place where previous search started\n" + "= Display current line number\n" + "/ Search for kth occurrence of regular expression [1]\n" + "n Search for kth occurrence of last r.e [1]\n" + "! or :! Execute in a subshell\n" + "v Start up /usr/bin/vi at current line\n" + "ctrl-L Redraw screen\n" + ":n Go to kth next file [1]\n" + ":p Go to kth previous file [1]\n" + ":f Display current file name and line number\n" + ". Repeat previous command\n")); + puts("---------------------------------------" + "----------------------------------------"); + prompt(filename); + break; + case 'v': /* This case should go right before default */ + if (!no_intty) { + /* Earlier: call vi +n file. This also + * works for emacs. POSIX: call vi -c n + * file (when editor is vi or ex). */ + char *editor, *p; + int n = (Currline - dlines <= 0 ? 1 : + Currline - (dlines + 1) / 2); + int split = 0; + + editor = getenv("VISUAL"); + if (editor == NULL || *editor == '\0') + editor = getenv("EDITOR"); + if (editor == NULL || *editor == '\0') + editor = VI; + + p = strrchr(editor, '/'); + if (p) + p++; + else + p = editor; + if (!strcmp(p, "vi") || !strcmp(p, "ex")) { + sprintf(cmdbuf, "-c %d", n); + split = 1; + } else { + sprintf(cmdbuf, "+%d", n); + } + + kill_line(); + printf("%s %s %s", editor, cmdbuf, + fnames[fnum]); + if (split) { + cmdbuf[2] = 0; + execute(filename, editor, editor, + cmdbuf, cmdbuf + 3, + fnames[fnum], (char *)0); + } else + execute(filename, editor, editor, + cmdbuf, fnames[fnum], + (char *)0); + break; + } + /* fall through */ + default: + if (dum_opt) { + kill_line(); + if (Senter && Sexit) { + my_putstring(Senter); + promptlen = + printf(_ + ("[Press 'h' for instructions.]")) + + 2 * soglitch; + my_putstring(Sexit); + } else + promptlen = + printf(_ + ("[Press 'h' for instructions.]")); + fflush(stdout); + } else + ringbell(); + break; } - else - promptlen = printf(_("[Press 'h' for instructions.]")); - fflush (stdout); - } - else - ringbell(); - break; + if (done) + break; } - if (done) break; - } - putchar ('\r'); -endsw: - inwait = 0; - notell++; - return (retval); + putchar('\r'); + endsw: + inwait = 0; + notell++; + return (retval); } static char ch; - -/* - * Execute a colon-prefixed command. - * Returns <0 if not a command that should cause - * more of the file to be printed. - */ - -int colon (char *filename, int cmd, int nlines) { +/* Execute a colon-prefixed command. Returns <0 if not a command that + * should cause more of the file to be printed. */ +int colon(char *filename, int cmd, int nlines) +{ if (cmd == 0) - ch = readch (); + ch = readch(); else ch = cmd; lastcolon = ch; switch (ch) { case 'f': - kill_line (); + kill_line(); if (!no_intty) - promptlen = printf(_("\"%s\" line %d"), fnames[fnum], Currline); + promptlen = + printf(_("\"%s\" line %d"), fnames[fnum], Currline); else promptlen = printf(_("[Not a file] line %d"), Currline); - fflush (stdout); + fflush(stdout); return (-1); case 'n': if (nlines == 0) { if (fnum >= nfiles - 1) - end_it (0); + end_it(0); nlines++; } - putchar ('\r'); - erasep (0); - skipf (nlines); + putchar('\r'); + erasep(0); + skipf(nlines); return (0); case 'p': if (no_intty) { ringbell(); return (-1); } - putchar ('\r'); - erasep (0); + putchar('\r'); + erasep(0); if (nlines == 0) nlines++; - skipf (-nlines); + skipf(-nlines); return (0); case '!': - do_shell (filename); + do_shell(filename); return (-1); case 'q': case 'Q': - end_it (0); + end_it(0); default: ringbell(); return (-1); } } -/* -** Read a decimal number from the terminal. Set cmd to the non-digit which -** terminates the number. -*/ - +/* Read a decimal number from the terminal. Set cmd to the non-digit + * which terminates the number. */ int number(char *cmd) { register int i; - i = 0; ch = otty.c_cc[VKILL]; + i = 0; + ch = otty.c_cc[VKILL]; for (;;) { - ch = readch (); + ch = readch(); if (isdigit(ch)) - i = i*10 + ch - '0'; + i = i * 10 + ch - '0'; else if ((cc_t) ch == otty.c_cc[VKILL]) i = 0; else { @@ -1542,22 +1525,22 @@ int number(char *cmd) return (i); } -void do_shell (char *filename) +void do_shell(char *filename) { char cmdbuf[COMMAND_BUF]; int rc; char *expanded; - kill_line (); + kill_line(); putchar('!'); - fflush (stdout); + fflush(stdout); promptlen = 1; if (lastp) putsout(shell_line); else { - ttyin (cmdbuf, sizeof(cmdbuf)-2, '!'); + ttyin(cmdbuf, sizeof(cmdbuf) - 2, '!'); expanded = 0; - rc = expand (&expanded, cmdbuf); + rc = expand(&expanded, cmdbuf); if (expanded) { if (strlen(expanded) < sizeof(shell_line)) strcpy(shell_line, expanded); @@ -1567,341 +1550,336 @@ void do_shell (char *filename) } if (rc < 0) { putserr(_(" Overflow\n")); - prompt (filename); + prompt(filename); return; } else if (rc > 0) { - kill_line (); + kill_line(); promptlen = printf("!%s", shell_line); } } - fflush (stdout); + fflush(stdout); putcerr('\n'); promptlen = 0; shellp = 1; - execute (filename, shell, shell, "-c", shell_line, 0); + execute(filename, shell, shell, "-c", shell_line, 0); } -/* -** Search for nth occurrence of regular expression contained in buf in the file -*/ - +/* Search for nth occurrence of regular expression contained in buf in + * the file */ void search(char buf[], FILE *file, register int n) { - long startline = Ftell (file); - register long line1 = startline; - register long line2 = startline; - register long line3 = startline; - register int lncount; - int saveln, rv, rc; - regex_t re; - - context.line = saveln = Currline; - context.chrctr = startline; - lncount = 0; - if ((rc = regcomp (&re, buf, REG_NOSUB)) != 0) { - char s[REGERR_BUF]; - regerror (rc, &re, s, sizeof s); - more_error (s); - } - while (!feof (file)) { - line3 = line2; - line2 = line1; - line1 = Ftell (file); - rdline (file); - lncount++; - if ((rv = regexec (&re, Line, 0, NULL, 0)) == 0) { - if (--n == 0) { - if (lncount > 3 || (lncount > 1 && no_intty)) - { - putchar('\n'); - if (clreol) - cleareol (); - putsout(_("...skipping\n")); - } - if (!no_intty) { - Currline -= (lncount >= 3 ? 3 : lncount); - Fseek (file, line3); - if (noscroll) { - if (clreol) { - home (); - cleareol (); - } - else - doclear (); - } - } - else { - kill_line (); - if (noscroll) { - if (clreol) { - home (); - cleareol (); - } - else - doclear (); + long startline = Ftell(file); + register long line1 = startline; + register long line2 = startline; + register long line3 = startline; + register int lncount; + int saveln, rv, rc; + regex_t re; + + context.line = saveln = Currline; + context.chrctr = startline; + lncount = 0; + if ((rc = regcomp(&re, buf, REG_NOSUB)) != 0) { + char s[REGERR_BUF]; + regerror(rc, &re, s, sizeof s); + more_error(s); + } + while (!feof(file)) { + line3 = line2; + line2 = line1; + line1 = Ftell(file); + rdline(file); + lncount++; + if ((rv = regexec(&re, Line, 0, NULL, 0)) == 0) { + if (--n == 0) { + if (lncount > 3 || (lncount > 1 && no_intty)) { + putchar('\n'); + if (clreol) + cleareol(); + putsout(_("...skipping\n")); + } + if (!no_intty) { + Currline -= + (lncount >= 3 ? 3 : lncount); + Fseek(file, line3); + if (noscroll) { + if (clreol) { + home(); + cleareol(); + } else + doclear(); + } + } else { + kill_line(); + if (noscroll) { + if (clreol) { + home(); + cleareol(); + } else + doclear(); + } + puts(Line); + } + break; } - puts(Line); - } - break; } } - } - if (feof (file)) { - if (!no_intty) { - Currline = saveln; - Fseek (file, startline); - } - else { - putsout(_("\nPattern not found\n")); - end_it (0); + if (feof(file)) { + if (!no_intty) { + Currline = saveln; + Fseek(file, startline); + } else { + putsout(_("\nPattern not found\n")); + end_it(0); + } + more_error(_("Pattern not found")); + free(previousre); + previousre = NULL; } - more_error (_("Pattern not found")); - free (previousre); - previousre = NULL; - } } -/*VARARGS2*/ -void execute (char *filename, char *cmd, ...) +void execute(char *filename, char *cmd, ...) { int id; int n; va_list argp; - char * arg; - char ** args; + char *arg; + char **args; int argcount; - fflush (stdout); - reset_tty (); - for (n = 10; (id = fork ()) < 0 && n > 0; n--) - sleep (5); + fflush(stdout); + reset_tty(); + for (n = 10; (id = fork()) < 0 && n > 0; n--) + sleep(5); if (id == 0) { - if (!isatty(0)) { - close(0); - open("/dev/tty", 0); - } - - va_start(argp, cmd); - arg = va_arg(argp, char *); - argcount = 0; - while (arg) { - argcount++; - arg = va_arg(argp, char *); - } - va_end(argp); - - args = alloca(sizeof(char *) * (argcount + 1)); - args[argcount] = NULL; - - va_start(argp, cmd); - arg = va_arg(argp, char *); - argcount = 0; - while (arg) { - args[argcount] = arg; - argcount++; - arg = va_arg(argp, char *); - } - va_end(argp); - - execvp (cmd, args); - putserr(_("exec failed\n")); - exit (EXIT_FAILURE); + if (!isatty(0)) { + close(0); + open("/dev/tty", 0); + } + + va_start(argp, cmd); + arg = va_arg(argp, char *); + argcount = 0; + while (arg) { + argcount++; + arg = va_arg(argp, char *); + } + va_end(argp); + + args = alloca(sizeof(char *) * (argcount + 1)); + args[argcount] = NULL; + + va_start(argp, cmd); + arg = va_arg(argp, char *); + argcount = 0; + while (arg) { + args[argcount] = arg; + argcount++; + arg = va_arg(argp, char *); + } + va_end(argp); + + execvp(cmd, args); + putserr(_("exec failed\n")); + exit(EXIT_FAILURE); } if (id > 0) { - signal (SIGINT, SIG_IGN); - signal (SIGQUIT, SIG_IGN); - if (catch_susp) - signal(SIGTSTP, SIG_DFL); - while (wait(0) > 0); - signal (SIGINT, end_it); - signal (SIGQUIT, onquit); - if (catch_susp) - signal(SIGTSTP, onsusp); + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + if (catch_susp) + signal(SIGTSTP, SIG_DFL); + while (wait(0) > 0) ; + signal(SIGINT, end_it); + signal(SIGQUIT, onquit); + if (catch_susp) + signal(SIGTSTP, onsusp); } else - putserr(_("can't fork\n")); - set_tty (); + putserr(_("can't fork\n")); + set_tty(); puts("------------------------"); - prompt (filename); + prompt(filename); } -/* -** Skip n lines in the file f -*/ -void skiplns (register int n, register FILE *f) +/* Skip n lines in the file f */ +void skiplns(register int n, register FILE *f) { - register int c; + register int c; - while (n > 0) { - while ((c = Getc (f)) != '\n') - if (c == EOF) - return; - n--; - Currline++; - } + while (n > 0) { + while ((c = Getc(f)) != '\n') + if (c == EOF) + return; + n--; + Currline++; + } } -/* -** Skip nskip files in the file list (from the command line). Nskip may be -** negative. -*/ - -void skipf (register int nskip) +/* Skip nskip files in the file list (from the command line). Nskip may + * be negative. */ +void skipf(register int nskip) { - if (nskip == 0) return; - if (nskip > 0) { - if (fnum + nskip > nfiles - 1) - nskip = nfiles - fnum - 1; - } - else if (within) - ++fnum; - fnum += nskip; - if (fnum < 0) - fnum = 0; - puts(_("\n...Skipping ")); - if (clreol) - cleareol (); - if (nskip > 0) - putsout(_("...Skipping to file ")); - else - putsout(_("...Skipping back to file ")); - puts(fnames[fnum]); - if (clreol) - cleareol (); - putchar('\n'); - --fnum; + if (nskip == 0) + return; + if (nskip > 0) { + if (fnum + nskip > nfiles - 1) + nskip = nfiles - fnum - 1; + } else if (within) + ++fnum; + fnum += nskip; + if (fnum < 0) + fnum = 0; + puts(_("\n...Skipping ")); + if (clreol) + cleareol(); + if (nskip > 0) + putsout(_("...Skipping to file ")); + else + putsout(_("...Skipping back to file ")); + puts(fnames[fnum]); + if (clreol) + cleareol(); + putchar('\n'); + --fnum; } /*----------------------------- Terminal I/O -------------------------------*/ - void initterm() { - int ret; - char *padstr; - char *term; - struct winsize win; + int ret; + char *padstr; + char *term; + struct winsize win; #ifdef do_SIGTTOU -retry: -#endif /* do_SIGTTOU */ - no_tty = tcgetattr(fileno(stdout), &otty); - if (!no_tty) { - docrterase = (otty.c_cc[VERASE] != 255); - docrtkill = (otty.c_cc[VKILL] != 255); + retry: +#endif + no_tty = tcgetattr(fileno(stdout), &otty); + if (!no_tty) { + docrterase = (otty.c_cc[VERASE] != 255); + docrtkill = (otty.c_cc[VKILL] != 255); #ifdef do_SIGTTOU - { - int tgrp; - /* - * Wait until we're in the foreground before we save the - * the terminal modes. - */ - if ((tgrp = tcgetpgrp(fileno(stdout))) < 0) { - perror("tcgetpgrp"); - exit(EXIT_FAILURE); - } - if (tgrp != getpgrp(0)) { - kill(0, SIGTTOU); - goto retry; - } - } -#endif /* do_SIGTTOU */ - if ((term = getenv("TERM")) == 0) { - dumb++; ul_opt = 0; - } - my_setupterm(term, 1, &ret); - if (ret <= 0) { - dumb++; ul_opt = 0; - } - else { + { + int tgrp; + /* Wait until we're in the foreground before we + * save the the terminal modes. */ + if ((tgrp = tcgetpgrp(fileno(stdout))) < 0) { + perror("tcgetpgrp"); + exit(EXIT_FAILURE); + } + if (tgrp != getpgrp(0)) { + kill(0, SIGTTOU); + goto retry; + } + } +#endif /* do_SIGTTOU */ + if ((term = getenv("TERM")) == 0) { + dumb++; + ul_opt = 0; + } + my_setupterm(term, 1, &ret); + if (ret <= 0) { + dumb++; + ul_opt = 0; + } else { #ifdef TIOCGWINSZ - if (ioctl(fileno(stdout), TIOCGWINSZ, &win) < 0) { -#endif /* TIOCGWINSZ */ - Lpp = my_tgetnum(TERM_LINES); - Mcol = my_tgetnum(TERM_COLS); + if (ioctl(fileno(stdout), TIOCGWINSZ, &win) < 0) { +#endif + Lpp = my_tgetnum(TERM_LINES); + Mcol = my_tgetnum(TERM_COLS); #ifdef TIOCGWINSZ - } else { - if ((Lpp = win.ws_row) == 0) - Lpp = my_tgetnum(TERM_LINES); - if ((Mcol = win.ws_col) == 0) - Mcol = my_tgetnum(TERM_COLS); - } -#endif /* TIOCGWINSZ */ - if ((Lpp <= 0) || my_tgetflag(TERM_HARD_COPY)) { - hard++; /* Hard copy terminal */ - Lpp = LINES_PER_PAGE; - } - - if (my_tgetflag(TERM_EAT_NEW_LINE)) - eatnl++; /* Eat newline at last column + 1; dec, concept */ - if (Mcol <= 0) - Mcol = NUM_COLUMNS; - - Wrap = my_tgetflag(TERM_AUTO_RIGHT_MARGIN); - bad_so = my_tgetflag (TERM_CEOL); - eraseln = my_tgetstr(TERM_CLEAR_TO_LINE_END); - Clear = my_tgetstr(TERM_CLEAR); - Senter = my_tgetstr(TERM_STANDARD_MODE); - Sexit = my_tgetstr(TERM_EXIT_STANDARD_MODE); - if ((soglitch = my_tgetnum(TERM_STD_MODE_GLITCH)) < 0) - soglitch = 0; - - /* - * Set up for underlining: some terminals don't need it; - * others have start/stop sequences, still others have an - * underline char sequence which is assumed to move the - * cursor forward one character. If underline sequence - * isn't available, settle for standout sequence. - */ - - if (my_tgetflag(TERM_UNDERLINE) || my_tgetflag(TERM_OVER_STRIKE)) - ul_opt = 0; - if ((chUL = my_tgetstr(TERM_UNDERLINE_CHAR)) == NULL ) - chUL = ""; - if (((ULenter = my_tgetstr(TERM_ENTER_UNDERLINE)) == NULL || - (ULexit = my_tgetstr(TERM_EXIT_UNDERLINE)) == NULL) && !*chUL) { - if ((ULenter = Senter) == NULL || (ULexit = Sexit) == NULL) { - ULenter = ""; - ULexit = ""; - } else - ulglitch = soglitch; - } else { - ulglitch = 0; - } - - if ((padstr = my_tgetstr(TERM_PAD_CHAR)) != NULL) - PC = *padstr; - Home = my_tgetstr(TERM_HOME); - if (Home == 0 || *Home == '\0') { - if ((cursorm = my_tgetstr(TERM_CURSOR_ADDRESS)) != NULL) { - const char *t = (const char *)my_tgoto(cursorm, 0, 0); - xstrncpy(cursorhome, t, sizeof(cursorhome)); - Home = cursorhome; - } - } - EodClr = my_tgetstr(TERM_CLEAR_TO_SCREEN_END); - if ((chBS = my_tgetstr(TERM_LINE_DOWN)) == NULL) - chBS = "\b"; + } else { + if ((Lpp = win.ws_row) == 0) + Lpp = my_tgetnum(TERM_LINES); + if ((Mcol = win.ws_col) == 0) + Mcol = my_tgetnum(TERM_COLS); + } +#endif + if ((Lpp <= 0) || my_tgetflag(TERM_HARD_COPY)) { + hard++; /* Hard copy terminal */ + Lpp = LINES_PER_PAGE; + } + + if (my_tgetflag(TERM_EAT_NEW_LINE)) + /* Eat newline at last column + 1; dec, concept */ + eatnl++; + if (Mcol <= 0) + Mcol = NUM_COLUMNS; + + Wrap = my_tgetflag(TERM_AUTO_RIGHT_MARGIN); + bad_so = my_tgetflag(TERM_CEOL); + eraseln = my_tgetstr(TERM_CLEAR_TO_LINE_END); + Clear = my_tgetstr(TERM_CLEAR); + Senter = my_tgetstr(TERM_STANDARD_MODE); + Sexit = my_tgetstr(TERM_EXIT_STANDARD_MODE); + if ((soglitch = my_tgetnum(TERM_STD_MODE_GLITCH)) < 0) + soglitch = 0; + + /* Set up for underlining: some terminals don't + * need it; others have start/stop sequences, + * still others have an underline char sequence + * which is assumed to move the cursor forward + * one character. If underline sequence isn't + * available, settle for standout sequence. */ + if (my_tgetflag(TERM_UNDERLINE) + || my_tgetflag(TERM_OVER_STRIKE)) + ul_opt = 0; + if ((chUL = my_tgetstr(TERM_UNDERLINE_CHAR)) == NULL) + chUL = ""; + if (((ULenter = + my_tgetstr(TERM_ENTER_UNDERLINE)) == NULL + || (ULexit = + my_tgetstr(TERM_EXIT_UNDERLINE)) == NULL) + && !*chUL) { + if ((ULenter = Senter) == NULL + || (ULexit = Sexit) == NULL) { + ULenter = ""; + ULexit = ""; + } else + ulglitch = soglitch; + } else { + ulglitch = 0; + } + if ((padstr = my_tgetstr(TERM_PAD_CHAR)) != NULL) + PC = *padstr; + Home = my_tgetstr(TERM_HOME); + if (Home == 0 || *Home == '\0') { + if ((cursorm = + my_tgetstr(TERM_CURSOR_ADDRESS)) != NULL) { + const char *t = + (const char *)my_tgoto(cursorm, 0, + 0); + xstrncpy(cursorhome, t, + sizeof(cursorhome)); + Home = cursorhome; + } + } + EodClr = my_tgetstr(TERM_CLEAR_TO_SCREEN_END); + if ((chBS = my_tgetstr(TERM_LINE_DOWN)) == NULL) + chBS = "\b"; + + } + if ((shell = getenv("SHELL")) == NULL) + shell = "/bin/sh"; + } + no_intty = tcgetattr(fileno(stdin), &otty); + tcgetattr(fileno(stderr), &otty); + savetty0 = otty; + slow_tty = cfgetispeed(&otty) < B1200; + hardtabs = (otty.c_oflag & TABDLY) != XTABS; + if (!no_tty) { + otty.c_lflag &= ~(ICANON | ECHO); + otty.c_cc[VMIN] = 1; + otty.c_cc[VTIME] = 0; } - if ((shell = getenv("SHELL")) == NULL) - shell = "/bin/sh"; - } - no_intty = tcgetattr(fileno(stdin), &otty); - tcgetattr(fileno(stderr), &otty); - savetty0 = otty; - slow_tty = cfgetispeed(&otty) < B1200; - hardtabs = (otty.c_oflag & TABDLY) != XTABS; - if (!no_tty) { - otty.c_lflag &= ~(ICANON|ECHO); - otty.c_cc[VMIN] = 1; - otty.c_cc[VTIME] = 0; - } } -int readch () { +int readch() +{ unsigned char c; errno = 0; - if (read (fileno(stderr), &c, 1) <= 0) { + if (read(fileno(stderr), &c, 1) <= 0) { if (errno != EINTR) end_it(0); else @@ -1919,279 +1897,281 @@ static char *CARAT = "^"; else \ putserr(BS); -void ttyin (char buf[], register int nmax, char pchar) { - char *sp; - int c; - int slash = 0; - int maxlen; - - sp = buf; - maxlen = 0; - while (sp - buf < nmax) { - if (promptlen > maxlen) maxlen = promptlen; - c = readch (); - if (c == '\\') { - slash++; - } - else if (((cc_t) c == otty.c_cc[VERASE]) && !slash) { - if (sp > buf) { +void ttyin(char buf[], register int nmax, char pchar) +{ + char *sp; + int c; + int slash = 0; + int maxlen; + + sp = buf; + maxlen = 0; + while (sp - buf < nmax) { + if (promptlen > maxlen) + maxlen = promptlen; + c = readch(); + if (c == '\\') { + slash++; + } else if (((cc_t) c == otty.c_cc[VERASE]) && !slash) { + if (sp > buf) { #ifdef HAVE_WIDECHAR - if (MB_CUR_MAX > 1) - { - wchar_t wc; - size_t pos = 0, mblength; - mbstate_t state, state_bak; - - memset (&state, '\0', sizeof (mbstate_t)); - - while (1) { - state_bak = state; - mblength = mbrtowc (&wc, buf + pos, sp - buf, &state); - - state = (mblength == (size_t)-2 - || mblength == (size_t)-1) ? state_bak : state; - mblength = (mblength == (size_t)-2 - || mblength == (size_t)-1 - || mblength == 0) ? 1 : mblength; - - if (buf + pos + mblength >= sp) - break; - - pos += mblength; - } - - if (mblength == 1) { - ERASEONECOLUMN - } - else { - int wc_width; - wc_width = wcwidth (wc); - wc_width = (wc_width < 1) ? 1 : wc_width; - while (wc_width--) { - ERASEONECOLUMN + if (MB_CUR_MAX > 1) { + wchar_t wc; + size_t pos = 0, mblength; + mbstate_t state, state_bak; + + memset(&state, '\0', sizeof(mbstate_t)); + + while (1) { + state_bak = state; + mblength = + mbrtowc(&wc, buf + pos, + sp - buf, &state); + + state = (mblength == (size_t)-2 + || mblength == + (size_t)-1) ? state_bak + : state; + mblength = + (mblength == (size_t)-2 + || mblength == (size_t)-1 + || mblength == + 0) ? 1 : mblength; + + if (buf + pos + mblength >= sp) + break; + + pos += mblength; + } + + if (mblength == 1) { + ERASEONECOLUMN} else { + int wc_width; + wc_width = wcwidth(wc); + wc_width = + (wc_width < + 1) ? 1 : wc_width; + while (wc_width--) { + ERASEONECOLUMN} + } + + while (mblength--) { + --promptlen; + --sp; + } + } else +#endif /* HAVE_WIDECHAR */ + { + --promptlen; + ERASEONECOLUMN-- sp; + } + + if ((*sp < ' ' && *sp != '\n') || *sp == RUBOUT) { + --promptlen; + ERASEONECOLUMN} + continue; + } else { + if (!eraseln) + promptlen = maxlen; + siglongjmp(restore, 1); } - } - - while (mblength--) { - --promptlen; - --sp; - } - } - else -#endif /* HAVE_WIDECHAR */ - { - --promptlen; - ERASEONECOLUMN - --sp; - } - - if ((*sp < ' ' && *sp != '\n') || *sp == RUBOUT) { - --promptlen; - ERASEONECOLUMN + } else if (((cc_t) c == otty.c_cc[VKILL]) && !slash) { + if (hard) { + show(c); + putchar('\n'); + putchar(pchar); + } else { + putchar('\r'); + putchar(pchar); + if (eraseln) + erasep(1); + else if (docrtkill) + while (promptlen-- > 1) + putserr(BSB); + promptlen = 1; + } + sp = buf; + fflush(stdout); + continue; } - continue; - } - else { - if (!eraseln) promptlen = maxlen; - siglongjmp (restore, 1); - } - } - else if (((cc_t) c == otty.c_cc[VKILL]) && !slash) { - if (hard) { - show (c); - putchar ('\n'); - putchar (pchar); - } - else { - putchar ('\r'); - putchar (pchar); - if (eraseln) - erasep (1); - else if (docrtkill) - while (promptlen-- > 1) - putserr(BSB); - promptlen = 1; - } - sp = buf; - fflush (stdout); - continue; - } - if (slash && ((cc_t) c == otty.c_cc[VKILL] - || (cc_t) c == otty.c_cc[VERASE])) { - ERASEONECOLUMN - --sp; - } - if (c != '\\') - slash = 0; - *sp++ = c; - if ((c < ' ' && c != '\n' && c != ESC) || c == RUBOUT) { - c += (c == RUBOUT) ? -0100 : 0100; - putserr(CARAT); - promptlen++; - } - if (c != '\n' && c != ESC) { - putcerr(c); - promptlen++; + if (slash && ((cc_t) c == otty.c_cc[VKILL] + || (cc_t) c == otty.c_cc[VERASE])) { + ERASEONECOLUMN-- sp; + } + if (c != '\\') + slash = 0; + *sp++ = c; + if ((c < ' ' && c != '\n' && c != ESC) || c == RUBOUT) { + c += (c == RUBOUT) ? -0100 : 0100; + putserr(CARAT); + promptlen++; + } + if (c != '\n' && c != ESC) { + putcerr(c); + promptlen++; + } else + break; } - else - break; - } - *--sp = '\0'; - if (!eraseln) promptlen = maxlen; - if (sp - buf >= nmax - 1) - more_error (_("Line too long")); + *--sp = '\0'; + if (!eraseln) + promptlen = maxlen; + if (sp - buf >= nmax - 1) + more_error(_("Line too long")); } /* return: 0 - unchanged, 1 - changed, -1 - overflow (unchanged) */ -int expand (char **outbuf, char *inbuf) { - char *inpstr; - char *outstr; - char c; - char *temp; - int changed = 0; - int tempsz, xtra, offset; - - xtra = strlen (fnames[fnum]) + strlen (shell_line) + 1; - tempsz = 200 + xtra; - temp = xmalloc(tempsz); - inpstr = inbuf; - outstr = temp; - while ((c = *inpstr++) != '\0'){ - offset = outstr-temp; - if (tempsz-offset-1 < xtra) { - tempsz += 200 + xtra; - temp = xrealloc(temp, tempsz); - outstr = temp + offset; - } - switch (c) { - case '%': - if (!no_intty) { - strcpy (outstr, fnames[fnum]); - outstr += strlen (fnames[fnum]); - changed++; - } else - *outstr++ = c; - break; - case '!': - if (!shellp) - more_error (_("No previous command to substitute for")); - strcpy (outstr, shell_line); - outstr += strlen (shell_line); - changed++; - break; - case '\\': - if (*inpstr == '%' || *inpstr == '!') { - *outstr++ = *inpstr++; - break; - } - default: - *outstr++ = c; +int expand(char **outbuf, char *inbuf) +{ + char *inpstr; + char *outstr; + char c; + char *temp; + int changed = 0; + int tempsz, xtra, offset; + + xtra = strlen(fnames[fnum]) + strlen(shell_line) + 1; + tempsz = 200 + xtra; + temp = xmalloc(tempsz); + inpstr = inbuf; + outstr = temp; + while ((c = *inpstr++) != '\0') { + offset = outstr - temp; + if (tempsz - offset - 1 < xtra) { + tempsz += 200 + xtra; + temp = xrealloc(temp, tempsz); + outstr = temp + offset; + } + switch (c) { + case '%': + if (!no_intty) { + strcpy(outstr, fnames[fnum]); + outstr += strlen(fnames[fnum]); + changed++; + } else + *outstr++ = c; + break; + case '!': + if (!shellp) + more_error(_ + ("No previous command to substitute for")); + strcpy(outstr, shell_line); + outstr += strlen(shell_line); + changed++; + break; + case '\\': + if (*inpstr == '%' || *inpstr == '!') { + *outstr++ = *inpstr++; + break; + } + default: + *outstr++ = c; + } } - } - *outstr++ = '\0'; - *outbuf = temp; - return (changed); + *outstr++ = '\0'; + *outbuf = temp; + return (changed); } -void show (char c) { - if ((c < ' ' && c != '\n' && c != ESC) || c == RUBOUT) { - c += (c == RUBOUT) ? -0100 : 0100; - putserr(CARAT); +void show(char c) +{ + if ((c < ' ' && c != '\n' && c != ESC) || c == RUBOUT) { + c += (c == RUBOUT) ? -0100 : 0100; + putserr(CARAT); + promptlen++; + } + putcerr(c); promptlen++; - } - putcerr(c); - promptlen++; } -void more_error (char *mess) +void more_error(char *mess) { - if (clreol) - cleareol (); - else - kill_line (); - promptlen += strlen (mess); - if (Senter && Sexit) { - my_putstring (Senter); - putsout(mess); - my_putstring (Sexit); - } - else - putsout(mess); - fflush(stdout); - errors++; - siglongjmp (restore, 1); + if (clreol) + cleareol(); + else + kill_line(); + promptlen += strlen(mess); + if (Senter && Sexit) { + my_putstring(Senter); + putsout(mess); + my_putstring(Sexit); + } else + putsout(mess); + fflush(stdout); + errors++; + siglongjmp(restore, 1); } - -void set_tty () { - otty.c_lflag &= ~(ICANON|ECHO); +void set_tty() +{ + otty.c_lflag &= ~(ICANON | ECHO); otty.c_cc[VMIN] = 1; /* read at least 1 char */ otty.c_cc[VTIME] = 0; /* no timeout */ stty(fileno(stderr), &otty); } -static int -ourputch(int c) { +static int ourputch(int c) +{ return putc(c, stdout); } -void -reset_tty () { - if (no_tty) - return; - if (pstate) { - tputs(ULexit, fileno(stdout), ourputch); /* putchar - if that isn't a macro */ - fflush(stdout); - pstate = 0; - } - otty.c_lflag |= ICANON|ECHO; - otty.c_cc[VMIN] = savetty0.c_cc[VMIN]; - otty.c_cc[VTIME] = savetty0.c_cc[VTIME]; - stty(fileno(stderr), &savetty0); +void reset_tty() +{ + if (no_tty) + return; + if (pstate) { + /* putchar - if that isn't a macro */ + tputs(ULexit, fileno(stdout), ourputch); + fflush(stdout); + pstate = 0; + } + otty.c_lflag |= ICANON | ECHO; + otty.c_cc[VMIN] = savetty0.c_cc[VMIN]; + otty.c_cc[VTIME] = savetty0.c_cc[VTIME]; + stty(fileno(stderr), &savetty0); } -void rdline (register FILE *f) +void rdline(register FILE *f) { - register int c; - register char *p; + register int c; + register char *p; - prepare_line_buffer(); + prepare_line_buffer(); - p = Line; - while ((c = Getc (f)) != '\n' && c != EOF && (size_t) (p - Line) < LineLen - 1) - *p++ = c; - if (c == '\n') - Currline++; - *p = '\0'; + p = Line; + while ((c = Getc(f)) != '\n' && c != EOF + && (size_t)(p - Line) < LineLen - 1) + *p++ = c; + if (c == '\n') + Currline++; + *p = '\0'; } /* Come here when we get a suspend signal from the terminal */ - -void onsusp (int dummy __attribute__ ((__unused__))) +void onsusp(int dummy __attribute__((__unused__))) { - sigset_t signals, oldmask; - - /* ignore SIGTTOU so we don't get stopped if csh grabs the tty */ - signal(SIGTTOU, SIG_IGN); - reset_tty (); - fflush (stdout); - signal(SIGTTOU, SIG_DFL); - /* Send the TSTP signal to suspend our process group */ - signal(SIGTSTP, SIG_DFL); - - /* unblock SIGTSTP or we won't be able to suspend ourself */ - sigemptyset(&signals); - sigaddset(&signals, SIGTSTP); - sigprocmask(SIG_UNBLOCK, &signals, &oldmask); - - kill (0, SIGTSTP); - /* Pause for station break */ - - sigprocmask(SIG_SETMASK, &oldmask, NULL); - - /* We're back */ - signal (SIGTSTP, onsusp); - set_tty (); - if (inwait) - siglongjmp (restore, 1); + sigset_t signals, oldmask; + + /* ignore SIGTTOU so we don't get stopped if csh grabs the tty */ + signal(SIGTTOU, SIG_IGN); + reset_tty(); + fflush(stdout); + signal(SIGTTOU, SIG_DFL); + /* Send the TSTP signal to suspend our process group */ + signal(SIGTSTP, SIG_DFL); + + /* unblock SIGTSTP or we won't be able to suspend ourself */ + sigemptyset(&signals); + sigaddset(&signals, SIGTSTP); + sigprocmask(SIG_UNBLOCK, &signals, &oldmask); + + kill(0, SIGTSTP); + /* Pause for station break */ + + sigprocmask(SIG_SETMASK, &oldmask, NULL); + + /* We're back */ + signal(SIGTSTP, onsusp); + set_tty(); + if (inwait) + siglongjmp(restore, 1); } -- cgit v1.2.3-55-g7522