]> git.ipfire.org Git - thirdparty/util-linux.git/blobdiff - text-utils/pg.c
wipefs: add --lock and LOCK_BLOCK_DEVICE
[thirdparty/util-linux.git] / text-utils / pg.c
index 26f6c928bca1a002a0549a63b079b64f95d433a6..5d01ebff34f1389ff0716e69b6034842fd02bfa1 100644 (file)
 
 /* 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,
@@ -94,10 +103,8 @@ enum {
        INVALID
 };
 
-/*
- * Current command
- */
-struct {
+/* Current command */
+static struct {
        char cmdline[CMDBUF];
        size_t cmdlen;
        int count;
@@ -106,45 +113,43 @@ struct {
        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\
@@ -169,28 +174,34 @@ See pg(1) for more information.\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;
@@ -203,26 +214,26 @@ static my_sighandler_t my_sigset(int sig, my_sighandler_t 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);
@@ -234,37 +245,35 @@ static void usage(FILE * 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++;
@@ -276,41 +285,32 @@ xmbstowcs(wchar_t *pwcs, const char *s, size_t nwcs)
        }
        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
@@ -338,7 +338,7 @@ getwinsize(void)
                initialized = 1;
        }
 #ifdef TIOCGWINSZ
-       badioctl = ioctl(1, TIOCGWINSZ, &winsz);
+       badioctl = ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsz);
 #endif
        if (envcols)
                ttycols = envcols - 1;
@@ -360,11 +360,8 @@ getwinsize(void)
        }
 }
 
-/*
- * 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"));
@@ -372,23 +369,17 @@ skip(int direction)
                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"));
@@ -402,12 +393,9 @@ checkf(void)
 }
 
 #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;
@@ -420,32 +408,24 @@ endline_for_mb(unsigned col, char *s)
        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))
@@ -457,13 +437,10 @@ endline_for_mb(unsigned col, char *s)
                        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++;
@@ -476,17 +453,14 @@ endline_for_mb(unsigned col, char *s)
  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;
@@ -498,32 +472,24 @@ endline(unsigned col, char *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++;
@@ -543,57 +509,73 @@ endline(unsigned col, char *s)
        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;
@@ -610,8 +592,10 @@ getcount(char *cmdstr)
                } 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 {
@@ -624,12 +608,9 @@ getcount(char *cmdstr)
        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;
@@ -649,21 +630,23 @@ prompt(long long pageno)
        }
        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:
@@ -676,20 +659,19 @@ prompt(long long pageno)
                                        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;
                                                }
@@ -756,7 +738,7 @@ prompt(long long pageno)
                                        continue;
                                }
                                state = COUNT;
-                               /*FALLTHRU*/
+                               /* fallthrough */
                        case COUNT:
                                break;
                        case ADDON_FIN:
@@ -766,25 +748,21 @@ prompt(long long pageno)
                                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;
@@ -793,8 +771,7 @@ colb_for_mb(char *s)
 
        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;
@@ -811,11 +788,8 @@ colb_for_mb(char *s)
 }
 #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;
 
@@ -839,12 +813,8 @@ colb(char *s)
 }
 
 #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;
@@ -863,11 +833,8 @@ makeprint_for_mb(char *s, size_t l)
 }
 #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) {
@@ -884,11 +851,8 @@ makeprint(char *s, size_t l)
        }
 }
 
-/*
- * 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;
 
@@ -900,11 +864,8 @@ striprs(char *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;
 
@@ -923,91 +884,54 @@ makepat(void)
        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++;
@@ -1022,7 +946,7 @@ pgfile(FILE *f, const char *name)
        }
        find = tmpfile();
        if (fbuf == NULL || find == NULL) {
-               warn(_("Cannot create tempfile"));
+               warn(_("Cannot create temporary file"));
                quit(++exitstatus);
        }
        if (searchfor) {
@@ -1039,10 +963,8 @@ pgfile(FILE *f, const char *name)
                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)
@@ -1058,56 +980,53 @@ pgfile(FILE *f, const char *name)
                                        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) {
@@ -1139,15 +1058,17 @@ pgfile(FILE *f, const char *name)
                                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;
                                }
                        }
@@ -1156,9 +1077,7 @@ pgfile(FILE *f, const char *name)
                                eof = 1;
                        dline++;
                        if ((sig = setjmp(jmpenv)) != 0) {
-                               /*
-                                * We got a signal.
-                                */
+                               /* We got a signal. */
                                canjump = 0;
                                my_sigrelse(sig);
                                dline = pagelen;
@@ -1167,14 +1086,12 @@ pgfile(FILE *f, const char *name)
                                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)
@@ -1184,7 +1101,7 @@ pgfile(FILE *f, const char *name)
                                dline = -1;
                                continue;
                        }
-newcmd:
+ newcmd:
                        if (eof) {
                                if (fline == 0 || eflag)
                                        break;
@@ -1193,9 +1110,7 @@ newcmd:
                        prompt((line - 1) / pagelen + 1);
                        switch (cmd.key) {
                        case '/':
-                               /*
-                                * Search forward.
-                                */
+                               /* Search forward. */
                                search = FORWARD;
                                oldline = line;
                                searchcount = cmd.count;
@@ -1204,11 +1119,12 @@ newcmd:
                                        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;
                                        }
@@ -1220,9 +1136,7 @@ newcmd:
                                continue;
                        case '?':
                        case '^':
-                               /*
-                                * Search backward.
-                                */
+                               /* Search backward. */
                                search = BACKWARD;
                                oldline = line;
                                searchcount = cmd.count;
@@ -1231,11 +1145,12 @@ newcmd:
                                        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;
                                        }
@@ -1249,8 +1164,9 @@ 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);
@@ -1262,12 +1178,12 @@ newcmd:
                                        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) {
@@ -1287,11 +1203,9 @@ found_bw:
                                        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");
@@ -1303,13 +1217,12 @@ found_bw:
                                        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;
@@ -1322,12 +1235,12 @@ found_bw:
                                                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++;
                                                }
@@ -1337,59 +1250,55 @@ found_bw:
                                }
                                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;
@@ -1403,16 +1312,14 @@ found_bw:
                                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) {
@@ -1424,9 +1331,7 @@ found_bw:
                                }
                                break;
                        case '$':
-                               /*
-                                * Advance to EOF.
-                                */
+                               /* Advance to EOF. */
                                if (!eof)
                                        skip(1);
                                eof = 0;
@@ -1435,10 +1340,8 @@ found_bw:
                                dline = -1;
                                break;
                        case '.':
-                       case '\014': /* ^L */
-                               /*
-                                * Repaint screen.
-                                */
+                       case '\014':    /* ^L */
+                               /* Repaint screen. */
                                eof = 0;
                                if (line >= pagelen)
                                        line -= pagelen;
@@ -1447,9 +1350,7 @@ found_bw:
                                dline = 0;
                                break;
                        case '!':
-                               /*
-                                * Shell escape.
-                                */
+                               /* Shell escape. */
                                if (rflag) {
                                        mesg(program_invocation_short_name);
                                        mesg(_(": !command not allowed in "
@@ -1457,9 +1358,9 @@ found_bw:
                                } 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()) {
@@ -1481,17 +1382,16 @@ found_bw:
                                                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);
@@ -1499,19 +1399,17 @@ found_bw:
                                }
                                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;
@@ -1522,9 +1420,7 @@ found_bw:
                                eof = 1;
                                break;
                        case 'p':
-                               /*
-                                * Previous file.
-                                */
+                               /* Previous file. */
                                if (cmd.count == 0)
                                        cmd.count = 1;
                                nextfile = 0 - cmd.count;
@@ -1536,16 +1432,12 @@ found_bw:
                                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)
@@ -1570,8 +1462,7 @@ found_bw:
                fclose(fbuf);
 }
 
-static int
-parse_arguments(int arg, int argc, char **argv)
+static int parse_arguments(int arg, int argc, char **argv)
 {
        FILE *input;
 
@@ -1592,9 +1483,7 @@ parse_arguments(int arg, int argc, char **argv)
                                        prompt(-1);
                                        switch (cmd.key) {
                                        case 'n':
-                                               /*
-                                                * Next file.
-                                                */
+                                               /* Next file. */
                                                if (cmd.count == 0)
                                                        cmd.count = 1;
                                                nextfile = cmd.count;
@@ -1605,9 +1494,7 @@ parse_arguments(int arg, int argc, char **argv)
                                                }
                                                continue;
                                        case 'p':
-                                               /*
-                                                * Previous file.
-                                                */
+                                               /* Previous file. */
                                                if (cmd.count == 0)
                                                        cmd.count = 1;
                                                nextfile = 0 - cmd.count;
@@ -1636,12 +1523,10 @@ parse_arguments(int arg, int argc, char **argv)
                        }
                }
                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)
@@ -1650,8 +1535,7 @@ parse_arguments(int arg, int argc, char **argv)
        return exitstatus;
 }
 
-int
-main(int argc, char **argv)
+int main(int argc, char **argv)
 {
        int arg, i;
        char *p;
@@ -1660,20 +1544,20 @@ main(int argc, char **argv)
                  _("%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);
        }
@@ -1683,14 +1567,32 @@ main(int argc, char **argv)
                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;
@@ -1722,19 +1624,19 @@ main(int argc, char **argv)
                        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] == '-') {
@@ -1754,8 +1656,16 @@ endargs:
                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;
@@ -1764,7 +1674,8 @@ endargs:
                        if (*searchfor == '\0')
                                needarg("+/");
                        p = searchfor + strlen(searchfor) - 1;
-                       if (*p == '/') *p = '\0';
+                       if (*p == '/')
+                               *p = '\0';
                        if (*searchfor == '\0')
                                needarg("+/");
                        break;
@@ -1778,6 +1689,6 @@ endargs:
                exitstatus = parse_arguments(arg, argc, argv);
 
        quit(exitstatus);
-       /*NOTREACHED*/
+       /* NOTREACHED */
        return 0;
 }