1#!/bin/sh 2# inotify-based tail would output redundant headers for 3# overlapping inotify events while it was suspended 4 5# Copyright (C) 2017-2023 Free Software Foundation, Inc. 6 7# This program is free software: you can redistribute it and/or modify 8# it under the terms of the GNU General Public License as published by 9# the Free Software Foundation, either version 3 of the License, or 10# (at your option) any later version. 11 12# This program is distributed in the hope that it will be useful, 13# but WITHOUT ANY WARRANTY; without even the implied warranty of 14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15# GNU General Public License for more details. 16 17# You should have received a copy of the GNU General Public License 18# along with this program. If not, see <https://www.gnu.org/licenses/>. 19 20. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src 21print_ver_ tail sleep 22 23# Function to count number of lines from tail 24# while ignoring transient errors due to resource limits 25countlines_ () 26{ 27 grep -Ev 'inotify (resources exhausted|cannot be used)' out | wc -l 28} 29 30# Function to check the expected line count in 'out'. 31# Called via retry_delay_(). Sleep some time - see retry_delay_() - if the 32# line count is still smaller than expected. 33wait4lines_ () 34{ 35 local delay=$1 36 local elc=$2 # Expected line count. 37 [ "$(countlines_)" -ge "$elc" ] || { sleep $delay; return 1; } 38} 39 40# Speedup the non inotify case 41fastpoll='---dis -s.1 --max-unchanged-stats=1' 42 43# Terminate any background tail process 44cleanup_() { 45 kill $pid 2>/dev/null && wait $pid; 46 kill $sleep 2>/dev/null && wait $sleep 47} 48 49echo start > file1 || framework_failure_ 50echo start > file2 || framework_failure_ 51 52# Use this as a way to gracefully terminate tail 53env sleep 20 & sleep=$! 54 55tail $fastpoll --pid=$sleep -f file1 file2 > out & pid=$! 56 57kill -0 $pid || fail=1 58 59# Wait for 5 initial lines 60retry_delay_ wait4lines_ .1 6 5 || fail=1 61 62# Suspend tail so single read() caters for multiple inotify events 63kill -STOP $pid || fail=1 64 65# Interleave writes to files to generate overlapping inotify events 66echo line >> file1 || framework_failure_ 67echo line >> file2 || framework_failure_ 68echo line >> file1 || framework_failure_ 69echo line >> file2 || framework_failure_ 70 71# Resume tail processing 72kill -CONT $pid || fail=1 73 74# Wait for 8 more lines 75retry_delay_ wait4lines_ .1 6 13 || fail=1 76 77kill $sleep && wait || framework_failure_ 78 79test "$(countlines_)" = 13 || fail=1 80 81Exit $fail 82