Subject: Re: pr lacks -p

From: Collin Funk <[email-masked]>
Date: Sun, 27 Jul 2025 15:36:48 -0700

Paul Eggert said:

> Given that hardly anybody uses pr any more, I'm surprised that the 
> Austin Group still cares about its options. It's an obsolete utility, 
> and ought to be deprecated.

True, but this option seems simple enough to implement.

How about the attached patch?

Collin

>From 5b4ac990e8dd43d8f3e1371e2e78271c9b35345e Mon Sep 17 00:00:00 2001
Message-ID: <5b4a[email-masked]>
From: Collin Funk <[email-masked]>
Date: Sun, 27 Jul 2025 15:00:15 -0700
Subject: [PATCH] pr: implement '-p' as required by POSIX Issue 6

* src/pr.c (pause_option): New variable.
(short_options): Add '-p'.
(long_options): Add '--pause'.
(main): Add the option. Only allow its use when stdout is a tty.
(print_files): If the option is use emit '\a' to stderr and wait until a
newline is read to print the next page.
(usage): Mention the new option.
* doc/coreutils.texi (pr invocation): Document the new option.
---
 doc/coreutils.texi |  8 ++++++++
 src/pr.c           | 30 ++++++++++++++++++++++++++----
 2 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index 7ca5b222c..14b98ea01 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -2825,6 +2825,14 @@ @node pr invocation
 set with the @option{-W/-w} option.  A limited overflow may occur with
 numbered single column output (compare @option{-n} option).
 
+@item -p
+@itemx --pause
+@opindex -p
+@opindex --pause
+After printing each page, print an alert (bell) to standard error and
+wait for a newline to be read from standard input before printing the
+next page.
+
 @item -r
 @itemx --no-file-warnings
 @opindex -r
diff --git a/src/pr.c b/src/pr.c
index e7081a059..5ccc7bf8a 100644
--- a/src/pr.c
+++ b/src/pr.c
@@ -711,6 +711,9 @@ static char *custom_header;
 /* (-D) Date format for the header.  */
 static char const *date_format;
 
+/* If true, pause after each page until a newline is read from stdin.  */
+static bool pause_option;
+
 /* The local time zone rules, as per the TZ environment variable.  */
 static timezone_t localtz;
 
@@ -738,7 +741,7 @@ enum
 };
 
 static char const short_options[] =
-  "-0123456789D:FJN:S::TW:abcde::fh:i::l:mn::o:rs::tvw:";
+  "-0123456789D:FJN:S::TW:abcde::fh:i::l:mn::po:rs::tvw:";
 
 static struct option const long_options[] =
 {
@@ -758,6 +761,7 @@ static struct option const long_options[] =
   {"number-lines", optional_argument, nullptr, 'n'},
   {"first-line-number", required_argument, nullptr, 'N'},
   {"indent", required_argument, nullptr, 'o'},
+  {"pause", no_argument, nullptr, 'p'},
   {"no-file-warnings", no_argument, nullptr, 'r'},
   {"separator", optional_argument, nullptr, 's'},
   {"sep-string", optional_argument, nullptr, 'S'},
@@ -999,6 +1003,9 @@ main (int argc, char **argv)
           chars_per_margin = getoptnum (optarg, 0,
                                         _("'-o MARGIN' invalid line offset"));
           break;
+        case 'p':
+          pause_option = true;
+          break;
         case 'r':
           ignore_failed_opens = true;
           break;
@@ -1079,6 +1086,10 @@ main (int argc, char **argv)
     error (EXIT_FAILURE, 0,
            _("cannot specify both printing across and printing in parallel"));
 
+  if (pause_option && ! isatty (STDOUT_FILENO))
+    error (EXIT_FAILURE, 0,
+           _("cannot use --pause (-p) unless writing and reading from a tty"));
+
 /* Translate some old short options to new/long options.
    To meet downward compatibility with other UNIX pr utilities
    and some POSIX specifications. */
@@ -1147,7 +1158,7 @@ main (int argc, char **argv)
 
   cleanup ();
 
-  if (have_read_stdin && fclose (stdin) == EOF)
+  if ((have_read_stdin || pause_option) && fclose (stdin) == EOF)
     error (EXIT_FAILURE, errno, _("standard input"));
   main_exit (failed_opens ? EXIT_FAILURE : EXIT_SUCCESS);
 }
@@ -1636,8 +1647,17 @@ print_files (int number_of_files, char **av)
   init_funcs ();
 
   line_number = line_count;
-  while (print_page ())
-    ;
+  for (;;)
+    {
+      if (pause_option)
+        {
+          putc ('\a', stderr);
+          while (getchar () != '\n')
+            ;
+        }
+      if (! print_page ())
+        break;
+    }
 }
 
 /* Initialize header information.
@@ -2824,6 +2844,8 @@ Paginate or columnate FILE(s) for printing.\n\
   -o, --indent=MARGIN\n\
                     offset each line with MARGIN (zero) spaces, do not\n\
                     affect -w or -W, MARGIN will be added to PAGE_WIDTH\n\
+  -p, --pause       pause at the beginning of each page until a newline\n\
+                    is read from standard input.\n\
   -r, --no-file-warnings\n\
                     omit warning when a file cannot be opened\n\
 "), stdout);
-- 
2.50.1