1#!/bin/sh 2# Exercise an abort-inducing flaw in inotify-enabled tail -F. 3 4# Copyright (C) 2009-2023 Free Software Foundation, Inc. 5 6# This program is free software: you can redistribute it and/or modify 7# it under the terms of the GNU General Public License as published by 8# the Free Software Foundation, either version 3 of the License, or 9# (at your option) any later version. 10 11# This program is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15 16# You should have received a copy of the GNU General Public License 17# along with this program. If not, see <https://www.gnu.org/licenses/>. 18 19. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src 20print_ver_ tail 21 22# 9 is a magic number, related to internal details of tail.c and hash.c 23n=9 24seq $n | xargs touch || framework_failure_ 25 26check_tail_output() 27{ 28 local delay="$1" 29 grep "$tail_re" out > /dev/null || 30 { sleep $delay; return 1; } 31} 32 33# Terminate any background tail process 34cleanup_() { kill $pid 2>/dev/null && wait $pid; } 35 36# Speedup the non inotify case 37fastpoll='-s.1 --max-unchanged-stats=1' 38 39for mode in '' '---disable-inotify'; do 40 rm -f out 41 42 tail $mode $fastpoll -qF $(seq $n) > out 2>&1 & pid=$! 43 44 # Wait up to 12.7s for tail to start 45 echo x > $n 46 tail_re='^x$' retry_delay_ check_tail_output .1 7 || 47 { cat out; fail=1; } 48 49 mv 1 f || framework_failure_ 50 51 # Wait 12.7s for this diagnostic: 52 # tail: '1' has become inaccessible: No such file or directory 53 tail_re='inaccessible' retry_delay_ check_tail_output .1 7 || 54 { cat out; fail=1; } 55 56 # Trigger the bug. Before the fix, this would provoke the abort. 57 echo a > 1 || framework_failure_ 58 59 # Wait up to 6.3s for the "tail: '1' has appeared; ..." message 60 # (or for the buggy tail to die) 61 tail_re='has appeared' retry_delay_ check_tail_output .1 6 || 62 { cat out; fail=1; } 63 64 # Double check that tail hasn't aborted 65 kill -0 $pid || fail=1 66 67 cleanup_ 68done 69 70 71Exit $fail 72