xref: /titanic_41/usr/src/cmd/tail/tests/tailtests.sh (revision 1a95defd9ad2425f3c74030860dd9eb24a3e7930)
1209e49b2SChris Love#!/bin/bash
2209e49b2SChris Love#
3209e49b2SChris Love#
4209e49b2SChris Love# This file and its contents are supplied under the terms of the
5209e49b2SChris Love# Common Development and Distribution License ("CDDL"), version 1.0.
6209e49b2SChris Love# You may only use this file in accordance with the terms of version
7209e49b2SChris Love# 1.0 of the CDDL.
8209e49b2SChris Love#
9209e49b2SChris Love# A full copy of the text of the CDDL should have accompanied this
10209e49b2SChris Love# source.  A copy is of the CDDL is also available via the Internet
11209e49b2SChris Love# at http://www.illumos.org/license/CDDL.
12209e49b2SChris Love#
13209e49b2SChris Love
14209e49b2SChris Love#
15209e49b2SChris Love# Copyright 2010 Chris Love.  All rights reserved.
16*4461a296SBryan Cantrill# Copyright (c) 2013, Joyent, Inc. All rights reserved.
17209e49b2SChris Love#
18209e49b2SChris Love
19*4461a296SBryan Cantrillchecktest()
20*4461a296SBryan Cantrill{
21*4461a296SBryan Cantrill	local actual=$1
22*4461a296SBryan Cantrill	local output=$2
23*4461a296SBryan Cantrill	local test=$3
24*4461a296SBryan Cantrill
25*4461a296SBryan Cantrill	if [[ "$actual" != "$output" ]]; then
26*4461a296SBryan Cantrill		echo "$CMD: test $test: FAIL"
27*4461a296SBryan Cantrill		echo -e "$CMD: test $test: expected output:\n$output"
28*4461a296SBryan Cantrill		echo -e "$CMD: test $test: actual output:\n$actual"
29*4461a296SBryan Cantrill	else
30*4461a296SBryan Cantrill		echo "$CMD: test $test: pass"
31*4461a296SBryan Cantrill	fi
32*4461a296SBryan Cantrill}
33209e49b2SChris Love
34209e49b2SChris Love#
35209e49b2SChris Love# Test cases for 'tail', some based on CoreUtils test cases (validated
36*4461a296SBryan Cantrill# with legacy Solaris 'tail' and/or xpg4 'tail').  Note that this is designed
37*4461a296SBryan Cantrill# to be able to run on BSD systems as well to check our behavior against
38*4461a296SBryan Cantrill# theirs (some behavior that is known to be idiosyncratic to illumos is
39*4461a296SBryan Cantrill# skipped on non-illumos systems).
40209e49b2SChris Love#
41209e49b2SChris LovePROG=/usr/bin/tail
42*4461a296SBryan CantrillCMD=`basename $0`
43*4461a296SBryan CantrillDIR=""
44209e49b2SChris Love
45*4461a296SBryan Cantrillwhile [[ $# -gt 0 ]]; do
46209e49b2SChris Love	case $1 in
47209e49b2SChris Love	    -x)
48209e49b2SChris Love		PROG=/usr/xpg4/bin/tail
49*4461a296SBryan Cantrill		shift
50209e49b2SChris Love		;;
51209e49b2SChris Love	    -o)
52209e49b2SChris Love		PROG=$2
53*4461a296SBryan Cantrill		shift 2
54209e49b2SChris Love		;;
55*4461a296SBryan Cantrill	    -d)
56*4461a296SBryan Cantrill		DIR=$2
57*4461a296SBryan Cantrill		shift 2
58*4461a296SBryan Cantrill		;;
59*4461a296SBryan Cantrill	    *)
60*4461a296SBryan Cantrill		echo "Usage: tailtests.sh" \
61*4461a296SBryan Cantrill		    "[-x][-o <override tail executable>]" \
62*4461a296SBryan Cantrill		    "[-d <override output directory>]"
63209e49b2SChris Love		exit 1
64209e49b2SChris Love		;;
65209e49b2SChris Love	esac
66*4461a296SBryan Cantrilldone
67209e49b2SChris Love
68*4461a296SBryan Cantrill#
69*4461a296SBryan Cantrill# Shut bash up upon receiving a term so we can drop it on our children
70*4461a296SBryan Cantrill# without disrupting the output.
71*4461a296SBryan Cantrill#
72*4461a296SBryan Cantrilltrap "exit 0" TERM
73*4461a296SBryan Cantrill
74*4461a296SBryan Cantrillecho "$CMD: program is $PROG"
75*4461a296SBryan Cantrill
76*4461a296SBryan Cantrillif [[ $DIR != "" ]]; then
77*4461a296SBryan Cantrill	echo "$CMD: directory is $DIR"
78*4461a296SBryan Cantrillfi
79209e49b2SChris Love
80209e49b2SChris Loveo=`echo -e "bcd"`
81209e49b2SChris Lovea=`echo -e "abcd" | $PROG +2c`
82*4461a296SBryan Cantrillchecktest "$a" "$o" 1
83209e49b2SChris Love
84209e49b2SChris Loveo=`echo -e ""`
85209e49b2SChris Lovea=`echo "abcd" | $PROG +8c`
86*4461a296SBryan Cantrillchecktest "$a" "$o" 2
87209e49b2SChris Love
88209e49b2SChris Loveo=`echo -e "abcd"`
89209e49b2SChris Lovea=`echo "abcd" | $PROG -9c`
90*4461a296SBryan Cantrillchecktest "$a" "$o" 3
91209e49b2SChris Love
92209e49b2SChris Loveo=`echo -e "x"`
93209e49b2SChris Lovea=`echo -e "x" | $PROG -1l`
94*4461a296SBryan Cantrillchecktest "$a" "$o" 4
95209e49b2SChris Love
96209e49b2SChris Loveo=`echo -e "\n"`
97209e49b2SChris Lovea=`echo -e "x\ny\n" | $PROG -1l`
98*4461a296SBryan Cantrillchecktest "$a" "$o" 5
99209e49b2SChris Love
100209e49b2SChris Loveo=`echo -e "y\n"`
101209e49b2SChris Lovea=`echo -e "x\ny\n" | $PROG -2l`
102*4461a296SBryan Cantrillchecktest "$a" "$o" 6
103209e49b2SChris Love
104209e49b2SChris Loveo=`echo -e "y"`
105209e49b2SChris Lovea=`echo -e "x\ny" | $PROG -1l`
106*4461a296SBryan Cantrillchecktest "$a" "$o" 7
107209e49b2SChris Love
108209e49b2SChris Loveo=`echo -e "x\ny\n"`
109209e49b2SChris Lovea=`echo -e "x\ny\n" | $PROG +1l`
110*4461a296SBryan Cantrillchecktest "$a" "$o" 8
111209e49b2SChris Love
112209e49b2SChris Loveo=`echo -e "y\n"`
113209e49b2SChris Lovea=`echo -e "x\ny\n" | $PROG +2l`
114*4461a296SBryan Cantrillchecktest "$a" "$o" 9
115209e49b2SChris Love
116209e49b2SChris Loveo=`echo -e "x"`
117209e49b2SChris Lovea=`echo -e "x" | $PROG -1`
118*4461a296SBryan Cantrillchecktest "$a" "$o" 10
119209e49b2SChris Love
120209e49b2SChris Loveo=`echo -e "\n"`
121209e49b2SChris Lovea=`echo -e "x\ny\n" | $PROG -1`
122*4461a296SBryan Cantrillchecktest "$a" "$o" 11
123209e49b2SChris Love
124209e49b2SChris Loveo=`echo -e "y\n"`
125209e49b2SChris Lovea=`echo -e "x\ny\n" | $PROG -2`
126*4461a296SBryan Cantrillchecktest "$a" "$o" 12
127209e49b2SChris Love
128209e49b2SChris Loveo=`echo -e "y"`
129209e49b2SChris Lovea=`echo -e "x\ny" | $PROG -1`
130*4461a296SBryan Cantrillchecktest "$a" "$o" 13
131209e49b2SChris Love
132209e49b2SChris Loveo=`echo -e "x\ny\n"`
133209e49b2SChris Lovea=`echo -e "x\ny\n" | $PROG +1`
134*4461a296SBryan Cantrillchecktest "$a" "$o" 14
135209e49b2SChris Love
136209e49b2SChris Loveo=`echo -e "y\n"`
137209e49b2SChris Lovea=`echo -e "x\ny\n" | $PROG +2`
138*4461a296SBryan Cantrillchecktest "$a" "$o" 15
139209e49b2SChris Love
140209e49b2SChris Loveo=`echo -e "yyz"`
141209e49b2SChris Lovea=`echo -e "xyyyyyyyyyyz" | $PROG +10c`
142*4461a296SBryan Cantrillchecktest "$a" "$o" 16
143209e49b2SChris Love
144209e49b2SChris Loveo=`echo -e "y\ny\nz"`
145209e49b2SChris Lovea=`echo -e "x\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\nz" | $PROG +10l`
146*4461a296SBryan Cantrillchecktest "$a" "$o" 17
147*4461a296SBryan Cantrill
148*4461a296SBryan Cantrillo=`echo -e "y\ny\ny\ny\ny\ny\ny\ny\ny\nz"`
149*4461a296SBryan Cantrilla=`echo -e "x\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\nz" | $PROG -10l`
150*4461a296SBryan Cantrillchecktest "$a" "$o" 18
151*4461a296SBryan Cantrill
152*4461a296SBryan Cantrill#
153*4461a296SBryan Cantrill# For reasons that are presumably as accidental as they are ancient, legacy
154*4461a296SBryan Cantrill# (and closed) Solaris tail(1) allows +c, +l and -l to be aliases for +10c,
155*4461a296SBryan Cantrill# +10l and -10l, respectively.  If we are on SunOS, verify that this silly
156*4461a296SBryan Cantrill# behavior is functional.
157*4461a296SBryan Cantrill#
158*4461a296SBryan Cantrillif [[ `uname -s` == "SunOS" ]]; then
159*4461a296SBryan Cantrill	o=`echo -e "yyz"`
160*4461a296SBryan Cantrill	a=`echo -e "xyyyyyyyyyyz" | $PROG +c`
161*4461a296SBryan Cantrill	checktest "$a" "$o" 16a
162209e49b2SChris Love
163209e49b2SChris Love	o=`echo -e "y\ny\nz"`
164209e49b2SChris Love	a=`echo -e "x\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\nz" | $PROG +l`
165*4461a296SBryan Cantrill	checktest "$a" "$o" 17a
166209e49b2SChris Love
167209e49b2SChris Love	o=`echo -e "y\ny\ny\ny\ny\ny\ny\ny\ny\nz"`
168209e49b2SChris Love	a=`echo -e "x\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\nz" | $PROG -l`
169*4461a296SBryan Cantrill	checktest "$a" "$o" 18a
170*4461a296SBryan Cantrillfi
171209e49b2SChris Love
172209e49b2SChris Loveo=`echo -e "c\nb\na"`
173209e49b2SChris Lovea=`echo -e "a\nb\nc" | $PROG -r`
174*4461a296SBryan Cantrillchecktest "$a" "$o" 19
175209e49b2SChris Love
176*4461a296SBryan Cantrill#
177*4461a296SBryan Cantrill# Now we want to do a series of follow tests.
178*4461a296SBryan Cantrill#
179*4461a296SBryan Cantrillif [[ $DIR == "" ]]; then
180*4461a296SBryan Cantrill	export TMPDIR=/var/tmp
181*4461a296SBryan Cantrill	tdir=$(mktemp -d -t tailtest.XXXXXXXX || exit 1)
182*4461a296SBryan Cantrillelse
183*4461a296SBryan Cantrill	tdir=$(mktemp -d $DIR/tailtest.XXXXXXXX || exit 1)
184*4461a296SBryan Cantrillfi
185209e49b2SChris Love
186*4461a296SBryan Cantrillfollow=$tdir/follow
187*4461a296SBryan Cantrillmoved=$tdir/follow.moved
188*4461a296SBryan Cantrillout=$tdir/out
189209e49b2SChris Love
190*4461a296SBryan Cantrill#
191*4461a296SBryan Cantrill# First, verify that following works in its most basic sense.
192*4461a296SBryan Cantrill#
193*4461a296SBryan Cantrillecho -e "a\nb\nc" > $follow
194*4461a296SBryan Cantrill$PROG -f $follow > $out 2> /dev/null &
195*4461a296SBryan Cantrillchild=$!
196*4461a296SBryan Cantrillsleep 2
197*4461a296SBryan Cantrillecho -e "d\ne\nf" >> $follow
198*4461a296SBryan Cantrillsleep 1
199*4461a296SBryan Cantrillkill $child
200*4461a296SBryan Cantrillsleep 1
201209e49b2SChris Love
202*4461a296SBryan Cantrillo=`echo -e "a\nb\nc\nd\ne\nf\n"`
203*4461a296SBryan Cantrilla=`cat $out`
204*4461a296SBryan Cantrillchecktest "$a" "$o" 20
205*4461a296SBryan Cantrillrm $follow
206*4461a296SBryan Cantrill
207*4461a296SBryan Cantrill#
208*4461a296SBryan Cantrill# Now verify that following correctly follows the file being moved.
209*4461a296SBryan Cantrill#
210*4461a296SBryan Cantrillecho -e "a\nb\nc" > $follow
211*4461a296SBryan Cantrill$PROG -f $follow > $out 2> /dev/null &
212*4461a296SBryan Cantrillchild=$!
213*4461a296SBryan Cantrillsleep 2
214*4461a296SBryan Cantrillmv $follow $moved
215*4461a296SBryan Cantrill
216*4461a296SBryan Cantrillecho -e "d\ne\nf" >> $moved
217*4461a296SBryan Cantrillsleep 1
218*4461a296SBryan Cantrillkill $child
219*4461a296SBryan Cantrillsleep 1
220*4461a296SBryan Cantrill
221*4461a296SBryan Cantrillo=`echo -e "a\nb\nc\nd\ne\nf\n"`
222*4461a296SBryan Cantrilla=`cat $out`
223*4461a296SBryan Cantrillchecktest "$a" "$o" 21
224*4461a296SBryan Cantrillrm $moved
225*4461a296SBryan Cantrill
226*4461a296SBryan Cantrill#
227*4461a296SBryan Cantrill# And now truncation with the new offset being less than the old offset.
228*4461a296SBryan Cantrill#
229*4461a296SBryan Cantrillecho -e "a\nb\nc" > $follow
230*4461a296SBryan Cantrill$PROG -f $follow > $out 2> /dev/null &
231*4461a296SBryan Cantrillchild=$!
232*4461a296SBryan Cantrillsleep 2
233*4461a296SBryan Cantrillecho -e "d\ne\nf" >> $follow
234*4461a296SBryan Cantrillsleep 1
235*4461a296SBryan Cantrillecho -e "g\nh\ni" > $follow
236*4461a296SBryan Cantrillsleep 1
237*4461a296SBryan Cantrillkill $child
238*4461a296SBryan Cantrillsleep 1
239*4461a296SBryan Cantrill
240*4461a296SBryan Cantrillo=`echo -e "a\nb\nc\nd\ne\nf\ng\nh\ni\n"`
241*4461a296SBryan Cantrilla=`cat $out`
242*4461a296SBryan Cantrillchecktest "$a" "$o" 22
243*4461a296SBryan Cantrillrm $follow
244*4461a296SBryan Cantrill
245*4461a296SBryan Cantrill#
246*4461a296SBryan Cantrill# And truncation with the new offset being greater than the old offset.
247*4461a296SBryan Cantrill#
248*4461a296SBryan Cantrillecho -e "a\nb\nc" > $follow
249*4461a296SBryan Cantrillsleep 1
250*4461a296SBryan Cantrill$PROG -f $follow > $out 2> /dev/null &
251*4461a296SBryan Cantrillchild=$!
252*4461a296SBryan Cantrillsleep 2
253*4461a296SBryan Cantrillecho -e "d\ne\nf" >> $follow
254*4461a296SBryan Cantrillsleep 1
255*4461a296SBryan Cantrillecho -e "g\nh\ni\nj\nk\nl\nm\no\np\nq" > $follow
256*4461a296SBryan Cantrillsleep 1
257*4461a296SBryan Cantrillkill $child
258*4461a296SBryan Cantrillsleep 1
259*4461a296SBryan Cantrill
260*4461a296SBryan Cantrillo=`echo -e "a\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\no\np\nq"`
261*4461a296SBryan Cantrilla=`cat $out`
262*4461a296SBryan Cantrillchecktest "$a" "$o" 23
263*4461a296SBryan Cantrillrm $follow
264*4461a296SBryan Cantrill
265*4461a296SBryan Cantrill#
266*4461a296SBryan Cantrill# Verify that we can follow the moved file and correctly see a truncation.
267*4461a296SBryan Cantrill#
268*4461a296SBryan Cantrillecho -e "a\nb\nc" > $follow
269*4461a296SBryan Cantrill$PROG -f $follow > $out 2> /dev/null &
270*4461a296SBryan Cantrillchild=$!
271*4461a296SBryan Cantrillsleep 2
272*4461a296SBryan Cantrillmv $follow $moved
273*4461a296SBryan Cantrill
274*4461a296SBryan Cantrillecho -e "d\ne\nf" >> $moved
275*4461a296SBryan Cantrillsleep 1
276*4461a296SBryan Cantrillecho -e "g\nh\ni\nj\nk\nl\nm\no\np\nq" > $moved
277*4461a296SBryan Cantrillsleep 1
278*4461a296SBryan Cantrillkill $child
279*4461a296SBryan Cantrillsleep 1
280*4461a296SBryan Cantrill
281*4461a296SBryan Cantrillo=`echo -e "a\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\no\np\nq"`
282*4461a296SBryan Cantrilla=`cat $out`
283*4461a296SBryan Cantrillchecktest "$a" "$o" 24
284*4461a296SBryan Cantrillrm $moved
285*4461a296SBryan Cantrill
286*4461a296SBryan Cantrill#
287*4461a296SBryan Cantrill# Verify that capital-F follow properly deals with truncation
288*4461a296SBryan Cantrill#
289*4461a296SBryan Cantrillecho -e "a\nb\nc" > $follow
290*4461a296SBryan Cantrill$PROG -F $follow > $out 2> /dev/null &
291*4461a296SBryan Cantrillchild=$!
292*4461a296SBryan Cantrillsleep 2
293*4461a296SBryan Cantrillecho -e "d\ne\nf" >> $follow
294*4461a296SBryan Cantrillsleep 1
295*4461a296SBryan Cantrillecho -e "g\nh\ni" > $follow
296*4461a296SBryan Cantrillsleep 1
297*4461a296SBryan Cantrillkill $child
298*4461a296SBryan Cantrillsleep 1
299*4461a296SBryan Cantrill
300*4461a296SBryan Cantrillo=`echo -e "a\nb\nc\nd\ne\nf\ng\nh\ni\n"`
301*4461a296SBryan Cantrilla=`cat $out`
302*4461a296SBryan Cantrillchecktest "$a" "$o" 25
303*4461a296SBryan Cantrillrm $follow
304*4461a296SBryan Cantrill
305*4461a296SBryan Cantrill#
306*4461a296SBryan Cantrill# Verify that capital-F follow _won't_ follow the moved file and will
307*4461a296SBryan Cantrill# correctly deal with recreation of the original file.
308*4461a296SBryan Cantrill#
309*4461a296SBryan Cantrillecho -e "a\nb\nc" > $follow
310*4461a296SBryan Cantrill$PROG -F $follow > $out 2> /dev/null &
311*4461a296SBryan Cantrillchild=$!
312*4461a296SBryan Cantrillsleep 2
313*4461a296SBryan Cantrillmv $follow $moved
314*4461a296SBryan Cantrill
315*4461a296SBryan Cantrillecho -e "x\ny\nz" >> $moved
316*4461a296SBryan Cantrill
317*4461a296SBryan Cantrill#
318*4461a296SBryan Cantrill# At this point, tail is polling on stat'ing the missing file; we need to
319*4461a296SBryan Cantrill# be sure to sleep long enough after recreating it to know that it will pick
320*4461a296SBryan Cantrill# it up.
321*4461a296SBryan Cantrill#
322*4461a296SBryan Cantrillecho -e "d\ne\nf" > $follow
323*4461a296SBryan Cantrillsleep 5
324*4461a296SBryan Cantrillkill $child
325*4461a296SBryan Cantrillsleep 1
326*4461a296SBryan Cantrill
327*4461a296SBryan Cantrillo=`echo -e "a\nb\nc\nd\ne\nf\n"`
328*4461a296SBryan Cantrilla=`cat $out`
329*4461a296SBryan Cantrillchecktest "$a" "$o" 26
330*4461a296SBryan Cantrillrm $moved
331*4461a296SBryan Cantrill
332*4461a296SBryan Cantrill#
333*4461a296SBryan Cantrill# Verify that following two files works.
334*4461a296SBryan Cantrill#
335*4461a296SBryan Cantrillecho -e "one" > $follow
336*4461a296SBryan Cantrillecho -e "two" > $moved
337*4461a296SBryan Cantrill$PROG -f $follow $moved > $out 2> /dev/null &
338*4461a296SBryan Cantrillchild=$!
339*4461a296SBryan Cantrillsleep 2
340*4461a296SBryan Cantrillecho -e "three" >> $follow
341*4461a296SBryan Cantrillsleep 1
342*4461a296SBryan Cantrillecho -e "four" >> $moved
343*4461a296SBryan Cantrillsleep 1
344*4461a296SBryan Cantrillecho -e "five" >> $follow
345*4461a296SBryan Cantrillsleep 1
346*4461a296SBryan Cantrillkill $child
347*4461a296SBryan Cantrillsleep 1
348*4461a296SBryan Cantrill
349*4461a296SBryan Cantrill# There is a bug where the content comes before the header lines,
350*4461a296SBryan Cantrill# where rlines/mapprint happens before the header.  A pain to fix.
351*4461a296SBryan Cantrill# In this test, just make sure we see both files change.
352*4461a296SBryan Cantrillo="one
353*4461a296SBryan Cantrill
354*4461a296SBryan Cantrill==> $follow <==
355*4461a296SBryan Cantrilltwo
356*4461a296SBryan Cantrill
357*4461a296SBryan Cantrill==> $moved <==
358*4461a296SBryan Cantrill
359*4461a296SBryan Cantrill==> $follow <==
360*4461a296SBryan Cantrillthree
361*4461a296SBryan Cantrill
362*4461a296SBryan Cantrill==> $moved <==
363*4461a296SBryan Cantrillfour
364*4461a296SBryan Cantrill
365*4461a296SBryan Cantrill==> $follow <==
366*4461a296SBryan Cantrillfive"
367*4461a296SBryan Cantrilla=`cat $out`
368*4461a296SBryan Cantrillchecktest "$a" "$o" 27
369*4461a296SBryan Cantrillrm $follow $moved
370*4461a296SBryan Cantrill
371*4461a296SBryan Cantrillif [[ `uname -s` == "SunOS" ]]; then
372*4461a296SBryan Cantrill	#
373*4461a296SBryan Cantrill	# Use DTrace to truncate the file between the return from port_get()
374*4461a296SBryan Cantrill	# and the reassociation of the file object with the port, exposing
375*4461a296SBryan Cantrill	# any race conditions whereby FILE_TRUNC events are lost.
376*4461a296SBryan Cantrill	#
377*4461a296SBryan Cantrill	cat /dev/null > $follow
378*4461a296SBryan Cantrill	dtrace -c "$PROG -f $follow" -s /dev/stdin > $out <<EOF
379*4461a296SBryan Cantrill		#pragma D option destructive
380*4461a296SBryan Cantrill		#pragma D option quiet 
381*4461a296SBryan Cantrill
382*4461a296SBryan Cantrill		pid\$target::port_get:return
383*4461a296SBryan Cantrill		/++i == 5/
384*4461a296SBryan Cantrill		{
385*4461a296SBryan Cantrill			stop();
386*4461a296SBryan Cantrill			system("cat /dev/null > $follow");
387*4461a296SBryan Cantrill			system("prun %d", pid);
388*4461a296SBryan Cantrill		}
389*4461a296SBryan Cantrill
390*4461a296SBryan Cantrill		tick-1sec
391*4461a296SBryan Cantrill		{
392*4461a296SBryan Cantrill			system("echo %d >> $follow", j++);
393*4461a296SBryan Cantrill		}
394*4461a296SBryan Cantrill
395*4461a296SBryan Cantrill		tick-1sec
396*4461a296SBryan Cantrill		/j == 10/
397*4461a296SBryan Cantrill		{
398*4461a296SBryan Cantrill			exit(0);
399*4461a296SBryan Cantrill		}
400*4461a296SBryan CantrillEOF
401*4461a296SBryan Cantrill
402*4461a296SBryan Cantrill	o=`echo -e "0\n1\n2\n3\n5\n6\n7\n8\n9\n"`
403*4461a296SBryan Cantrill	a=`cat $out`
404*4461a296SBryan Cantrill	checktest "$a" "$o" 27a
405*4461a296SBryan Cantrill	rm $follow
406*4461a296SBryan Cantrill
407*4461a296SBryan Cantrill	cat /dev/null > $follow
408*4461a296SBryan Cantrill	dtrace -c "$PROG -f $follow" -s /dev/stdin > $out <<EOF
409*4461a296SBryan Cantrill		#pragma D option destructive
410*4461a296SBryan Cantrill		#pragma D option quiet 
411*4461a296SBryan Cantrill
412*4461a296SBryan Cantrill		pid\$target::port_get:return
413*4461a296SBryan Cantrill		/++i == 5/
414*4461a296SBryan Cantrill		{
415*4461a296SBryan Cantrill			stop();
416*4461a296SBryan Cantrill			system("mv $follow $moved");
417*4461a296SBryan Cantrill			system("cat /dev/null > $moved");
418*4461a296SBryan Cantrill			system("prun %d", pid);
419*4461a296SBryan Cantrill		}
420*4461a296SBryan Cantrill
421*4461a296SBryan Cantrill		tick-1sec
422*4461a296SBryan Cantrill		{
423*4461a296SBryan Cantrill			system("echo %d >> %s", j++,
424*4461a296SBryan Cantrill			    i < 5 ? "$follow" : "$moved");
425*4461a296SBryan Cantrill		}
426*4461a296SBryan Cantrill
427*4461a296SBryan Cantrill		tick-1sec
428*4461a296SBryan Cantrill		/j == 10/
429*4461a296SBryan Cantrill		{
430*4461a296SBryan Cantrill			exit(0);
431*4461a296SBryan Cantrill		}
432*4461a296SBryan CantrillEOF
433*4461a296SBryan Cantrill
434*4461a296SBryan Cantrill	o=`echo -e "0\n1\n2\n3\n5\n6\n7\n8\n9\n"`
435*4461a296SBryan Cantrill	a=`cat $out`
436*4461a296SBryan Cantrill	checktest "$a" "$o" 27b
437*4461a296SBryan Cantrill	rm $moved
438*4461a296SBryan Cantrill
439*4461a296SBryan Cantrill	#
440*4461a296SBryan Cantrill	# Verify that -F will deal properly with the file being truncated
441*4461a296SBryan Cantrill	# not by truncation, but rather via an ftruncate() from logadm.
442*4461a296SBryan Cantrill	#
443*4461a296SBryan Cantrill	cat /dev/null > $follow
444*4461a296SBryan Cantrill	( $PROG -F $follow > $out ) &
445*4461a296SBryan Cantrill	child=$!
446*4461a296SBryan Cantrill	echo -e "a\nb\nc\nd\ne\nf" >> $follow
447*4461a296SBryan Cantrill	logadm -c $follow
448*4461a296SBryan Cantrill	sleep 2
449*4461a296SBryan Cantrill	echo -e "g\nh\ni" >> $follow
450*4461a296SBryan Cantrill	sleep 2
451*4461a296SBryan Cantrill	kill $child
452*4461a296SBryan Cantrill	sleep 1
453*4461a296SBryan Cantrill
454*4461a296SBryan Cantrill	o=`echo -e "a\nb\nc\nd\ne\nf\ng\nh\ni\n"`
455*4461a296SBryan Cantrill	a=`cat $out`
456*4461a296SBryan Cantrill	checktest "$a" "$o" 27c
457*4461a296SBryan Cantrillfi
458*4461a296SBryan Cantrill
459*4461a296SBryan Cantrill#
460*4461a296SBryan Cantrill# We're now going to test that while we may miss output due to truncations
461*4461a296SBryan Cantrill# occurring faster than tail can read, we don't ever repeat output.
462*4461a296SBryan Cantrill#
463*4461a296SBryan Cantrillcat /dev/null > $follow
464*4461a296SBryan Cantrill( $PROG -f $follow > $out ) &
465*4461a296SBryan Cantrilltchild=$!
466*4461a296SBryan Cantrill( let i=0 ; while true; do echo $i > $follow ; sleep 0.1; let i=i+1 ; done ) &
467*4461a296SBryan Cantrillchild=$!
468*4461a296SBryan Cantrillsleep 10
469*4461a296SBryan Cantrillkill $tchild
470*4461a296SBryan Cantrillkill $child
471*4461a296SBryan Cantrill
472*4461a296SBryan Cantrilla=`sort $out | uniq -c | sort -n | tail -1 | awk '{ print $1 }'`
473*4461a296SBryan Cantrillo=1
474*4461a296SBryan Cantrill
475*4461a296SBryan Cantrillchecktest "$a" "$o" 28
476*4461a296SBryan Cantrill
477*4461a296SBryan Cantrillecho "$CMD: completed"
478*4461a296SBryan Cantrill
479*4461a296SBryan Cantrillexit $errs
480*4461a296SBryan Cantrill
481