mirror of
https://https.git.savannah.gnu.org/git/coreutils.git
synced 2026-01-26 15:29:07 +00:00
tail: fix handling of broken pipes with SIGPIPE ignored
* init.cfg (trap_sigpipe_or_skip_): A new function refactored from... * tests/misc/printf-surprise.sh: ...here. * tests/misc/seq-epipe.sh. Likewise. * src/tail.c (die_pipe): Ensure we exit upon sending SIGPIPE. * tests/tail-2/pipe-f.sh: Ensure we exit even if SIGPIPE is ignored. * NEWS: Mention the bug fix.
This commit is contained in:
parent
17983b2cb3
commit
fa50623394
4
NEWS
4
NEWS
@ -27,6 +27,10 @@ GNU coreutils NEWS -*- outline -*-
|
||||
'tail -f file | filter' no longer exits immediately on AIX.
|
||||
[bug introduced in coreutils-8.28]
|
||||
|
||||
'tail -f file | filter' no longer goes into an infinite loop
|
||||
if filter exits and SIGPIPE is ignored.
|
||||
[bug introduced in coreutils-8.28]
|
||||
|
||||
** Changes in behavior
|
||||
|
||||
echo now always processes backslash escapes when the POSIXLY_CORRECT
|
||||
|
||||
6
init.cfg
6
init.cfg
@ -610,6 +610,12 @@ mkfifo_or_skip_()
|
||||
fi
|
||||
}
|
||||
|
||||
trap_sigpipe_or_skip_()
|
||||
{
|
||||
(trap '' PIPE && yes | :) 2>&1 | grep -qF 'Broken pipe' ||
|
||||
skip_ 'trapping SIGPIPE is not supported'
|
||||
}
|
||||
|
||||
# Disable the current test if the working directory seems to have
|
||||
# the setgid bit set.
|
||||
skip_if_setgid_()
|
||||
|
||||
14
src/tail.c
14
src/tail.c
@ -334,6 +334,14 @@ named file in a way that accommodates renaming, removal and creation.\n\
|
||||
exit (status);
|
||||
}
|
||||
|
||||
/* Ensure exit, either with SIGPIPE or EXIT_FAILURE status. */
|
||||
static void ATTRIBUTE_NORETURN
|
||||
die_pipe (void)
|
||||
{
|
||||
raise (SIGPIPE);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* If the output has gone away, then terminate
|
||||
as we would if we had written to this output. */
|
||||
static void
|
||||
@ -349,7 +357,7 @@ check_output_alive (void)
|
||||
pfd.events = POLLERR;
|
||||
|
||||
if (poll (&pfd, 1, 0) >= 0 && (pfd.revents & POLLERR))
|
||||
raise (SIGPIPE);
|
||||
die_pipe ();
|
||||
#else
|
||||
struct timeval delay;
|
||||
delay.tv_sec = delay.tv_usec = 0;
|
||||
@ -361,7 +369,7 @@ check_output_alive (void)
|
||||
/* readable event on STDOUT is equivalent to POLLERR,
|
||||
and implies an error condition on output like broken pipe. */
|
||||
if (select (STDOUT_FILENO + 1, &rfd, NULL, NULL, &delay) == 1)
|
||||
raise (SIGPIPE);
|
||||
die_pipe ();
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1659,7 +1667,7 @@ tail_forever_inotify (int wd, struct File_spec *f, size_t n_files,
|
||||
{
|
||||
/* readable event on STDOUT is equivalent to POLLERR,
|
||||
and implies an error on output like broken pipe. */
|
||||
raise (SIGPIPE);
|
||||
die_pipe ();
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
@ -49,9 +49,7 @@ vm=$(get_min_ulimit_v_ env $prog %20f 0) \
|
||||
# triggering the printf(3) misbehavior -- which, btw, is required by ISO C99.
|
||||
|
||||
mkfifo_or_skip_ fifo
|
||||
|
||||
(trap '' PIPE && yes | :) 2>&1 | grep -qF 'Broken pipe' ||
|
||||
skip_ 'trapping SIGPIPE is not supported'
|
||||
trap_sigpipe_or_skip_
|
||||
|
||||
# Disable MALLOC_PERTURB_, to avoid triggering this bug
|
||||
# https://bugs.debian.org/481543#77
|
||||
|
||||
@ -18,9 +18,7 @@
|
||||
|
||||
. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
|
||||
print_ver_ seq
|
||||
|
||||
(trap '' PIPE && yes | :) 2>&1 | grep -qF 'Broken pipe' ||
|
||||
skip_ 'trapping SIGPIPE is not supported'
|
||||
trap_sigpipe_or_skip_
|
||||
|
||||
# upon EPIPE with signals ignored, 'seq' should exit with an error.
|
||||
timeout 10 sh -c \
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
|
||||
. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
|
||||
print_ver_ tail
|
||||
trap_sigpipe_or_skip_
|
||||
|
||||
# Speedup the non inotify case
|
||||
fastpoll='-s.1 --max-unchanged-stats=1'
|
||||
@ -36,11 +37,19 @@ echo bar | returns_ 1 \
|
||||
compare exp out || fail=1
|
||||
|
||||
# This would wait indefinitely before v8.28 due to no EPIPE being
|
||||
# generated due to no data written after the first small amount
|
||||
(returns_ 124 timeout 10 tail -n2 -f $mode $fastpoll out && touch timed_out) |
|
||||
sed 2q > out2
|
||||
test -e timed_out && fail=1
|
||||
compare exp out2 || fail=1
|
||||
# generated due to no data written after the first small amount.
|
||||
# Also check tail exits if SIGPIPE is being ignored.
|
||||
# Note 'trap - SIGPIPE' is ineffective if the initiating shell
|
||||
# has ignored SIGPIPE, but that's not the normal case.
|
||||
for disposition in '' '-'; do
|
||||
(trap "$disposition" PIPE;
|
||||
returns_ 124 timeout 10 \
|
||||
tail -n2 -f $mode $fastpoll out && touch timed_out) |
|
||||
sed 2q > out2
|
||||
test -e timed_out && fail=1
|
||||
compare exp out2 || fail=1
|
||||
rm -f timed_out
|
||||
done
|
||||
|
||||
# This would wait indefinitely before v8.28 (until first write)
|
||||
(returns_ 1 timeout 10 tail -f $mode $fastpoll /dev/null >&-) || fail=1
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user