Subject: bug#47243: pr lacks -p

From: Collin Funk <[email-masked]>
Date: Sun, 27 Jul 2025 16:39:46 -0700

Collin Funk <[email-masked]> writes:

> I have attached the V2 patch [...]

Oops, forgotten patch attached here.

Collin

>From 6927ed786c87d0849f70e20459672fcff0d114bd Mon Sep 17 00:00:00 2001
Message-ID: <6927[email-masked]>
From: Collin Funk <[email-masked]>
Date: Sun, 27 Jul 2025 15:00:15 -0700
Subject: [PATCH v2] 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. Ignore it if stdin or stdout are not 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.
* NEWS: Mention the new option.
---
 NEWS               |  4 ++++
 doc/coreutils.texi |  9 +++++++++
 src/pr.c           | 29 +++++++++++++++++++++++++----
 3 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/NEWS b/NEWS
index 0b2be7116..3d0ee4b79 100644
--- a/NEWS
+++ b/NEWS
@@ -64,6 +64,10 @@ GNU coreutils NEWS                                    -*- outline -*-
   Iranian locale (fa_IR) and for the Ethiopian locale (am_ET), and also
   does so more consistently for the Thailand locale (th_TH.UTF-8).
 
+  pr now supports the -p option, to pause upon printing each page until
+  a newline character is read from standard input, as required by POSIX
+  Issue 6.  The corresponding long option is --pause.
+
 
 * Noteworthy changes in release 9.7 (2025-04-09) [stable]
 
diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index 7ca5b222c..0aa767ba7 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -2825,6 +2825,15 @@ @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.  This option is ignored unless both standard input and
+standard output are a tty.
+
 @item -r
 @itemx --no-file-warnings
 @opindex -r
diff --git a/src/pr.c b/src/pr.c
index e7081a059..10c3af276 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,9 @@ main (int argc, char **argv)
     error (EXIT_FAILURE, 0,
            _("cannot specify both printing across and printing in parallel"));
 
+  if (pause_option)
+    pause_option = isatty (STDOUT_FILENO) && isatty (STDIN_FILENO);
+
 /* Translate some old short options to new/long options.
    To meet downward compatibility with other UNIX pr utilities
    and some POSIX specifications. */
@@ -1147,7 +1157,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 +1646,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 +2843,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