Blame SOURCES/coreutils-8.30-tail-use-poll.patch

8cf838
From 95f427178720d047316e95f44777cfdf2ecf2b46 Mon Sep 17 00:00:00 2001
8cf838
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <P@draigBrady.com>
8cf838
Date: Fri, 4 Jan 2019 09:29:13 -0800
8cf838
Subject: [PATCH 1/4] tail: don't exit immediately with filters on AIX
8cf838
8cf838
* src/tail.c: Fix the check_output_available check on AIX.
8cf838
Note we don't use poll for all systems as the overhead
8cf838
of adding the gnulib poll module wouldn't be worth it
8cf838
just for this single use.
8cf838
* tests/tail-2/pipe-f.sh: Fix the test which always passed
8cf838
due to only the exit code of sleep being checked.
8cf838
* NEWS: Mention the bug fix and rearrange alphabetically.
8cf838
Fixes http://bugs.gnu.org/33946
8cf838
8cf838
Upstream-commit: d5ab4cbe424e3e95140eec22ef828f50b2fb3067
8cf838
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
8cf838
---
8cf838
 src/tail.c             | 13 +++++++++++++
8cf838
 tests/tail-2/pipe-f.sh |  5 ++++-
8cf838
 2 files changed, 17 insertions(+), 1 deletion(-)
8cf838
8cf838
diff --git a/src/tail.c b/src/tail.c
8cf838
index ac001d7..d63aacc 100644
8cf838
--- a/src/tail.c
8cf838
+++ b/src/tail.c
8cf838
@@ -30,6 +30,9 @@
8cf838
 #include <getopt.h>
8cf838
 #include <sys/types.h>
8cf838
 #include <signal.h>
8cf838
+#ifdef _AIX
8cf838
+# include <poll.h>
8cf838
+#endif
8cf838
 
8cf838
 #include "system.h"
8cf838
 #include "argmatch.h"
8cf838
@@ -335,6 +338,16 @@ named file in a way that accommodates renaming, removal and creation.\n\
8cf838
 static void
8cf838
 check_output_alive (void)
8cf838
 {
8cf838
+#ifdef _AIX
8cf838
+  /* select on AIX was seen to give a readable event immediately.  */
8cf838
+  struct pollfd pfd;
8cf838
+  pfd.fd = STDOUT_FILENO;
8cf838
+  pfd.events = POLLERR;
8cf838
+
8cf838
+  if (poll (&pfd, 1, 0) >= 0 && (pfd.revents & POLLERR))
8cf838
+    raise (SIGPIPE);
8cf838
+#endif
8cf838
+
8cf838
   if (! monitor_output)
8cf838
     return;
8cf838
 
8cf838
diff --git a/tests/tail-2/pipe-f.sh b/tests/tail-2/pipe-f.sh
8cf838
index 76b0d90..1126c93 100755
8cf838
--- a/tests/tail-2/pipe-f.sh
8cf838
+++ b/tests/tail-2/pipe-f.sh
8cf838
@@ -37,7 +37,10 @@ compare exp out || fail=1
8cf838
 
8cf838
 # This would wait indefinitely before v8.28 due to no EPIPE being
8cf838
 # generated due to no data written after the first small amount
8cf838
-timeout 10 tail -f $mode $fastpoll out | sleep .1 || fail=1
8cf838
+(returns_ 124 timeout 10 tail -n2 -f $mode $fastpoll out && touch timed_out) |
8cf838
+ sed 2q > out2
8cf838
+test -e timed_out && fail=1
8cf838
+compare exp out2 || fail=1
8cf838
 
8cf838
 # This would wait indefinitely before v8.28 (until first write)
8cf838
 (returns_ 1 timeout 10 tail -f $mode $fastpoll /dev/null >&-) || fail=1
8cf838
-- 
8cf838
2.31.1
8cf838
8cf838
8cf838
From 125bb79d3e9f414533b1c29237ee3f647053d0d6 Mon Sep 17 00:00:00 2001
8cf838
From: Ayappan <ayappap2@in.ibm.com>
8cf838
Date: Sun, 20 Jan 2019 00:17:33 -0800
8cf838
Subject: [PATCH 2/4] tail: fix recent ineffective AIX change
8cf838
8cf838
* src/tail.c: Fix commit v8.30-40-gd5ab4cb which was ineffective.
8cf838
Fixes http://bugs.gnu.org/33946
8cf838
8cf838
Upstream-commit: 17983b2cb3bccbb4fa69691178caddd99269bda9
8cf838
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
8cf838
---
8cf838
 src/tail.c | 10 +++++-----
8cf838
 1 file changed, 5 insertions(+), 5 deletions(-)
8cf838
8cf838
diff --git a/src/tail.c b/src/tail.c
8cf838
index d63aacc..9ed6d48 100644
8cf838
--- a/src/tail.c
8cf838
+++ b/src/tail.c
8cf838
@@ -338,6 +338,9 @@ named file in a way that accommodates renaming, removal and creation.\n\
8cf838
 static void
8cf838
 check_output_alive (void)
8cf838
 {
8cf838
+  if (! monitor_output)
8cf838
+    return;
8cf838
+
8cf838
 #ifdef _AIX
8cf838
   /* select on AIX was seen to give a readable event immediately.  */
8cf838
   struct pollfd pfd;
8cf838
@@ -346,11 +349,7 @@ check_output_alive (void)
8cf838
 
8cf838
   if (poll (&pfd, 1, 0) >= 0 && (pfd.revents & POLLERR))
8cf838
     raise (SIGPIPE);
8cf838
-#endif
8cf838
-
8cf838
-  if (! monitor_output)
8cf838
-    return;
8cf838
-
8cf838
+#else
8cf838
   struct timeval delay;
8cf838
   delay.tv_sec = delay.tv_usec = 0;
8cf838
 
8cf838
@@ -362,6 +361,7 @@ check_output_alive (void)
8cf838
      and implies an error condition on output like broken pipe.  */
8cf838
   if (select (STDOUT_FILENO + 1, &rfd, NULL, NULL, &delay) == 1)
8cf838
     raise (SIGPIPE);
8cf838
+#endif
8cf838
 }
8cf838
 
8cf838
 static bool
8cf838
-- 
8cf838
2.31.1
8cf838
8cf838
8cf838
From 7741989c3e633aa44f01d8f91332cb65a9280ba3 Mon Sep 17 00:00:00 2001
8cf838
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <P@draigBrady.com>
8cf838
Date: Sun, 20 Jan 2019 00:13:15 -0800
8cf838
Subject: [PATCH 3/4] tail: fix handling of broken pipes with SIGPIPE ignored
8cf838
8cf838
* init.cfg (trap_sigpipe_or_skip_): A new function refactored from...
8cf838
* tests/misc/printf-surprise.sh: ...here.
8cf838
* tests/misc/seq-epipe.sh. Likewise.
8cf838
* src/tail.c (die_pipe): Ensure we exit upon sending SIGPIPE.
8cf838
* tests/tail-2/pipe-f.sh: Ensure we exit even if SIGPIPE is ignored.
8cf838
* NEWS: Mention the bug fix.
8cf838
8cf838
Upstream-commit: fa50623394f491b975dbd7ad73193519dd721771
8cf838
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
8cf838
---
8cf838
 init.cfg                      |  6 ++++++
8cf838
 src/tail.c                    | 14 +++++++++++---
8cf838
 tests/misc/printf-surprise.sh |  4 +---
8cf838
 tests/misc/seq-epipe.sh       |  4 +---
8cf838
 tests/tail-2/pipe-f.sh        | 19 ++++++++++++++-----
8cf838
 5 files changed, 33 insertions(+), 14 deletions(-)
8cf838
8cf838
diff --git a/init.cfg b/init.cfg
8cf838
index b6c81ab..985c8d3 100644
8cf838
--- a/init.cfg
8cf838
+++ b/init.cfg
8cf838
@@ -613,6 +613,12 @@ mkfifo_or_skip_()
8cf838
   fi
8cf838
 }
8cf838
 
8cf838
+trap_sigpipe_or_skip_()
8cf838
+{
8cf838
+  (trap '' PIPE && yes | :) 2>&1 | grep -qF 'Broken pipe' ||
8cf838
+    skip_ 'trapping SIGPIPE is not supported'
8cf838
+}
8cf838
+
8cf838
 # Disable the current test if the working directory seems to have
8cf838
 # the setgid bit set.
8cf838
 skip_if_setgid_()
8cf838
diff --git a/src/tail.c b/src/tail.c
8cf838
index 9ed6d48..16e0d73 100644
8cf838
--- a/src/tail.c
8cf838
+++ b/src/tail.c
8cf838
@@ -333,6 +333,14 @@ named file in a way that accommodates renaming, removal and creation.\n\
8cf838
   exit (status);
8cf838
 }
8cf838
 
8cf838
+/* Ensure exit, either with SIGPIPE or EXIT_FAILURE status.  */
8cf838
+static void ATTRIBUTE_NORETURN
8cf838
+die_pipe (void)
8cf838
+{
8cf838
+  raise (SIGPIPE);
8cf838
+  exit (EXIT_FAILURE);
8cf838
+}
8cf838
+
8cf838
 /* If the output has gone away, then terminate
8cf838
    as we would if we had written to this output.  */
8cf838
 static void
8cf838
@@ -348,7 +356,7 @@ check_output_alive (void)
8cf838
   pfd.events = POLLERR;
8cf838
 
8cf838
   if (poll (&pfd, 1, 0) >= 0 && (pfd.revents & POLLERR))
8cf838
-    raise (SIGPIPE);
8cf838
+    die_pipe ();
8cf838
 #else
8cf838
   struct timeval delay;
8cf838
   delay.tv_sec = delay.tv_usec = 0;
8cf838
@@ -360,7 +368,7 @@ check_output_alive (void)
8cf838
   /* readable event on STDOUT is equivalent to POLLERR,
8cf838
      and implies an error condition on output like broken pipe.  */
8cf838
   if (select (STDOUT_FILENO + 1, &rfd, NULL, NULL, &delay) == 1)
8cf838
-    raise (SIGPIPE);
8cf838
+    die_pipe ();
8cf838
 #endif
8cf838
 }
8cf838
 
8cf838
@@ -1658,7 +1666,7 @@ tail_forever_inotify (int wd, struct File_spec *f, size_t n_files,
8cf838
              {
8cf838
                /* readable event on STDOUT is equivalent to POLLERR,
8cf838
                   and implies an error on output like broken pipe.  */
8cf838
-               raise (SIGPIPE);
8cf838
+               die_pipe ();
8cf838
              }
8cf838
            else
8cf838
              break;
8cf838
diff --git a/tests/misc/printf-surprise.sh b/tests/misc/printf-surprise.sh
8cf838
index fd88133..acac0b1 100755
8cf838
--- a/tests/misc/printf-surprise.sh
8cf838
+++ b/tests/misc/printf-surprise.sh
8cf838
@@ -49,9 +49,7 @@ vm=$(get_min_ulimit_v_ env $prog %20f 0) \
8cf838
 # triggering the printf(3) misbehavior -- which, btw, is required by ISO C99.
8cf838
 
8cf838
 mkfifo_or_skip_ fifo
8cf838
-
8cf838
-(trap '' PIPE && yes | :) 2>&1 | grep -qF 'Broken pipe' ||
8cf838
-    skip_ 'trapping SIGPIPE is not supported'
8cf838
+trap_sigpipe_or_skip_
8cf838
 
8cf838
 # Disable MALLOC_PERTURB_, to avoid triggering this bug
8cf838
 # https://bugs.debian.org/481543#77
8cf838
diff --git a/tests/misc/seq-epipe.sh b/tests/misc/seq-epipe.sh
8cf838
index 3e89158..127d61c 100755
8cf838
--- a/tests/misc/seq-epipe.sh
8cf838
+++ b/tests/misc/seq-epipe.sh
8cf838
@@ -18,9 +18,7 @@
8cf838
 
8cf838
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
8cf838
 print_ver_ seq
8cf838
-
8cf838
-(trap '' PIPE && yes | :) 2>&1 | grep -qF 'Broken pipe' ||
8cf838
-    skip_ 'trapping SIGPIPE is not supported'
8cf838
+trap_sigpipe_or_skip_
8cf838
 
8cf838
 # upon EPIPE with signals ignored, 'seq' should exit with an error.
8cf838
 timeout 10 sh -c \
8cf838
diff --git a/tests/tail-2/pipe-f.sh b/tests/tail-2/pipe-f.sh
8cf838
index 1126c93..f734a61 100755
8cf838
--- a/tests/tail-2/pipe-f.sh
8cf838
+++ b/tests/tail-2/pipe-f.sh
8cf838
@@ -18,6 +18,7 @@
8cf838
 
8cf838
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
8cf838
 print_ver_ tail
8cf838
+trap_sigpipe_or_skip_
8cf838
 
8cf838
 # Speedup the non inotify case
8cf838
 fastpoll='-s.1 --max-unchanged-stats=1'
8cf838
@@ -36,11 +37,19 @@ echo bar | returns_ 1 \
8cf838
 compare exp out || fail=1
8cf838
 
8cf838
 # This would wait indefinitely before v8.28 due to no EPIPE being
8cf838
-# generated due to no data written after the first small amount
8cf838
-(returns_ 124 timeout 10 tail -n2 -f $mode $fastpoll out && touch timed_out) |
8cf838
- sed 2q > out2
8cf838
-test -e timed_out && fail=1
8cf838
-compare exp out2 || fail=1
8cf838
+# generated due to no data written after the first small amount.
8cf838
+# Also check tail exits if SIGPIPE is being ignored.
8cf838
+# Note 'trap - SIGPIPE' is ineffective if the initiating shell
8cf838
+# has ignored SIGPIPE, but that's not the normal case.
8cf838
+for disposition in '' '-'; do
8cf838
+  (trap "$disposition" PIPE;
8cf838
+   returns_ 124 timeout 10 \
8cf838
+    tail -n2 -f $mode $fastpoll out && touch timed_out) |
8cf838
+  sed 2q > out2
8cf838
+  test -e timed_out && fail=1
8cf838
+  compare exp out2 || fail=1
8cf838
+  rm -f timed_out
8cf838
+done
8cf838
 
8cf838
 # This would wait indefinitely before v8.28 (until first write)
8cf838
 (returns_ 1 timeout 10 tail -f $mode $fastpoll /dev/null >&-) || fail=1
8cf838
-- 
8cf838
2.31.1
8cf838
8cf838
8cf838
From 0f5760466d167e955d28a1250ffd0af347d48dc9 Mon Sep 17 00:00:00 2001
8cf838
From: Paul Eggert <eggert@cs.ucla.edu>
8cf838
Date: Sat, 26 Jun 2021 18:23:52 -0700
8cf838
Subject: [PATCH 4/4] tail: use poll, not select
8cf838
MIME-Version: 1.0
8cf838
Content-Type: text/plain; charset=UTF-8
8cf838
Content-Transfer-Encoding: 8bit
8cf838
8cf838
This fixes an unlikely stack out-of-bounds write reported by
8cf838
Stepan Broz via Kamil Dudka (Bug#49209).
8cf838
* src/tail.c: Do not include <sys/select.h>.
8cf838
[!_AIX]: Include poll.h.
8cf838
(check_output_alive) [!_AIX]: Use poll instead of select.
8cf838
(tail_forever_inotify): Likewise.  Simplify logic, as there is no
8cf838
need for a ‘while (len <= evbuf_off)’ loop.
8cf838
8cf838
Upstream-commit: da0d448bca62c6305fc432f67e2c5ccc2da75346
8cf838
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
8cf838
---
8cf838
 src/tail.c | 101 +++++++++++++++++++++--------------------------------
8cf838
 1 file changed, 39 insertions(+), 62 deletions(-)
8cf838
8cf838
diff --git a/src/tail.c b/src/tail.c
8cf838
index 16e0d73..d77c660 100644
8cf838
--- a/src/tail.c
8cf838
+++ b/src/tail.c
8cf838
@@ -29,10 +29,8 @@
8cf838
 #include <assert.h>
8cf838
 #include <getopt.h>
8cf838
 #include <sys/types.h>
8cf838
+#include <poll.h>
8cf838
 #include <signal.h>
8cf838
-#ifdef _AIX
8cf838
-# include <poll.h>
8cf838
-#endif
8cf838
 
8cf838
 #include "system.h"
8cf838
 #include "argmatch.h"
8cf838
@@ -55,8 +53,6 @@
8cf838
 #if HAVE_INOTIFY
8cf838
 # include "hash.h"
8cf838
 # include <sys/inotify.h>
8cf838
-/* 'select' is used by tail_forever_inotify.  */
8cf838
-# include <sys/select.h>
8cf838
 
8cf838
 /* inotify needs to know if a file is local.  */
8cf838
 # include "fs.h"
8cf838
@@ -349,27 +345,12 @@ check_output_alive (void)
8cf838
   if (! monitor_output)
8cf838
     return;
8cf838
 
8cf838
-#ifdef _AIX
8cf838
-  /* select on AIX was seen to give a readable event immediately.  */
8cf838
   struct pollfd pfd;
8cf838
   pfd.fd = STDOUT_FILENO;
8cf838
   pfd.events = POLLERR;
8cf838
 
8cf838
   if (poll (&pfd, 1, 0) >= 0 && (pfd.revents & POLLERR))
8cf838
     die_pipe ();
8cf838
-#else
8cf838
-  struct timeval delay;
8cf838
-  delay.tv_sec = delay.tv_usec = 0;
8cf838
-
8cf838
-  fd_set rfd;
8cf838
-  FD_ZERO (&rfd;;
8cf838
-  FD_SET (STDOUT_FILENO, &rfd;;
8cf838
-
8cf838
-  /* readable event on STDOUT is equivalent to POLLERR,
8cf838
-     and implies an error condition on output like broken pipe.  */
8cf838
-  if (select (STDOUT_FILENO + 1, &rfd, NULL, NULL, &delay) == 1)
8cf838
-    die_pipe ();
8cf838
-#endif
8cf838
 }
8cf838
 
8cf838
 static bool
8cf838
@@ -1609,7 +1590,7 @@ tail_forever_inotify (int wd, struct File_spec *f, size_t n_files,
8cf838
   /* Wait for inotify events and handle them.  Events on directories
8cf838
      ensure that watched files can be re-added when following by name.
8cf838
      This loop blocks on the 'safe_read' call until a new event is notified.
8cf838
-     But when --pid=P is specified, tail usually waits via the select.  */
8cf838
+     But when --pid=P is specified, tail usually waits via poll.  */
8cf838
   while (1)
8cf838
     {
8cf838
       struct File_spec *fspec;
8cf838
@@ -1626,54 +1607,51 @@ tail_forever_inotify (int wd, struct File_spec *f, size_t n_files,
8cf838
           return false;
8cf838
         }
8cf838
 
8cf838
-      /* When watching a PID, ensure that a read from WD will not block
8cf838
-         indefinitely.  */
8cf838
-      while (len <= evbuf_off)
8cf838
+      if (len <= evbuf_off)
8cf838
         {
8cf838
-          struct timeval delay; /* how long to wait for file changes.  */
8cf838
+          /* Poll for inotify events.  When watching a PID, ensure
8cf838
+             that a read from WD will not block indefinitely.
8cf838
+             If MONITOR_OUTPUT, also poll for a broken output pipe.  */
8cf838
 
8cf838
-          if (pid)
8cf838
+          int file_change;
8cf838
+          struct pollfd pfd[2];
8cf838
+          do
8cf838
             {
8cf838
-              if (writer_is_dead)
8cf838
-                exit (EXIT_SUCCESS);
8cf838
+              /* How many ms to wait for changes.  -1 means wait forever.  */
8cf838
+              int delay = -1;
8cf838
 
8cf838
-              writer_is_dead = (kill (pid, 0) != 0 && errno != EPERM);
8cf838
-
8cf838
-              if (writer_is_dead)
8cf838
-                delay.tv_sec = delay.tv_usec = 0;
8cf838
-              else
8cf838
+              if (pid)
8cf838
                 {
8cf838
-                  delay.tv_sec = (time_t) sleep_interval;
8cf838
-                  delay.tv_usec = 1000000 * (sleep_interval - delay.tv_sec);
8cf838
+                  if (writer_is_dead)
8cf838
+                    exit (EXIT_SUCCESS);
8cf838
+
8cf838
+                  writer_is_dead = (kill (pid, 0) != 0 && errno != EPERM);
8cf838
+
8cf838
+                  if (writer_is_dead || sleep_interval <= 0)
8cf838
+                    delay = 0;
8cf838
+                  else if (sleep_interval < INT_MAX / 1000 - 1)
8cf838
+                    {
8cf838
+                      /* delay = ceil (sleep_interval * 1000), sans libm.  */
8cf838
+                      double ddelay = sleep_interval * 1000;
8cf838
+                      delay = ddelay;
8cf838
+                      delay += delay < ddelay;
8cf838
+                    }
8cf838
                 }
8cf838
+
8cf838
+              pfd[0].fd = wd;
8cf838
+              pfd[0].events = POLLIN;
8cf838
+              pfd[1].fd = STDOUT_FILENO;
8cf838
+              pfd[1].events = pfd[1].revents = 0;
8cf838
+              file_change = poll (pfd, monitor_output + 1, delay);
8cf838
             }
8cf838
+          while (file_change == 0);
8cf838
 
8cf838
-           fd_set rfd;
8cf838
-           FD_ZERO (&rfd;;
8cf838
-           FD_SET (wd, &rfd;;
8cf838
-           if (monitor_output)
8cf838
-             FD_SET (STDOUT_FILENO, &rfd;;
8cf838
-
8cf838
-           int file_change = select (MAX (wd, STDOUT_FILENO) + 1,
8cf838
-                                     &rfd, NULL, NULL, pid ? &delay: NULL);
8cf838
-
8cf838
-           if (file_change == 0)
8cf838
-             continue;
8cf838
-           else if (file_change == -1)
8cf838
-             die (EXIT_FAILURE, errno,
8cf838
-                  _("error waiting for inotify and output events"));
8cf838
-           else if (FD_ISSET (STDOUT_FILENO, &rfd))
8cf838
-             {
8cf838
-               /* readable event on STDOUT is equivalent to POLLERR,
8cf838
-                  and implies an error on output like broken pipe.  */
8cf838
-               die_pipe ();
8cf838
-             }
8cf838
-           else
8cf838
-             break;
8cf838
-        }
8cf838
+          if (file_change < 0)
8cf838
+            die (EXIT_FAILURE, errno,
8cf838
+                 _("error waiting for inotify and output events"));
8cf838
+          if (pfd[1].revents)
8cf838
+            die_pipe ();
8cf838
 
8cf838
-      if (len <= evbuf_off)
8cf838
-        {
8cf838
           len = safe_read (wd, evbuf, evlen);
8cf838
           evbuf_off = 0;
8cf838
 
8cf838
@@ -2434,8 +2412,7 @@ main (int argc, char **argv)
8cf838
   if (forever && ignore_fifo_and_pipe (F, n_files))
8cf838
     {
8cf838
       /* If stdout is a fifo or pipe, then monitor it
8cf838
-         so that we exit if the reader goes away.
8cf838
-         Note select() on a regular file is always readable.  */
8cf838
+         so that we exit if the reader goes away.  */
8cf838
       struct stat out_stat;
8cf838
       if (fstat (STDOUT_FILENO, &out_stat) < 0)
8cf838
         die (EXIT_FAILURE, errno, _("standard output"));
8cf838
-- 
8cf838
2.31.1
8cf838