/* Sccsid @(#)pg.c 1.44 (gritter) 2/8/02 - modified for util-linux */
+/*
+ * This command is deprecated. The utility is in maintenance mode,
+ * meaning we keep them in source tree for backward compatibility
+ * only. Do not waste time making this command better, unless the
+ * fix is about security or other very critical issue.
+ *
+ * See Documentation/deprecated.txt for more information.
+ */
+
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#ifndef TIOCGWINSZ
-#include <sys/ioctl.h>
+# include <sys/ioctl.h>
#endif
-#include <sys/termios.h>
+#include <termios.h>
#include <fcntl.h>
#include <regex.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <setjmp.h>
-#include <libgen.h>
-#ifdef HAVE_NCURSES_H
-#include <ncurses.h>
+#if defined(HAVE_NCURSESW_NCURSES_H)
+# include <ncursesw/ncurses.h>
#elif defined(HAVE_NCURSES_NCURSES_H)
-#include <ncurses/ncurses.h>
+# include <ncurses/ncurses.h>
+#elif defined(HAVE_NCURSES_H)
+# include <ncurses.h>
#endif
-#include <term.h>
+#if defined(HAVE_NCURSESW_TERM_H)
+# include <ncursesw/term.h>
+#elif defined(HAVE_NCURSES_TERM_H)
+# include <ncurses/term.h>
+#elif defined(HAVE_TERM_H)
+# include <term.h>
+#endif
#include "nls.h"
#include "xalloc.h"
#define READBUF LINE_MAX /* size of input buffer */
#define CMDBUF 255 /* size of command buffer */
-#define TABSIZE 8 /* spaces consumed by tab character */
-
-/*
- * Avoid the message "`var' might be clobbered by `longjmp' or `vfork'"
- */
-#define CLOBBGRD(a) (void)(&(a));
+#define PG_TABSIZE 8 /* spaces consumed by tab character */
#define cuc(c) ((c) & 0377)
enum { FORWARD = 1, BACKWARD = 2 }; /* search direction */
enum { TOP, MIDDLE, BOTTOM }; /* position of matching line */
-/*
- * States for syntax-aware command line editor.
- */
+/* States for syntax-aware command line editor. */
enum {
COUNT,
SIGN,
INVALID
};
-/*
- * Current command
- */
-struct {
+/* Current command */
+static struct {
char cmdline[CMDBUF];
size_t cmdlen;
int count;
char addon;
} cmd;
-/*
- * Position of file arguments on argv[] to main()
- */
-struct {
+/* Position of file arguments on argv[] to main() */
+static struct {
int first;
int current;
int last;
} files;
-void (*oldint)(int); /* old SIGINT handler */
-void (*oldquit)(int); /* old SIGQUIT handler */
-void (*oldterm)(int); /* old SIGTERM handler */
-char *tty; /* result of ttyname(1) */
-unsigned ontty; /* whether running on tty device */
-unsigned exitstatus; /* exit status */
-int pagelen = 23; /* lines on a single screen page */
-int ttycols = 79; /* screen columns (starting at 0) */
-struct termios otio; /* old termios settings */
-int tinfostat = -1; /* terminfo routines initialized */
-int searchdisplay = TOP; /* matching line position */
-regex_t re; /* regular expression to search for */
-int remembered; /* have a remembered search string */
-int cflag; /* clear screen before each page */
-int eflag; /* suppress (EOF) */
-int fflag; /* do not split lines */
-int nflag; /* no newline for commands required */
-int rflag; /* "restricted" pg */
-int sflag; /* use standout mode */
-const char *pstring = ":"; /* prompt string */
-char *searchfor; /* search pattern from argv[] */
-int havepagelen; /* page length is manually defined */
-long startline; /* start line from argv[] */
-int nextfile = 1; /* files to advance */
-jmp_buf jmpenv; /* jump from signal handlers */
-int canjump; /* jmpenv is valid */
-wchar_t wbuf[READBUF]; /* used in several widechar routines */
-
-char *copyright;
-const char *helpscreen = N_("\
+static void (*oldint) (int); /* old SIGINT handler */
+static void (*oldquit) (int); /* old SIGQUIT handler */
+static void (*oldterm) (int); /* old SIGTERM handler */
+static char *tty; /* result of ttyname(1) */
+static unsigned ontty; /* whether running on tty device */
+static unsigned exitstatus; /* exit status */
+static int pagelen = 23; /* lines on a single screen page */
+static int ttycols = 79; /* screen columns (starting at 0) */
+static struct termios otio; /* old termios settings */
+static int tinfostat = -1; /* terminfo routines initialized */
+static int searchdisplay = TOP; /* matching line position */
+static regex_t re; /* regular expression to search for */
+static int remembered; /* have a remembered search string */
+static int cflag; /* clear screen before each page */
+static int eflag; /* suppress (EOF) */
+static int fflag; /* do not split lines */
+static int nflag; /* no newline for commands required */
+static int rflag; /* "restricted" pg */
+static int sflag; /* use standout mode */
+static const char *pstring = ":"; /* prompt string */
+static char *searchfor; /* search pattern from argv[] */
+static int havepagelen; /* page length is manually defined */
+static long startline; /* start line from argv[] */
+static int nextfile = 1; /* files to advance */
+static jmp_buf jmpenv; /* jump from signal handlers */
+static int canjump; /* jmpenv is valid */
+static wchar_t wbuf[READBUF]; /* used in several widechar routines */
+
+static char *copyright;
+static const char *helpscreen = N_("\
-------------------------------------------------------\n\
h this screen\n\
q or Q quit program\n\
-------------------------------------------------------\n");
#ifndef HAVE_FSEEKO
- static int fseeko(FILE *f, off_t off, int whence) {
- return fseek(f, (long) off, whence);
- }
- static off_t ftello(FILE *f) {
+static int fseeko(FILE *f, off_t off, int whence)
+{
+ return fseek(f, (long)off, whence);
+}
+
+static off_t ftello(FILE *f)
+{
return (off_t) ftell(f);
- }
+}
#endif
#ifdef USE_SIGSET /* never defined */
/* sigset and sigrelse are obsolete - use when POSIX stuff is unavailable */
-#define my_sigset sigset
-#define my_sigrelse sigrelse
+# define my_sigset sigset
+# define my_sigrelse sigrelse
#else
-static int my_sigrelse(int sig) {
+static int my_sigrelse(int sig)
+{
sigset_t sigs;
if (sigemptyset(&sigs) || sigaddset(&sigs, sig))
return -1;
return sigprocmask(SIG_UNBLOCK, &sigs, NULL);
}
-typedef void (*my_sighandler_t)(int);
-static my_sighandler_t my_sigset(int sig, my_sighandler_t disp) {
+
+typedef void (*my_sighandler_t) (int);
+static my_sighandler_t my_sigset(int sig, my_sighandler_t disp)
+{
struct sigaction act, oact;
act.sa_handler = disp;
return SIG_ERR;
return oact.sa_handler;
}
-#endif
+#endif /* USE_SIGSET */
-/*
- * Quit pg.
- */
-static void
-quit(int status)
+/* Quit pg. */
+static void __attribute__((__noreturn__)) quit(int status)
{
exit(status < 0100 ? status : 077);
}
-/*
- * Usage message and similar routines.
- */
-static void usage(FILE * out)
+/* Usage message and similar routines. */
+static void __attribute__((__noreturn__)) usage(void)
{
+ FILE *out = stdout;
fputs(USAGE_HEADER, out);
fprintf(out,
- _(" %s [options] [+line] [+/pattern/] [files]\n"),
+ _(" %s [options] [+line] [+/pattern/] [files]\n"),
program_invocation_short_name);
+
+ fputs(USAGE_SEPARATOR, out);
+ fputs(_("Browse pagewise through text files.\n"), out);
+
fputs(USAGE_OPTIONS, out);
fputs(_(" -number lines per page\n"), out);
fputs(_(" -c clear screen before displaying\n"), out);
fputs(_(" -s print messages to stdout\n"), out);
fputs(_(" +number start at the given line\n"), out);
fputs(_(" +/pattern/ start at the line containing pattern\n"), out);
- fputs(_(" -h display this help and exit\n"), out);
- fputs(_(" -V output version information and exit\n"), out);
- fprintf(out, USAGE_MAN_TAIL("pg(1)"));
- quit(out == stderr ? 2 : 0);
+
+ fputs(USAGE_SEPARATOR, out);
+ printf(USAGE_HELP_OPTIONS(16));
+
+ printf(USAGE_MAN_TAIL("pg(1)"));
+ exit(0);
}
-static void
-needarg(const char *s)
+static void __attribute__((__noreturn__)) needarg(const char *s)
{
warnx(_("option requires an argument -- %s"), s);
- usage(stderr);
+ errtryhelp(2);
}
-static void
-invopt(const char *s)
+static void __attribute__((__noreturn__)) invopt(const char *s)
{
warnx(_("illegal option -- %s"), s);
- usage(stderr);
+ errtryhelp(2);
}
#ifdef HAVE_WIDECHAR
-/*
- * A mbstowcs()-alike function that transparently handles invalid sequences.
- */
-static size_t
-xmbstowcs(wchar_t *pwcs, const char *s, size_t nwcs)
+/* A mbstowcs()-alike function that transparently handles invalid
+ * sequences. */
+static size_t xmbstowcs(wchar_t * pwcs, const char *s, size_t nwcs)
{
size_t n = nwcs;
int c;
- ignore_result( mbtowc(pwcs, NULL, MB_CUR_MAX) ); /* reset shift state */
+ ignore_result(mbtowc(pwcs, NULL, MB_CUR_MAX)); /* reset shift state */
while (*s && n) {
if ((c = mbtowc(pwcs, s, MB_CUR_MAX)) < 0) {
s++;
}
if (n)
*pwcs = L'\0';
- ignore_result( mbtowc(pwcs, NULL, MB_CUR_MAX) );
+ ignore_result(mbtowc(pwcs, NULL, MB_CUR_MAX));
return nwcs - n;
}
#endif
-/*
- * Helper function for tputs().
- */
-static int
-outcap(int i)
+/* Helper function for tputs(). */
+static int outcap(int i)
{
char c = i;
- return write_all(1, &c, 1) == 0 ? 1 : -1;
+ return write_all(STDOUT_FILENO, &c, 1) == 0 ? 1 : -1;
}
-/*
- * Write messages to terminal.
- */
-static void
-mesg(const char *message)
+/* Write messages to terminal. */
+static void mesg(const char *message)
{
if (ontty == 0)
return;
if (*message != '\n' && sflag)
vidputs(A_STANDOUT, outcap);
- write_all(1, message, strlen(message));
+ write_all(STDOUT_FILENO, message, strlen(message));
if (*message != '\n' && sflag)
vidputs(A_NORMAL, outcap);
}
-/*
- * Get the window size.
- */
-static void
-getwinsize(void)
+/* Get the window size. */
+static void getwinsize(void)
{
static int initialized, envlines, envcols, deflines, defcols;
#ifdef TIOCGWINSZ
initialized = 1;
}
#ifdef TIOCGWINSZ
- badioctl = ioctl(1, TIOCGWINSZ, &winsz);
+ badioctl = ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsz);
#endif
if (envcols)
ttycols = envcols - 1;
}
}
-/*
- * Message if skipping parts of files.
- */
-static void
-skip(int direction)
+/* Message if skipping parts of files. */
+static void skip(int direction)
{
if (direction > 0)
mesg(_("...skipping forward\n"));
mesg(_("...skipping backward\n"));
}
-/*
- * Signal handler while reading from input file.
- */
-static void
-sighandler(int signum)
+/* Signal handler while reading from input file. */
+static void sighandler(int signum)
{
if (canjump && (signum == SIGINT || signum == SIGQUIT))
longjmp(jmpenv, signum);
- tcsetattr(1, TCSADRAIN, &otio);
+ tcsetattr(STDOUT_FILENO, TCSADRAIN, &otio);
quit(exitstatus);
}
-/*
- * Check whether the requested file was specified on the command line.
- */
-static int
-checkf(void)
+/* Check whether the requested file was specified on the command line. */
+static int checkf(void)
{
if (files.current + nextfile >= files.last) {
mesg(_("No next file"));
}
#ifdef HAVE_WIDECHAR
-/*
- * Return the last character that will fit on the line at col columns
- * in case MB_CUR_MAX > 1.
- */
-static char *
-endline_for_mb(unsigned col, char *s)
+/* Return the last character that will fit on the line at col columns in
+ * case MB_CUR_MAX > 1. */
+static char *endline_for_mb(unsigned col, char *s)
{
size_t pos = 0;
wchar_t *p = wbuf;
wbuf[wl] = L'\0';
while (*p != L'\0') {
switch (*p) {
- /*
- * Cursor left.
- */
+ /* Cursor left. */
case L'\b':
if (pos > 0)
pos--;
break;
- /*
- * No cursor movement.
- */
+ /* No cursor movement. */
case L'\a':
break;
- /*
- * Special.
- */
+ /* Special. */
case L'\r':
pos = 0;
break;
case L'\n':
end = p + 1;
goto ended;
- /*
- * Cursor right.
- */
+ /* Cursor right. */
case L'\t':
- pos += TABSIZE - (pos % TABSIZE);
+ pos += PG_TABSIZE - (pos % PG_TABSIZE);
break;
default:
if (iswprint(*p))
if (*p == L'\t')
p++;
else if (pos > col + 1)
- /*
- * wcwidth() found a character that
- * has multiple columns. What happens
- * now? Assume the terminal will print
- * the entire character onto the next
- * row.
- */
+ /* wcwidth() found a character that has
+ * multiple columns. What happens now?
+ * Assume the terminal will print the
+ * entire character onto the next row. */
p--;
if (*++p == L'\n')
p++;
ended:
*end = L'\0';
p = wbuf;
- if ((pos = wcstombs(NULL, p, READBUF)) == (size_t) -1)
+ if ((pos = wcstombs(NULL, p, READBUF)) == (size_t)-1)
return s + 1;
return s + pos;
}
-#endif
+#endif /* HAVE_WIDECHAR */
-/*
- * Return the last character that will fit on the line at col columns.
- */
-static char *
-endline(unsigned col, char *s)
+/* Return the last character that will fit on the line at col columns. */
+static char *endline(unsigned col, char *s)
{
unsigned pos = 0;
char *t = s;
while (*s != '\0') {
switch (*s) {
- /*
- * Cursor left.
- */
+ /* Cursor left. */
case '\b':
if (pos > 0)
pos--;
break;
- /*
- * No cursor movement.
- */
+ /* No cursor movement. */
case '\a':
break;
- /*
- * Special.
- */
+ /* Special. */
case '\r':
pos = 0;
break;
case '\n':
t = s + 1;
goto cend;
- /*
- * Cursor right.
- */
+ /* Cursor right. */
case '\t':
- pos += TABSIZE - (pos % TABSIZE);
+ pos += PG_TABSIZE - (pos % PG_TABSIZE);
break;
default:
pos++;
return t;
}
-/*
- * Clear the current line on the terminal's screen.
- */
-static void
-cline(void)
+/* Clear the current line on the terminal's screen. */
+static void cline(void)
{
char *buf = xmalloc(ttycols + 2);
memset(buf, ' ', ttycols + 2);
buf[0] = '\r';
buf[ttycols + 1] = '\r';
- write_all(1, buf, ttycols + 2);
+ write_all(STDOUT_FILENO, buf, ttycols + 2);
free(buf);
}
-/*
- * Evaluate a command character's semantics.
- */
-static int
-getstate(int c)
+/* Evaluate a command character's semantics. */
+static int getstate(int c)
{
switch (c) {
- 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':
+ case '0':
case '\0':
return COUNT;
- case '-': case '+':
+ case '-':
+ case '+':
return SIGN;
- case 'l': case 'd': case '\004': case 'f': case 'z':
- case '.': case '\014': case '$': case 'n': case 'p':
- case 'w': case 'h': case 'q': case 'Q':
+ case 'l':
+ case 'd':
+ case '\004':
+ case 'f':
+ case 'z':
+ case '.':
+ case '\014':
+ case '$':
+ case 'n':
+ case 'p':
+ case 'w':
+ case 'h':
+ case 'q':
+ case 'Q':
return CMD_FIN;
- case '/': case '?': case '^':
+ case '/':
+ case '?':
+ case '^':
return SEARCH;
- case 's': case '!':
+ case 's':
+ case '!':
return STRING;
- case 'm': case 'b': case 't':
+ case 'm':
+ case 'b':
+ case 't':
return ADDON_FIN;
default:
#ifdef PG_BELL
if (bell)
- tputs(bell, 1, outcap);
-#endif /* PG_BELL */
+ tputs(bell, STDOUT_FILENO, outcap);
+#endif
return INVALID;
}
}
-/*
- * Get the count and ignore last character of string.
- */
-static int
-getcount(char *cmdstr)
+/* Get the count and ignore last character of string. */
+static int getcount(char *cmdstr)
{
char *buf;
char *p;
} else
*(buf + strlen(buf) - 1) = '\0';
}
- if (*buf == '\0')
+ if (*buf == '\0') {
+ free(buf);
return 1;
+ }
if (buf[0] == '-' && buf[1] == '\0') {
i = -1;
} else {
return i;
}
-/*
- * Read what the user writes at the prompt. This is tricky because
- * we check for valid input.
- */
-static void
-prompt(long long pageno)
+/* Read what the user writes at the prompt. This is tricky because we
+ * check for valid input. */
+static void prompt(long long pageno)
{
struct termios tio;
char key;
}
cmd.key = cmd.addon = cmd.cmdline[0] = '\0';
cmd.cmdlen = 0;
- tcgetattr(1, &tio);
+ tcgetattr(STDOUT_FILENO, &tio);
tio.c_lflag &= ~(ICANON | ECHO);
tio.c_cc[VMIN] = 1;
tio.c_cc[VTIME] = 0;
- tcsetattr(1, TCSADRAIN, &tio);
- tcflush(1, TCIFLUSH);
+ tcsetattr(STDOUT_FILENO, TCSADRAIN, &tio);
+ tcflush(STDOUT_FILENO, TCIFLUSH);
for (;;) {
- switch (read(1, &key, 1)) {
- case 0: quit(0);
- /*NOTREACHED*/
- case -1: quit(1);
+ switch (read(STDOUT_FILENO, &key, 1)) {
+ case 0:
+ quit(0);
+ /* NOTREACHED */
+ case -1:
+ quit(1);
}
if (key == tio.c_cc[VERASE]) {
if (cmd.cmdlen) {
- write_all(1, "\b \b", 3);
+ write_all(STDOUT_FILENO, "\b \b", 3);
cmd.cmdline[--cmd.cmdlen] = '\0';
switch (state) {
case ADDON_FIN:
break;
case SEARCH_FIN:
state = SEARCH;
- /*FALLTHRU*/
+ /* fallthrough */
case SEARCH:
- if (cmd.cmdline[cmd.cmdlen - 1]
- == '\\') {
+ if (cmd.cmdline[cmd.cmdlen - 1] == '\\') {
escape = 1;
- while(cmd.cmdline[cmd.cmdlen
- - escape - 1]
- == '\\') escape++;
+ while (cmd.cmdline[cmd.cmdlen
+ - escape - 1]
+ == '\\')
+ escape++;
escape %= 2;
- }
- else {
+ } else {
escape = 0;
if (strchr(cmd.cmdline, cmd.key)
- == NULL) {
+ == NULL) {
cmd.key = '\0';
state = COUNT;
}
continue;
}
state = COUNT;
- /*FALLTHRU*/
+ /* fallthrough */
case COUNT:
break;
case ADDON_FIN:
cmd.key = key;
}
}
- write_all(1, &key, 1);
+ write_all(STDOUT_FILENO, &key, 1);
cmd.cmdline[cmd.cmdlen++] = key;
cmd.cmdline[cmd.cmdlen] = '\0';
if (nflag && state == CMD_FIN)
goto endprompt;
}
-endprompt:
- tcsetattr(1, TCSADRAIN, &otio);
+ endprompt:
+ tcsetattr(STDOUT_FILENO, TCSADRAIN, &otio);
cline();
cmd.count = getcount(cmd.cmdline);
}
#ifdef HAVE_WIDECHAR
-/*
- * Remove backspace formatting, for searches
- * in case MB_CUR_MAX > 1.
- */
-static char *
-colb_for_mb(char *s)
+/* Remove backspace formatting, for searches in case MB_CUR_MAX > 1. */
+static char *colb_for_mb(char *s)
{
char *p = s;
wchar_t *wp, *wq;
if ((wl = xmbstowcs(wbuf, p, sizeof wbuf)) == (size_t)-1)
return s;
- for (wp = wbuf, wq = wbuf, i = 0; *wp != L'\0' && i < wl;
- wp++, wq++) {
+ for (wp = wbuf, wq = wbuf, i = 0; *wp != L'\0' && i < wl; wp++, wq++) {
if (*wp == L'\b') {
if (wq != wbuf)
wq -= 2;
}
#endif
-/*
- * Remove backspace formatting, for searches.
- */
-static char *
-colb(char *s)
+/* Remove backspace formatting, for searches. */
+static char *colb(char *s)
{
char *p = s, *q;
}
#ifdef HAVE_WIDECHAR
-/*
- * Convert nonprintable characters to spaces
- * in case MB_CUR_MAX > 1.
- */
-static void
-makeprint_for_mb(char *s, size_t l)
+/* Convert non-printable characters to spaces in case MB_CUR_MAX > 1. */
+static void makeprint_for_mb(char *s, size_t l)
{
char *t = s;
wchar_t *wp = wbuf;
}
#endif
-/*
- * Convert nonprintable characters to spaces.
- */
-static void
-makeprint(char *s, size_t l)
+/* Convert non-printable characters to spaces. */
+static void makeprint(char *s, size_t l)
{
#ifdef HAVE_WIDECHAR
if (MB_CUR_MAX > 1) {
}
}
-/*
- * Strip backslash characters from the given string.
- */
-static void
-striprs(char *s)
+/* Strip backslash characters from the given string. */
+static void striprs(char *s)
{
char *p = s;
} while (*s++ != '\0');
}
-/*
- * Extract the search pattern off the command line.
- */
-static char *
-makepat(void)
+/* Extract the search pattern off the command line. */
+static char *makepat(void)
{
char *p;
return p;
}
-/*
- * Process errors that occurred in temporary file operations.
- */
-static void
-tmperr(FILE *f, const char *ftype)
+/* Process errors that occurred in temporary file operations. */
+static void __attribute__((__noreturn__)) tmperr(FILE *f, const char *ftype)
{
if (ferror(f))
warn(_("Read error from %s file"), ftype);
else if (feof(f))
- /*
- * Most likely '\0' in input.
- */
+ /* Most likely '\0' in input. */
warnx(_("Unexpected EOF in %s file"), ftype);
else
warn(_("Unknown error in %s file"), ftype);
quit(++exitstatus);
}
-/*
- * Read the file and respond to user input.
- * Beware: long and ugly.
- */
-static void
-pgfile(FILE *f, const char *name)
+/* Read the file and respond to user input. Beware: long and ugly. */
+static void pgfile(FILE *f, const char *name)
{
off_t pos, oldpos, fpos;
+ /* These are the line counters:
+ * line the line desired to display
+ * fline the current line of the input file
+ * bline the current line of the file buffer
+ * oldline the line before a search was started
+ * eofline the last line of the file if it is already reached
+ * dline the line on the display */
off_t line = 0, fline = 0, bline = 0, oldline = 0, eofline = 0;
int dline = 0;
- /*
- * These are the line counters:
- * line the line desired to display
- * fline the current line of the input file
- * bline the current line of the file buffer
- * oldline the line before a search was started
- * eofline the last line of the file if it is already reached
- * dline the line on the display
- */
int search = 0;
unsigned searchcount = 0;
- /*
- * Advance to EOF immediately.
- */
+ /* Advance to EOF immediately. */
int seekeof = 0;
- /*
- * EOF has been reached by `line'.
- */
+ /* EOF has been reached by `line'. */
int eof = 0;
- /*
- * f and fbuf refer to the same file.
- */
+ /* f and fbuf refer to the same file. */
int nobuf = 0;
int sig;
int rerror;
size_t sz;
char b[READBUF + 1];
char *p;
- /*
- * fbuf an exact copy of the input file as it gets read
- * find index table for input, one entry per line
- * save for the s command, to save to a file
- */
+ /* fbuf an exact copy of the input file as it gets read
+ * find index table for input, one entry per line
+ * save for the s command, to save to a file */
FILE *fbuf, *find, *save;
- /* silence compiler - it may warn about longjmp() */
- CLOBBGRD(line);
- CLOBBGRD(fline);
- CLOBBGRD(bline);
- CLOBBGRD(oldline);
- CLOBBGRD(eofline);
- CLOBBGRD(dline);
- CLOBBGRD(ttycols);
- CLOBBGRD(search);
- CLOBBGRD(searchcount);
- CLOBBGRD(seekeof);
- CLOBBGRD(eof);
- CLOBBGRD(fpos);
- CLOBBGRD(nobuf);
- CLOBBGRD(fbuf);
-
if (ontty == 0) {
- /*
- * Just copy stdin to stdout.
- */
+ /* Just copy stdin to stdout. */
while ((sz = fread(b, sizeof *b, READBUF, f)) != 0)
- write_all(1, b, sz);
+ write_all(STDOUT_FILENO, b, sz);
if (ferror(f)) {
warn("%s", name);
exitstatus++;
}
find = tmpfile();
if (fbuf == NULL || find == NULL) {
- warn(_("Cannot create tempfile"));
+ warn(_("Cannot create temporary file"));
quit(++exitstatus);
}
if (searchfor) {
remembered = 1;
}
- for (line = startline; ; ) {
- /*
- * Get a line from input file or buffer.
- */
+ for (line = startline;;) {
+ /* Get a line from input file or buffer. */
if (line < bline) {
fseeko(find, line * sizeof pos, SEEK_SET);
if (fread(&pos, sizeof pos, 1, find) == 0)
fseeko(fbuf, (off_t)0, SEEK_END);
pos = ftello(fbuf);
if ((sig = setjmp(jmpenv)) != 0) {
- /*
- * We got a signal.
- */
+ /* We got a signal. */
canjump = 0;
my_sigrelse(sig);
fseeko(fbuf, pos, SEEK_SET);
*b = '\0';
dline = pagelen;
break;
- } else {
- if (nobuf)
- fseeko(f, fpos, SEEK_SET);
- canjump = 1;
- p = fgets(b, READBUF, f);
- if (nobuf)
- if ((fpos = ftello(f)) == -1)
- warn("%s", name);
- canjump = 0;
}
+
+ if (nobuf)
+ fseeko(f, fpos, SEEK_SET);
+ canjump = 1;
+ p = fgets(b, READBUF, f);
+ if (nobuf)
+ if ((fpos = ftello(f)) == -1)
+ warn("%s", name);
+ canjump = 0;
+
if (p == NULL || *b == '\0') {
if (ferror(f))
warn("%s", name);
eofline = fline;
eof = 1;
break;
- } else {
- if (!nobuf)
- fputs(b, fbuf);
- fwrite_all(&pos, sizeof pos, 1, find);
- if (!fflag) {
- oldpos = pos;
- p = b;
- while (*(p = endline(ttycols,
- p))
- != '\0') {
- pos = oldpos + (p - b);
- fwrite_all(&pos,
- sizeof pos,
- 1, find);
- fline++;
- bline++;
- }
+ }
+
+ if (!nobuf)
+ fputs(b, fbuf);
+ fwrite_all(&pos, sizeof pos, 1, find);
+ if (!fflag) {
+ oldpos = pos;
+ p = b;
+ while (*(p = endline(ttycols,
+ p))
+ != '\0') {
+ pos = oldpos + (p - b);
+ fwrite_all(&pos,
+ sizeof pos,
+ 1, find);
+ fline++;
+ bline++;
}
- fline++;
}
+ fline++;
} while (line > bline++);
} else {
- /*
- * eofline != 0
- */
+ /* eofline != 0 */
eof = 1;
}
if (search == FORWARD && remembered == 1) {
skip(1);
}
continue;
- } else if (eof) { /*
- * We are not searching.
- */
+ }
+
+ if (eof) {
+ /* We are not searching. */
line = bline;
} else if (*b != '\0') {
if (cflag && clear_screen) {
switch (dline) {
case 0:
- tputs(clear_screen, 1, outcap);
+ tputs(clear_screen, STDOUT_FILENO,
+ outcap);
dline = 0;
}
}
eof = 1;
dline++;
if ((sig = setjmp(jmpenv)) != 0) {
- /*
- * We got a signal.
- */
+ /* We got a signal. */
canjump = 0;
my_sigrelse(sig);
dline = pagelen;
sz = p - b;
makeprint(b, sz);
canjump = 1;
- write_all(1, b, sz);
+ write_all(STDOUT_FILENO, b, sz);
canjump = 0;
}
}
if (dline >= pagelen || eof) {
- /*
- * Time for prompting!
- */
+ /* Time for prompting! */
if (eof && seekeof) {
eof = seekeof = 0;
if (line >= pagelen)
dline = -1;
continue;
}
-newcmd:
+ newcmd:
if (eof) {
if (fline == 0 || eflag)
break;
prompt((line - 1) / pagelen + 1);
switch (cmd.key) {
case '/':
- /*
- * Search forward.
- */
+ /* Search forward. */
search = FORWARD;
oldline = line;
searchcount = cmd.count;
if (remembered == 1)
regfree(&re);
rerror = regcomp(&re, p,
- REG_NOSUB | REG_NEWLINE);
+ REG_NOSUB |
+ REG_NEWLINE);
if (rerror != 0) {
mesg(_("RE error: "));
sz = regerror(rerror, &re,
- b, READBUF);
+ b, READBUF);
mesg(b);
goto newcmd;
}
continue;
case '?':
case '^':
- /*
- * Search backward.
- */
+ /* Search backward. */
search = BACKWARD;
oldline = line;
searchcount = cmd.count;
if (remembered == 1)
regfree(&re);
rerror = regcomp(&re, p,
- REG_NOSUB | REG_NEWLINE);
+ REG_NOSUB |
+ REG_NEWLINE);
if (rerror != 0) {
mesg(_("RE error: "));
regerror(rerror, &re,
- b, READBUF);
+ b, READBUF);
mesg(b);
goto newcmd;
}
goto notfound_bw;
while (line) {
fseeko(find, --line * sizeof pos,
- SEEK_SET);
- if(fread(&pos, sizeof pos, 1,find)==0)
+ SEEK_SET);
+ if (fread(&pos, sizeof pos, 1, find) ==
+ 0)
tmperr(find, "index");
fseeko(find, (off_t)0, SEEK_END);
fseeko(fbuf, pos, SEEK_SET);
if (searchcount == 0)
goto found_bw;
}
-notfound_bw:
+ notfound_bw:
line = oldline;
search = searchcount = 0;
mesg(_("Pattern not found"));
goto newcmd;
-found_bw:
+ found_bw:
eof = search = dline = 0;
skip(-1);
switch (searchdisplay) {
line = 0;
continue;
case 's':
- /*
- * Save to file.
- */
+ /* Save to file. */
p = cmd.cmdline;
- while (*++p == ' ');
+ while (*++p == ' ') ;
if (*p == '\0')
goto newcmd;
save = fopen(p, "wb");
mesg(strerror(cmd.count));
goto newcmd;
}
- /*
- * Advance to EOF.
- */
+ /* Advance to EOF. */
fseeko(find, (off_t)0, SEEK_END);
for (;;) {
if (!nobuf)
- fseeko(fbuf,(off_t)0,SEEK_END);
+ fseeko(fbuf, (off_t)0,
+ SEEK_END);
pos = ftello(fbuf);
if (fgets(b, READBUF, f) == NULL) {
eofline = fline;
oldpos = pos;
p = b;
while (*(p = endline(ttycols,
- p))
- != '\0') {
+ p))
+ != '\0') {
pos = oldpos + (p - b);
fwrite_all(&pos,
- sizeof pos,
- 1, find);
+ sizeof pos,
+ 1, find);
fline++;
bline++;
}
}
fseeko(fbuf, (off_t)0, SEEK_SET);
while ((sz = fread(b, sizeof *b, READBUF,
- fbuf)) != 0) {
- /*
- * No error check for compat.
- */
+ fbuf)) != 0) {
+ /* No error check for compat. */
fwrite_all(b, sizeof *b, sz, save);
}
- fclose(save);
+ if (close_stream(save) != 0) {
+ cmd.count = errno;
+ mesg(_("write failed"));
+ mesg(": ");
+ mesg(p);
+ mesg(strerror(cmd.count));
+ goto newcmd;
+ }
fseeko(fbuf, (off_t)0, SEEK_END);
mesg(_("saved"));
goto newcmd;
case 'l':
- /*
- * Next line.
- */
+ /* Next line. */
if (*cmd.cmdline != 'l')
eof = 0;
if (cmd.count == 0)
- cmd.count = 1; /* compat */
+ cmd.count = 1; /* compat */
if (isdigit(cuc(*cmd.cmdline))) {
line = cmd.count - 2;
dline = 0;
} else {
if (cmd.count != 1) {
- line += cmd.count - 1
- - pagelen;
+ line += cmd.count - 1 - pagelen;
dline = -1;
skip(cmd.count);
}
- /*
- * Nothing to do if count==1.
- */
+ /* Nothing to do if (count == 1) */
}
break;
case 'd':
- /*
- * Half screen forward.
- */
+ /* Half screen forward. */
case '\004': /* ^D */
if (*cmd.cmdline != cmd.key)
eof = 0;
if (cmd.count == 0)
- cmd.count = 1; /* compat */
+ cmd.count = 1; /* compat */
line += (cmd.count * pagelen / 2)
- - pagelen - 1;
+ - pagelen - 1;
dline = -1;
skip(cmd.count);
break;
case 'f':
- /*
- * Skip forward.
- */
+ /* Skip forward. */
if (cmd.count <= 0)
- cmd.count = 1; /* compat */
+ cmd.count = 1; /* compat */
line += cmd.count * pagelen - 2;
if (eof)
line += 2;
skip(cmd.count);
break;
case '\0':
- /*
- * Just a number, or '-', or <newline>.
- */
+ /* Just a number, or '-', or <newline>. */
if (cmd.count == 0)
- cmd.count = 1; /* compat */
+ cmd.count = 1; /* compat */
if (isdigit(cuc(*cmd.cmdline)))
line = (cmd.count - 1) * pagelen - 2;
else
line += (cmd.count - 1)
- * (pagelen - 1) - 2;
+ * (pagelen - 1) - 2;
if (*cmd.cmdline != '\0')
eof = 0;
if (cmd.count != 1) {
}
break;
case '$':
- /*
- * Advance to EOF.
- */
+ /* Advance to EOF. */
if (!eof)
skip(1);
eof = 0;
dline = -1;
break;
case '.':
- case '\014': /* ^L */
- /*
- * Repaint screen.
- */
+ case '\014': /* ^L */
+ /* Repaint screen. */
eof = 0;
if (line >= pagelen)
line -= pagelen;
dline = 0;
break;
case '!':
- /*
- * Shell escape.
- */
+ /* Shell escape. */
if (rflag) {
mesg(program_invocation_short_name);
mesg(_(": !command not allowed in "
} else {
pid_t cpid;
- write_all(1, cmd.cmdline,
- strlen(cmd.cmdline));
- write_all(1, "\n", 1);
+ write_all(STDOUT_FILENO, cmd.cmdline,
+ strlen(cmd.cmdline));
+ write_all(STDOUT_FILENO, "\n", 1);
my_sigset(SIGINT, SIG_IGN);
my_sigset(SIGQUIT, SIG_IGN);
switch (cpid = fork()) {
my_sigset(SIGQUIT, oldquit);
my_sigset(SIGTERM, oldterm);
execl(sh, sh, "-c",
- cmd.cmdline + 1, NULL);
- warn("%s", sh);
- _exit(0177);
- /*NOTREACHED*/
+ cmd.cmdline + 1, NULL);
+ errexec(sh);
+ break;
}
case -1:
mesg(_("fork() failed, "
"try again later\n"));
break;
default:
- while (wait(NULL) != cpid);
+ while (wait(NULL) != cpid) ;
}
my_sigset(SIGINT, sighandler);
my_sigset(SIGQUIT, sighandler);
}
goto newcmd;
case 'h':
- {
- /*
- * Help!
- */
- const char *help = _(helpscreen);
- write_all(1, copyright, strlen(copyright));
- write_all(1, help, strlen(help));
- goto newcmd;
- }
+ {
+ /* Help! */
+ const char *help = _(helpscreen);
+ write_all(STDOUT_FILENO, copyright,
+ strlen(copyright));
+ write_all(STDOUT_FILENO, help,
+ strlen(help));
+ goto newcmd;
+ }
case 'n':
- /*
- * Next file.
- */
+ /* Next file. */
if (cmd.count == 0)
cmd.count = 1;
nextfile = cmd.count;
eof = 1;
break;
case 'p':
- /*
- * Previous file.
- */
+ /* Previous file. */
if (cmd.count == 0)
cmd.count = 1;
nextfile = 0 - cmd.count;
break;
case 'q':
case 'Q':
- /*
- * Exit pg.
- */
+ /* Exit pg. */
quit(exitstatus);
- /*NOTREACHED*/
+ /* NOTREACHED */
case 'w':
case 'z':
- /*
- * Set window size.
- */
+ /* Set window size. */
if (cmd.count < 0)
cmd.count = 0;
if (*cmd.cmdline != cmd.key)
fclose(fbuf);
}
-static int
-parse_arguments(int arg, int argc, char **argv)
+static int parse_arguments(int arg, int argc, char **argv)
{
FILE *input;
prompt(-1);
switch (cmd.key) {
case 'n':
- /*
- * Next file.
- */
+ /* Next file. */
if (cmd.count == 0)
cmd.count = 1;
nextfile = cmd.count;
}
continue;
case 'p':
- /*
- * Previous file.
- */
+ /* Previous file. */
if (cmd.count == 0)
cmd.count = 1;
nextfile = 0 - cmd.count;
}
}
if (ontty == 0 && argc > 2) {
- /*
- * Use the prefix as specified by SUSv2.
- */
- write_all(1, "::::::::::::::\n", 15);
- write_all(1, argv[arg], strlen(argv[arg]));
- write_all(1, "\n::::::::::::::\n", 16);
+ /* Use the prefix as specified by SUSv2. */
+ write_all(STDOUT_FILENO, "::::::::::::::\n", 15);
+ write_all(STDOUT_FILENO, argv[arg], strlen(argv[arg]));
+ write_all(STDOUT_FILENO, "\n::::::::::::::\n", 16);
}
pgfile(input, argv[arg]);
if (input != stdin)
return exitstatus;
}
-int
-main(int argc, char **argv)
+int main(int argc, char **argv)
{
int arg, i;
char *p;
_("%s %s Copyright (c) 2000-2001 Gunnar Ritter. All rights reserved.\n"),
program_invocation_short_name, PACKAGE_VERSION);
- setlocale(LC_MESSAGES, "");
+ setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
- atexit(close_stdout);
+ close_stdout_atexit();
- if (tcgetattr(1, &otio) == 0) {
+ if (tcgetattr(STDOUT_FILENO, &otio) == 0) {
ontty = 1;
oldint = my_sigset(SIGINT, sighandler);
oldquit = my_sigset(SIGQUIT, sighandler);
oldterm = my_sigset(SIGTERM, sighandler);
setlocale(LC_CTYPE, "");
setlocale(LC_COLLATE, "");
- tty = ttyname(1);
- setupterm(NULL, 1, &tinfostat);
+ tty = ttyname(STDOUT_FILENO);
+ setupterm(NULL, STDOUT_FILENO, &tinfostat);
getwinsize();
helpscreen = _(helpscreen);
}
if (*argv[arg] != '-' || argv[arg][1] == '\0')
break;
argc--;
+
+ if (!strcmp(argv[arg], "--help")) {
+ usage();
+ }
+
+ if (!strcmp(argv[arg], "--version")) {
+ print_version(EXIT_SUCCESS);
+ return EXIT_SUCCESS;
+ }
+
for (i = 1; argv[arg][i]; i++) {
switch (argv[arg][i]) {
case '-':
if (i != 1 || argv[arg][i + 1])
invopt(&argv[arg][i]);
goto endargs;
- 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':
+ case '0':
pagelen = strtol_or_err(argv[arg] + 1,
_("failed to parse number of lines per page"));
havepagelen = 1;
case 's':
sflag = 1;
break;
+
case 'h':
- usage(stdout);
+ usage();
case 'V':
- printf(UTIL_LINUX_VERSION);
- return EXIT_SUCCESS;
+ print_version(EXIT_SUCCESS);
default:
invopt(&argv[arg][i]);
}
}
-nextarg:
+ nextarg:
;
}
-endargs:
+ endargs:
for (arg = 1; argv[arg]; arg++) {
if (*argv[arg] == '-') {
if (argv[arg][1] == '-') {
case '\0':
needarg("+");
/*NOTREACHED*/
- 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':
+ case '0':
startline = strtol_or_err(argv[arg] + 1,
_("failed to parse number of lines per page"));
break;
if (*searchfor == '\0')
needarg("+/");
p = searchfor + strlen(searchfor) - 1;
- if (*p == '/') *p = '\0';
+ if (*p == '/')
+ *p = '\0';
if (*searchfor == '\0')
needarg("+/");
break;
exitstatus = parse_arguments(arg, argc, argv);
quit(exitstatus);
- /*NOTREACHED*/
+ /* NOTREACHED */
return 0;
}