summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorPádraig Brady <P@draigBrady.com>2009-10-01 08:36:25 +0100
committerPádraig Brady <P@draigBrady.com>2009-10-02 14:00:06 +0100
commitf8726e05c4ec1141fb3ffad1c9ec3838f59182cb (patch)
tree7153d27a45fb3d26b186473daf8443fc4654f377 /tests
parent95c01c656e061bccbab41fa651c99cb7041c9937 (diff)
downloadcoreutils-f8726e05c4ec1141fb3ffad1c9ec3838f59182cb.tar.xz
tail: avoid a race where we could miss new data with --pid
* src/tail.c (tail_forever, tail_forever_inotify): Close a race in tail_forever_inotify where new data written after the file check by a now dead process, but before the pid check, is not output. We use the POSIX guarantee that read() and write() are serialized wrt each other even in separate processes, to assume full file consistency after exit() and so poll for new data _after_ the writer has exited. This also allows us to not redundantly _wait_ for new data if the process is dead. * tests/tail-2/pid: Remove the now partially invalid sub second sleep check as we now don't unconditionally wait, and replace it with a check for the redundant sleep. Also clarify some of the existing comments. * NEWS: Mention the fix.
Diffstat (limited to 'tests')
-rwxr-xr-xtests/tail-2/pid15
1 files changed, 8 insertions, 7 deletions
diff --git a/tests/tail-2/pid b/tests/tail-2/pid
index 90f168430..760e289bc 100755
--- a/tests/tail-2/pid
+++ b/tests/tail-2/pid
@@ -29,26 +29,27 @@ touch here || framework_failure
fail=0
for inotify in ---disable-inotify ''; do
- # Use tail itself to create a background process to monitor.
+ # Use tail itself to create a background process to monitor,
+ # which will auto exit when "here" is removed.
tail -f $inotify here &
bg_pid=$!
# Ensure that tail --pid=PID does not exit when PID is alive.
- timeout 1 tail -s.1 -f $inotify here --pid=$bg_pid
+ timeout 1 tail -f -s.1 --pid=$bg_pid $inotify here
test $? = 124 || fail=1
# Cleanup background process
kill $bg_pid
- # Ensure that tail --pid=PID exits successfully when PID is dead.
+ # Ensure that tail --pid=PID exits with success status when PID is dead.
# Use an unlikely-to-be-live PID
- timeout 3 tail -s.1 --pid=$PID_T_MAX -f $inotify /dev/null
+ timeout 3 tail -f -s.1 --pid=$PID_T_MAX $inotify /dev/null
ret=$?
- test $ret = 124 && skip_test_ "pid $PID_T_MAX present"
+ test $ret = 124 && skip_test_ "pid $PID_T_MAX present or tail too slow"
test $ret = 0 || fail=1
- # Ensure fractional sleep parameter is honored with --pid
- timeout 3 tail -s.1 -f $inotify /dev/null --pid=$PID_T_MAX
+ # Ensure tail doesn't wait for data when PID is dead
+ timeout 3 tail -f -s10 --pid=$PID_T_MAX $inotify /dev/null
test $? = 124 && fail=1
done