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