110898Sroland.mainz@nrubsig.org#
210898Sroland.mainz@nrubsig.org# CDDL HEADER START
310898Sroland.mainz@nrubsig.org#
410898Sroland.mainz@nrubsig.org# The contents of this file are subject to the terms of the
510898Sroland.mainz@nrubsig.org# Common Development and Distribution License (the "License").
610898Sroland.mainz@nrubsig.org# You may not use this file except in compliance with the License.
710898Sroland.mainz@nrubsig.org#
810898Sroland.mainz@nrubsig.org# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
910898Sroland.mainz@nrubsig.org# or http://www.opensolaris.org/os/licensing.
1010898Sroland.mainz@nrubsig.org# See the License for the specific language governing permissions
1110898Sroland.mainz@nrubsig.org# and limitations under the License.
1210898Sroland.mainz@nrubsig.org#
1310898Sroland.mainz@nrubsig.org# When distributing Covered Code, include this CDDL HEADER in each
1410898Sroland.mainz@nrubsig.org# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1510898Sroland.mainz@nrubsig.org# If applicable, add the following below this CDDL HEADER, with the
1610898Sroland.mainz@nrubsig.org# fields enclosed by brackets "[]" replaced with your own identifying
1710898Sroland.mainz@nrubsig.org# information: Portions Copyright [yyyy] [name of copyright owner]
1810898Sroland.mainz@nrubsig.org#
1910898Sroland.mainz@nrubsig.org# CDDL HEADER END
2010898Sroland.mainz@nrubsig.org#
2110898Sroland.mainz@nrubsig.org
2210898Sroland.mainz@nrubsig.org#
23*12068SRoger.Faulkner@Oracle.COM# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
2410898Sroland.mainz@nrubsig.org#
2510898Sroland.mainz@nrubsig.org
2610898Sroland.mainz@nrubsig.org#
2710898Sroland.mainz@nrubsig.org# Test whether the ksh93/libcmd tail builtin is compatible to
2810898Sroland.mainz@nrubsig.org# Solaris/SystemV { /usr/bin/tail, /usr/xpg4/bin/tail } and
2910898Sroland.mainz@nrubsig.org# POSIX "tail"
3010898Sroland.mainz@nrubsig.org#
3110898Sroland.mainz@nrubsig.org
3210898Sroland.mainz@nrubsig.org# test setup
3310898Sroland.mainz@nrubsig.orgfunction err_exit
3410898Sroland.mainz@nrubsig.org{
3510898Sroland.mainz@nrubsig.org	print -u2 -n "\t"
3610898Sroland.mainz@nrubsig.org	print -u2 -r ${Command}[$1]: "${@:2}"
37*12068SRoger.Faulkner@Oracle.COM	(( Errors < 127 && Errors++ ))
3810898Sroland.mainz@nrubsig.org}
3910898Sroland.mainz@nrubsig.orgalias err_exit='err_exit $LINENO'
4010898Sroland.mainz@nrubsig.org
4110898Sroland.mainz@nrubsig.orgset -o nounset
4210898Sroland.mainz@nrubsig.orgCommand=${0##*/}
4310898Sroland.mainz@nrubsig.orginteger Errors=0
4410898Sroland.mainz@nrubsig.org
4510898Sroland.mainz@nrubsig.org# common functions
4610898Sroland.mainz@nrubsig.orgfunction isvalidpid
4710898Sroland.mainz@nrubsig.org{
4810898Sroland.mainz@nrubsig.org        kill -0 ${1} 2>/dev/null && return 0
4910898Sroland.mainz@nrubsig.org        return 1
5010898Sroland.mainz@nrubsig.org}
5110898Sroland.mainz@nrubsig.org
5210898Sroland.mainz@nrubsig.orgfunction waitpidtimeout
5310898Sroland.mainz@nrubsig.org{
5410898Sroland.mainz@nrubsig.org	integer pid=$1
5510898Sroland.mainz@nrubsig.org	float timeout=$2
5610898Sroland.mainz@nrubsig.org	float i
5710898Sroland.mainz@nrubsig.org	float -r STEP=0.5 # const
5810898Sroland.mainz@nrubsig.org
5910898Sroland.mainz@nrubsig.org	(( timeout=timeout/STEP ))
6010898Sroland.mainz@nrubsig.org
6110898Sroland.mainz@nrubsig.org	for (( i=0 ; i < timeout ; i+=STEP )) ; do
6210898Sroland.mainz@nrubsig.org		isvalidpid ${pid} || break
6310898Sroland.mainz@nrubsig.org		sleep ${STEP}
6410898Sroland.mainz@nrubsig.org	done
6510898Sroland.mainz@nrubsig.org
6610898Sroland.mainz@nrubsig.org	return 0
6710898Sroland.mainz@nrubsig.org}
6810898Sroland.mainz@nrubsig.org
6910898Sroland.mainz@nrubsig.orgfunction myintseq
7010898Sroland.mainz@nrubsig.org{
7110898Sroland.mainz@nrubsig.org        integer i
7210898Sroland.mainz@nrubsig.org	float arg1=$1
7310898Sroland.mainz@nrubsig.org	float arg2=$2
7410898Sroland.mainz@nrubsig.org	float arg3=$3
7510898Sroland.mainz@nrubsig.org
7610898Sroland.mainz@nrubsig.org        case $# in
7710898Sroland.mainz@nrubsig.org                1)
7810898Sroland.mainz@nrubsig.org                        for (( i=1 ; i <= arg1 ; i++ )) ; do
7910898Sroland.mainz@nrubsig.org                                printf "%d\n" i
8010898Sroland.mainz@nrubsig.org                        done
8110898Sroland.mainz@nrubsig.org                        ;;
8210898Sroland.mainz@nrubsig.org                2)
8310898Sroland.mainz@nrubsig.org                        for (( i=arg1 ; i <= arg2 ; i++ )) ; do
8410898Sroland.mainz@nrubsig.org                                printf "%d\n" i
8510898Sroland.mainz@nrubsig.org                        done
8610898Sroland.mainz@nrubsig.org                        ;;
8710898Sroland.mainz@nrubsig.org                3)
8810898Sroland.mainz@nrubsig.org                        for (( i=arg1 ; i <= arg3 ; i+=arg2 )) ; do
8910898Sroland.mainz@nrubsig.org                                printf "%d\n" i
9010898Sroland.mainz@nrubsig.org                        done
9110898Sroland.mainz@nrubsig.org                        ;;
9210898Sroland.mainz@nrubsig.org                *)
9310898Sroland.mainz@nrubsig.org                        print -u2 -f "%s: Illegal number of arguments %d\n" "$0" $#
9410898Sroland.mainz@nrubsig.org			return 1
9510898Sroland.mainz@nrubsig.org                        ;;
9610898Sroland.mainz@nrubsig.org        esac
9710898Sroland.mainz@nrubsig.org
9810898Sroland.mainz@nrubsig.org        return 0
9910898Sroland.mainz@nrubsig.org}
10010898Sroland.mainz@nrubsig.org
101*12068SRoger.Faulkner@Oracle.COM# quote input string but use single-backslash that "err_exit" prints
102*12068SRoger.Faulkner@Oracle.COM# the strings correctly
103*12068SRoger.Faulkner@Oracle.COMfunction singlebackslashquote
104*12068SRoger.Faulkner@Oracle.COM{
105*12068SRoger.Faulkner@Oracle.COM	typeset s
106*12068SRoger.Faulkner@Oracle.COM	s="$(printf "%q\n" "$1")"
107*12068SRoger.Faulkner@Oracle.COM	print -r "$s"
108*12068SRoger.Faulkner@Oracle.COM	return 0
109*12068SRoger.Faulkner@Oracle.COM}
110*12068SRoger.Faulkner@Oracle.COM
11110898Sroland.mainz@nrubsig.org# quote input string but use double-backslash that "err_exit" prints
11210898Sroland.mainz@nrubsig.org# the strings correctly
11310898Sroland.mainz@nrubsig.orgfunction doublebackslashquote
11410898Sroland.mainz@nrubsig.org{
11510898Sroland.mainz@nrubsig.org	typeset s
11610898Sroland.mainz@nrubsig.org	s="$(printf "%q\n" "$1")"
11710898Sroland.mainz@nrubsig.org	s="${s//\\/\\\\}"
11810898Sroland.mainz@nrubsig.org	print -r "$s"
11910898Sroland.mainz@nrubsig.org	return 0
12010898Sroland.mainz@nrubsig.org}
12110898Sroland.mainz@nrubsig.org
12210898Sroland.mainz@nrubsig.org
12310898Sroland.mainz@nrubsig.org# main
12410898Sroland.mainz@nrubsig.orgbuiltin mktemp || err_exit "mktemp builtin not found"
12510898Sroland.mainz@nrubsig.orgbuiltin rm || err_exit "rm builtin not found"
12610898Sroland.mainz@nrubsig.orgbuiltin tail || err_exit "tail builtin not found"
12710898Sroland.mainz@nrubsig.org
12810898Sroland.mainz@nrubsig.orgtypeset ocwd
12910898Sroland.mainz@nrubsig.orgtypeset tmpdir
13010898Sroland.mainz@nrubsig.org
13110898Sroland.mainz@nrubsig.org# create temporary test directory
13210898Sroland.mainz@nrubsig.orgocwd="$PWD"
133*12068SRoger.Faulkner@Oracle.COMtmpdir="$(mktemp -t -d "test_sun_solaris_builtin_tail.XXXXXXXX")" || err_exit "Cannot create temporary directory"
13410898Sroland.mainz@nrubsig.org
135*12068SRoger.Faulkner@Oracle.COMcd "${tmpdir}" || { err_exit "cd ${tmpdir} failed." ; exit $((Errors)) ; }
13610898Sroland.mainz@nrubsig.org
13710898Sroland.mainz@nrubsig.org
13810898Sroland.mainz@nrubsig.org# run tests:
13910898Sroland.mainz@nrubsig.org
14010898Sroland.mainz@nrubsig.org# test1: basic tests
14110898Sroland.mainz@nrubsig.orgcompound -a testcases=(
14210898Sroland.mainz@nrubsig.org	(
14310898Sroland.mainz@nrubsig.org		name="reverse_n"
14410898Sroland.mainz@nrubsig.org		input=$'hello\nworld'
14510898Sroland.mainz@nrubsig.org		compound -A tail_args=(
14610898Sroland.mainz@nrubsig.org			[legacy]=(   argv=( "-r"  ) )
14710898Sroland.mainz@nrubsig.org		)
14810898Sroland.mainz@nrubsig.org		expected_output=$'world\nhello'
14910898Sroland.mainz@nrubsig.org	)
15010898Sroland.mainz@nrubsig.org	(
15110898Sroland.mainz@nrubsig.org		name="revlist0n"
15210898Sroland.mainz@nrubsig.org		input=$'1\n2\n3\n4'
15310898Sroland.mainz@nrubsig.org		compound -A tail_args=(
15410898Sroland.mainz@nrubsig.org			[legacy]=(   argv=( "-0"	 ) )
15510898Sroland.mainz@nrubsig.org			[std_like]=( argv=( "-n" "0" ) )
15610898Sroland.mainz@nrubsig.org		)
15710898Sroland.mainz@nrubsig.org		expected_output=$''
15810898Sroland.mainz@nrubsig.org	)
15910898Sroland.mainz@nrubsig.org	(
16010898Sroland.mainz@nrubsig.org		name="revlist0nr"
16110898Sroland.mainz@nrubsig.org		input=$'1\n2\n3\n4'
16210898Sroland.mainz@nrubsig.org		compound -A tail_args=(
16310898Sroland.mainz@nrubsig.org			[legacy]=(       argv=( "-0r"	      ) )
16410898Sroland.mainz@nrubsig.org			[std_like]=(     argv=( "-n" "0" "-r" ) )
16510898Sroland.mainz@nrubsig.org			[long_options]=( argv=( "--lines" "0" "--reverse" ) )
16610898Sroland.mainz@nrubsig.org		)
16710898Sroland.mainz@nrubsig.org		expected_output=$'' )
16810898Sroland.mainz@nrubsig.org	(
16910898Sroland.mainz@nrubsig.org		name="revlist1n"
17010898Sroland.mainz@nrubsig.org		input=$'1\n2\n3\n4'
17110898Sroland.mainz@nrubsig.org		compound -A tail_args=(
17210898Sroland.mainz@nrubsig.org			[legacy]=(       argv=( "-1"     ) )
17310898Sroland.mainz@nrubsig.org			[std_like]=(     argv=( "-n" "1" ) )
17410898Sroland.mainz@nrubsig.org			[long_options]=( argv=( "--lines" "1" ) )
17510898Sroland.mainz@nrubsig.org		)
17610898Sroland.mainz@nrubsig.org		expected_output=$'4' )
17710898Sroland.mainz@nrubsig.org	(
17810898Sroland.mainz@nrubsig.org		name="revlist1nr"
17910898Sroland.mainz@nrubsig.org		input=$'1\n2\n3\n4'
18010898Sroland.mainz@nrubsig.org		compound -A tail_args=(
18110898Sroland.mainz@nrubsig.org			[legacy]=(       argv=( "-1r" ) )
18210898Sroland.mainz@nrubsig.org			[std_like]=(     argv=( "-n" "1" "-r" ) )
18310898Sroland.mainz@nrubsig.org			[long_options]=( argv=( "--lines" "1" "--reverse" ) )
18410898Sroland.mainz@nrubsig.org		)
18510898Sroland.mainz@nrubsig.org		expected_output=$'4'
18610898Sroland.mainz@nrubsig.org	)
18710898Sroland.mainz@nrubsig.org	(
18810898Sroland.mainz@nrubsig.org		name="revlist2n"
18910898Sroland.mainz@nrubsig.org		input=$'1\n2\n3\n4'
19010898Sroland.mainz@nrubsig.org		compound -A tail_args=(
19110898Sroland.mainz@nrubsig.org			[legacy]=(   argv=( "-2"  ) )
19210898Sroland.mainz@nrubsig.org			[std_like]=( argv=( "-n" "2" ) )
19310898Sroland.mainz@nrubsig.org		)
19410898Sroland.mainz@nrubsig.org		expected_output=$'3\n4'
19510898Sroland.mainz@nrubsig.org	)
19610898Sroland.mainz@nrubsig.org	(
19710898Sroland.mainz@nrubsig.org		name="revlist2nr"
19810898Sroland.mainz@nrubsig.org		input=$'1\n2\n3\n4'
19910898Sroland.mainz@nrubsig.org		compound -A tail_args=(
20010898Sroland.mainz@nrubsig.org			[legacy]=(   argv=( "-2r" ) )
20110898Sroland.mainz@nrubsig.org			[std_like]=( argv=( "-n" "2" "-r" ) )
20210898Sroland.mainz@nrubsig.org			)
20310898Sroland.mainz@nrubsig.org		expected_output=$'4\n3'
20410898Sroland.mainz@nrubsig.org	)
20510898Sroland.mainz@nrubsig.org	(
20610898Sroland.mainz@nrubsig.org		name="revlist3nr"
20710898Sroland.mainz@nrubsig.org		input=$'1\n2\n3\n4'
20810898Sroland.mainz@nrubsig.org		compound -A tail_args=(
20910898Sroland.mainz@nrubsig.org			[legacy]=(   argv=( "-3r" ) )
21010898Sroland.mainz@nrubsig.org			[std_like]=( argv=( "-n" "3" "-r" ) )
21110898Sroland.mainz@nrubsig.org		)
21210898Sroland.mainz@nrubsig.org		expected_output=$'4\n3\n2'
21310898Sroland.mainz@nrubsig.org	)
21410898Sroland.mainz@nrubsig.org	(
21510898Sroland.mainz@nrubsig.org		name="revlist2p"
21610898Sroland.mainz@nrubsig.org		input=$'1\n2\n3\n4'
21710898Sroland.mainz@nrubsig.org		compound -A tail_args=(
21810898Sroland.mainz@nrubsig.org			[legacy]=(   argv=( "+2"  ) )
21910898Sroland.mainz@nrubsig.org			[std_like]=( argv=( "-n" "+2" ) )
22010898Sroland.mainz@nrubsig.org			)
22110898Sroland.mainz@nrubsig.org		expected_output=$'2\n3\n4'
22210898Sroland.mainz@nrubsig.org	)
22310898Sroland.mainz@nrubsig.org	(
22410898Sroland.mainz@nrubsig.org		name="revlist2pr"
22510898Sroland.mainz@nrubsig.org		input=$'1\n2\n3\n4'
22610898Sroland.mainz@nrubsig.org		compound -A tail_args=(
22710898Sroland.mainz@nrubsig.org			[legacy]=(   argv=( "+2r" ) )
22810898Sroland.mainz@nrubsig.org			[std_like]=( argv=( "-n" "+2" "-r" ) )
22910898Sroland.mainz@nrubsig.org		)
23010898Sroland.mainz@nrubsig.org		expected_output=$'4\n3\n2'
23110898Sroland.mainz@nrubsig.org	)
23210898Sroland.mainz@nrubsig.org	(
23310898Sroland.mainz@nrubsig.org		name="revlist3p"
23410898Sroland.mainz@nrubsig.org		input=$'1\n2\n3\n4'
23510898Sroland.mainz@nrubsig.org		compound -A tail_args=(
23610898Sroland.mainz@nrubsig.org			[legacy]=(   argv=( "+3"  ) )
23710898Sroland.mainz@nrubsig.org			[std_like]=( argv=( "-n" "+3"  ) )
23810898Sroland.mainz@nrubsig.org		)
23910898Sroland.mainz@nrubsig.org		expected_output=$'3\n4'
24010898Sroland.mainz@nrubsig.org	)
24110898Sroland.mainz@nrubsig.org	(
24210898Sroland.mainz@nrubsig.org		name="revlist3pr"
24310898Sroland.mainz@nrubsig.org		input=$'1\n2\n3\n4'
24410898Sroland.mainz@nrubsig.org		compound -A tail_args=(
24510898Sroland.mainz@nrubsig.org			[legacy]=(   argv=( "+3r" ) )
24610898Sroland.mainz@nrubsig.org			[std_like]=( argv=( "-n" "+3" "-r" ) )
24710898Sroland.mainz@nrubsig.org		)
24810898Sroland.mainz@nrubsig.org		expected_output=$'4\n3'
24910898Sroland.mainz@nrubsig.org	)
25010898Sroland.mainz@nrubsig.org	(
25110898Sroland.mainz@nrubsig.org		name="revlist4p"
25210898Sroland.mainz@nrubsig.org		input=$'1\n2\n3\n4'
25310898Sroland.mainz@nrubsig.org		compound -A tail_args=(
25410898Sroland.mainz@nrubsig.org			[legacy]=(   argv=( "+4"  ) )
25510898Sroland.mainz@nrubsig.org			[std_like]=( argv=( "-n" "+4"  ) )
25610898Sroland.mainz@nrubsig.org		)
25710898Sroland.mainz@nrubsig.org		expected_output=$'4'
25810898Sroland.mainz@nrubsig.org	)
25910898Sroland.mainz@nrubsig.org	(
26010898Sroland.mainz@nrubsig.org		name="revlist4pr"
26110898Sroland.mainz@nrubsig.org		input=$'1\n2\n3\n4'
26210898Sroland.mainz@nrubsig.org		compound -A tail_args=(
26310898Sroland.mainz@nrubsig.org			[legacy]=(   argv=( "+4r" ) )
26410898Sroland.mainz@nrubsig.org			[std_like]=( argv=( "-n" "+4" "-r" ) )
26510898Sroland.mainz@nrubsig.org		)
26610898Sroland.mainz@nrubsig.org		expected_output=$'4'
26710898Sroland.mainz@nrubsig.org	)
26810898Sroland.mainz@nrubsig.org	(
26910898Sroland.mainz@nrubsig.org		name="revlist5p"
27010898Sroland.mainz@nrubsig.org		input=$'1\n2\n3\n4'
27110898Sroland.mainz@nrubsig.org		compound -A tail_args=(
27210898Sroland.mainz@nrubsig.org			[legacy]=(   argv=( "+5"  ) )
27310898Sroland.mainz@nrubsig.org			[std_like]=( argv=( "-n" "+5"  ) )
27410898Sroland.mainz@nrubsig.org		)
27510898Sroland.mainz@nrubsig.org		expected_output=$''
27610898Sroland.mainz@nrubsig.org	)
27710898Sroland.mainz@nrubsig.org	(
27810898Sroland.mainz@nrubsig.org		name="revlist5pr"
27910898Sroland.mainz@nrubsig.org		input=$'1\n2\n3\n4'
28010898Sroland.mainz@nrubsig.org		compound -A tail_args=(
28110898Sroland.mainz@nrubsig.org			[legacy]=(   argv=( "+5r" ) )
28210898Sroland.mainz@nrubsig.org			[std_like]=( argv=( "-n" "+5" "-r" ) )
28310898Sroland.mainz@nrubsig.org		)
28410898Sroland.mainz@nrubsig.org		expected_output=$''
28510898Sroland.mainz@nrubsig.org	)
28610898Sroland.mainz@nrubsig.org)
28710898Sroland.mainz@nrubsig.org
28810898Sroland.mainz@nrubsig.orgfor testid in "${!testcases[@]}" ; do
28910898Sroland.mainz@nrubsig.org	nameref tc=testcases[${testid}]
29010898Sroland.mainz@nrubsig.org
29110898Sroland.mainz@nrubsig.org	for argv_variants in "${!tc.tail_args[@]}" ; do
29210898Sroland.mainz@nrubsig.org		nameref argv=tc.tail_args[${argv_variants}].argv
29310898Sroland.mainz@nrubsig.org		output=$(
294*12068SRoger.Faulkner@Oracle.COM				set -o pipefail
295*12068SRoger.Faulkner@Oracle.COM	          		(trap "" PIPE ; print -r -- "${tc.input}") | tail "${argv[@]}"
29610898Sroland.mainz@nrubsig.org			) || err_exit "test ${tc.name}/${argv_variants}: command failed with exit code $?"
29710898Sroland.mainz@nrubsig.org
29810898Sroland.mainz@nrubsig.org		[[ "${output}" == "${tc.expected_output}" ]] || err_exit "test ${tc.name}/${argv_variants}: Expected $(doublebackslashquote "${tc.expected_output}"), got $(doublebackslashquote "${output}")"
29910898Sroland.mainz@nrubsig.org	done
30010898Sroland.mainz@nrubsig.orgdone
30110898Sroland.mainz@nrubsig.org
30210898Sroland.mainz@nrubsig.org
30310898Sroland.mainz@nrubsig.org# test2: test "tail -r </etc/profile | rev -l" vs. "cat </etc/profile"
30410898Sroland.mainz@nrubsig.org[[ "$(tail -r </etc/profile | rev -l)" == "$( cat /etc/profile )" ]] || err_exit "'tail -r </etc/profile | rev -l' output does not match 'cat /etc/profile'"
30510898Sroland.mainz@nrubsig.org
30610898Sroland.mainz@nrubsig.org
30710898Sroland.mainz@nrubsig.org# test 3: ast-ksh.2009-05-05 "tail" builtin may crash if we pass unsupported long options
30810898Sroland.mainz@nrubsig.org$SHELL -o errexit -c 'builtin tail ; print "hello" | tail --attack_of_chicken_monsters' >/dev/null 2>&1
30910898Sroland.mainz@nrubsig.org(( $? == 2 )) || err_exit "expected exit code 2 for unsupported long option, got $?"
31010898Sroland.mainz@nrubsig.org
31110898Sroland.mainz@nrubsig.org
31210898Sroland.mainz@nrubsig.org# test 4: FIFO tests
31310898Sroland.mainz@nrubsig.org
31410898Sroland.mainz@nrubsig.org# FIFO test functions
31510898Sroland.mainz@nrubsig.org# (we use functions here to do propper garbage collection)
31610898Sroland.mainz@nrubsig.orgfunction test_tail_fifo_1
31710898Sroland.mainz@nrubsig.org{
31810898Sroland.mainz@nrubsig.org	typeset tail_cmd="$1"
31910898Sroland.mainz@nrubsig.org	integer i
32010898Sroland.mainz@nrubsig.org	integer tail_pid=-1
32110898Sroland.mainz@nrubsig.org
32210898Sroland.mainz@nrubsig.org	# cleanup trap
32310898Sroland.mainz@nrubsig.org	trap "rm -f tailtestfifo tailout" EXIT
32410898Sroland.mainz@nrubsig.org
32510898Sroland.mainz@nrubsig.org	# create test FIFO
32610898Sroland.mainz@nrubsig.org	mkfifo tailtestfifo
32710898Sroland.mainz@nrubsig.org
32810898Sroland.mainz@nrubsig.org	${tail_cmd} -f <tailtestfifo >tailout &
32910898Sroland.mainz@nrubsig.org	tail_pid=$!
33010898Sroland.mainz@nrubsig.org
33110898Sroland.mainz@nrubsig.org	myintseq 20 >tailtestfifo
33210898Sroland.mainz@nrubsig.org
33310898Sroland.mainz@nrubsig.org	waitpidtimeout ${tail_pid} 5
33410898Sroland.mainz@nrubsig.org
33510898Sroland.mainz@nrubsig.org	if isvalidpid ${tail_pid} ; then
33610898Sroland.mainz@nrubsig.org		err_exit "test_tail_fifo_1: # tail hung (not expected)"
33710898Sroland.mainz@nrubsig.org		kill -KILL ${tail_pid}
33810898Sroland.mainz@nrubsig.org	fi
33910898Sroland.mainz@nrubsig.org
34010898Sroland.mainz@nrubsig.org	wait || err_exit "tail child returned non-zero exit code=$?"
34110898Sroland.mainz@nrubsig.org
34210898Sroland.mainz@nrubsig.org	[[ "$(cat tailout)" == $'11\n12\n13\n14\n15\n16\n17\n18\n19\n20' ]] || err_exit "test_tail_fifo_1: Expected $(doublebackslashquote '11\n12\n13\n14\n15\n16\n17\n18\n19\n20'), got $(doublebackslashquote "$(cat tailout)")"
34310898Sroland.mainz@nrubsig.org
34410898Sroland.mainz@nrubsig.org	return 0
34510898Sroland.mainz@nrubsig.org}
34610898Sroland.mainz@nrubsig.org
34710898Sroland.mainz@nrubsig.orgfunction test_tail_fifo_2
34810898Sroland.mainz@nrubsig.org{
34910898Sroland.mainz@nrubsig.org	typeset tail_cmd="$1"
35010898Sroland.mainz@nrubsig.org	integer i
35110898Sroland.mainz@nrubsig.org	integer tail_pid=-1
35210898Sroland.mainz@nrubsig.org
35310898Sroland.mainz@nrubsig.org	# cleanup trap
35410898Sroland.mainz@nrubsig.org	trap "rm -f tailtestfifo tailout" EXIT
35510898Sroland.mainz@nrubsig.org
35610898Sroland.mainz@nrubsig.org	# create test FIFO
35710898Sroland.mainz@nrubsig.org	mkfifo tailtestfifo
35810898Sroland.mainz@nrubsig.org
35910898Sroland.mainz@nrubsig.org	${tail_cmd} -f tailtestfifo >tailout &
36010898Sroland.mainz@nrubsig.org	tail_pid=$!
36110898Sroland.mainz@nrubsig.org
36210898Sroland.mainz@nrubsig.org	myintseq 14 >tailtestfifo
36310898Sroland.mainz@nrubsig.org
36410898Sroland.mainz@nrubsig.org	waitpidtimeout ${tail_pid} 5
36510898Sroland.mainz@nrubsig.org
36610898Sroland.mainz@nrubsig.org	if isvalidpid ${tail_pid} ; then
36710898Sroland.mainz@nrubsig.org		[[ "$(cat tailout)" == $'5\n6\n7\n8\n9\n10\n11\n12\n13\n14' ]] || err_exit "test_tail_fifo_2: Expected $(doublebackslashquote $'5\n6\n7\n8\n9\n10\n11\n12\n13\n14'), got $(doublebackslashquote "$(cat tailout)")"
36810898Sroland.mainz@nrubsig.org
36910898Sroland.mainz@nrubsig.org		myintseq 15 >>tailtestfifo
37010898Sroland.mainz@nrubsig.org
37110898Sroland.mainz@nrubsig.org		waitpidtimeout ${tail_pid} 5
37210898Sroland.mainz@nrubsig.org
37310898Sroland.mainz@nrubsig.org		if isvalidpid ${tail_pid} ; then
37410898Sroland.mainz@nrubsig.org			kill -KILL ${tail_pid}
37510898Sroland.mainz@nrubsig.org		else
37610898Sroland.mainz@nrubsig.org			err_exit "test_tail_fifo_2: # tail exit with return code $? (not expected)"
37710898Sroland.mainz@nrubsig.org		fi
37810898Sroland.mainz@nrubsig.org	fi
37910898Sroland.mainz@nrubsig.org
38010898Sroland.mainz@nrubsig.org	wait || err_exit "tail child returned non-zero exit code=$?"
38110898Sroland.mainz@nrubsig.org
38210898Sroland.mainz@nrubsig.org	[[ "$(cat tailout)" == $'5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15' ]] || err_exit "test_tail_fifo_2: Expected $(doublebackslashquote $'5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15'), got $(doublebackslashquote "$(cat tailout)")"
38310898Sroland.mainz@nrubsig.org
38410898Sroland.mainz@nrubsig.org	return 0
38510898Sroland.mainz@nrubsig.org}
38610898Sroland.mainz@nrubsig.org
38710898Sroland.mainz@nrubsig.org# fixme: This should test /usr/bin/tail and /usr/xpg4/bin/tail in Solaris
38810898Sroland.mainz@nrubsig.orgtest_tail_fifo_1 "tail"
38910898Sroland.mainz@nrubsig.orgtest_tail_fifo_2 "tail"
39010898Sroland.mainz@nrubsig.org
39110898Sroland.mainz@nrubsig.org
39210898Sroland.mainz@nrubsig.org# test 5: "tail -f" tests
39310898Sroland.mainz@nrubsig.orgfunction followtest1
39410898Sroland.mainz@nrubsig.org{
39510898Sroland.mainz@nrubsig.org	typeset -r FOLLOWFILE="followfile.txt"
39610898Sroland.mainz@nrubsig.org	typeset -r OUTFILE="outfile.txt"
39710898Sroland.mainz@nrubsig.org
39810898Sroland.mainz@nrubsig.org	typeset title="$1"
39910898Sroland.mainz@nrubsig.org	typeset testcmd="$2"
40010898Sroland.mainz@nrubsig.org	typeset usenewline=$3
40110898Sroland.mainz@nrubsig.org	typeset followstr=""
40210898Sroland.mainz@nrubsig.org	typeset newline=""
40310898Sroland.mainz@nrubsig.org	integer i
40410898Sroland.mainz@nrubsig.org	integer tailchild=-1
40510898Sroland.mainz@nrubsig.org
40610898Sroland.mainz@nrubsig.org	if ${usenewline} ; then
40710898Sroland.mainz@nrubsig.org		newline=$'\n'
40810898Sroland.mainz@nrubsig.org	fi
40910898Sroland.mainz@nrubsig.org
41010898Sroland.mainz@nrubsig.org	rm -f "${FOLLOWFILE}" "${OUTFILE}"
41110898Sroland.mainz@nrubsig.org	print -n "${newline}" > "${FOLLOWFILE}"
41210898Sroland.mainz@nrubsig.org
41310898Sroland.mainz@nrubsig.org	${testcmd} -f "${FOLLOWFILE}" >"${OUTFILE}" &
41410898Sroland.mainz@nrubsig.org	(( tailchild=$! ))
41510898Sroland.mainz@nrubsig.org
41610898Sroland.mainz@nrubsig.org	for (( i=0 ; i < 10 ; i++)) ; do
41710898Sroland.mainz@nrubsig.org		followstr+="${newline}${i}"
41810898Sroland.mainz@nrubsig.org		print -n "${i}${newline}" >>"${FOLLOWFILE}"
41910898Sroland.mainz@nrubsig.org		sleep 2
42010898Sroland.mainz@nrubsig.org
42110898Sroland.mainz@nrubsig.org		[[ "$( < "${OUTFILE}")" == "${followstr}" ]] || err_exit "${title}: Expected $(doublebackslashquote "${followstr}"), got "$(doublebackslashquote "$( < "${OUTFILE}")")""
42210898Sroland.mainz@nrubsig.org	done
42310898Sroland.mainz@nrubsig.org
424*12068SRoger.Faulkner@Oracle.COM	kill -KILL ${tailchild} 2>/dev/null
42510898Sroland.mainz@nrubsig.org	#kill -TERM ${tailchild} 2>/dev/null
42610898Sroland.mainz@nrubsig.org	waitpidtimeout ${tailchild} 5
42710898Sroland.mainz@nrubsig.org
42810898Sroland.mainz@nrubsig.org	if isvalidpid ${tailchild} ; then
42910898Sroland.mainz@nrubsig.org		err_exit "${title}: tail pid=${tailchild} hung."
43010898Sroland.mainz@nrubsig.org		kill -KILL ${tailchild} 2>/dev/null
43110898Sroland.mainz@nrubsig.org	fi
43210898Sroland.mainz@nrubsig.org
43310898Sroland.mainz@nrubsig.org	wait ${tailchild} 2>/dev/null
43410898Sroland.mainz@nrubsig.org
43510898Sroland.mainz@nrubsig.org	rm -f "${FOLLOWFILE}" "${OUTFILE}"
43610898Sroland.mainz@nrubsig.org
43710898Sroland.mainz@nrubsig.org	return 0
43810898Sroland.mainz@nrubsig.org}
43910898Sroland.mainz@nrubsig.org
44010898Sroland.mainz@nrubsig.orgfollowtest1 "test5a" "tail" true
44110898Sroland.mainz@nrubsig.org# fixme: later we should test this, too:
44210898Sroland.mainz@nrubsig.org#followtest1 "test5b" "tail" false
44310898Sroland.mainz@nrubsig.org#followtest1 "test5c" "/usr/xpg4/bin/tail" true
44410898Sroland.mainz@nrubsig.org#followtest1 "test5d" "/usr/xpg4/bin/tail" false
44510898Sroland.mainz@nrubsig.org#followtest1 "test5e" "/usr/bin/tail" true
44610898Sroland.mainz@nrubsig.org#followtest1 "test5f" "/usr/bin/tail" false
44710898Sroland.mainz@nrubsig.org
44810898Sroland.mainz@nrubsig.org
449*12068SRoger.Faulkner@Oracle.COM# test 6: "tail -f" tests
450*12068SRoger.Faulkner@Oracle.COMfunction followtest2
451*12068SRoger.Faulkner@Oracle.COM{
452*12068SRoger.Faulkner@Oracle.COM	typeset -r FOLLOWFILE="followfile.txt"
453*12068SRoger.Faulkner@Oracle.COM	typeset -r OUTFILE="outfile.txt"
454*12068SRoger.Faulkner@Oracle.COM
455*12068SRoger.Faulkner@Oracle.COM	typeset title="$1"
456*12068SRoger.Faulkner@Oracle.COM	typeset testcmd="$2"
457*12068SRoger.Faulkner@Oracle.COM	integer tailchild=-1
458*12068SRoger.Faulkner@Oracle.COM
459*12068SRoger.Faulkner@Oracle.COM	rm -f "${FOLLOWFILE}" "${OUTFILE}"
460*12068SRoger.Faulkner@Oracle.COM
461*12068SRoger.Faulkner@Oracle.COM	myintseq 50000 >"${FOLLOWFILE}"
462*12068SRoger.Faulkner@Oracle.COM
463*12068SRoger.Faulkner@Oracle.COM	${testcmd} -n 60000 -f "${FOLLOWFILE}" >"${OUTFILE}" &
464*12068SRoger.Faulkner@Oracle.COM	(( tailchild=$! ))
465*12068SRoger.Faulkner@Oracle.COM
466*12068SRoger.Faulkner@Oracle.COM	sleep 10
467*12068SRoger.Faulkner@Oracle.COM
468*12068SRoger.Faulkner@Oracle.COM	kill -KILL ${tailchild} 2>/dev/null
469*12068SRoger.Faulkner@Oracle.COM	#kill -TERM ${tailchild} 2>/dev/null
470*12068SRoger.Faulkner@Oracle.COM	waitpidtimeout ${tailchild} 5
471*12068SRoger.Faulkner@Oracle.COM
472*12068SRoger.Faulkner@Oracle.COM	if isvalidpid ${tailchild} ; then
473*12068SRoger.Faulkner@Oracle.COM		err_exit "${title}: tail pid=${tailchild} hung."
474*12068SRoger.Faulkner@Oracle.COM		kill -KILL ${tailchild} 2>/dev/null
475*12068SRoger.Faulkner@Oracle.COM	fi
476*12068SRoger.Faulkner@Oracle.COM
477*12068SRoger.Faulkner@Oracle.COM	wait ${tailchild} 2>/dev/null
478*12068SRoger.Faulkner@Oracle.COM
479*12068SRoger.Faulkner@Oracle.COM	# this tail should be an external process
480*12068SRoger.Faulkner@Oracle.COM	outstr=$(/usr/bin/tail "${OUTFILE}") || err_exit "tail returned non-zero exit code $?"
481*12068SRoger.Faulkner@Oracle.COM        [[ "${outstr}" == 49991*50000 ]] || err_exit "${title}: Expected match for 49991*50000, got "$(singlebackslashquote "${outstr}")""
482*12068SRoger.Faulkner@Oracle.COM
483*12068SRoger.Faulkner@Oracle.COM	rm -f "${FOLLOWFILE}" "${OUTFILE}"
484*12068SRoger.Faulkner@Oracle.COM
485*12068SRoger.Faulkner@Oracle.COM	return 0
486*12068SRoger.Faulkner@Oracle.COM}
487*12068SRoger.Faulkner@Oracle.COM
488*12068SRoger.Faulkner@Oracle.COMfollowtest2 "test6a" "tail"
489*12068SRoger.Faulkner@Oracle.COMfollowtest2 "test6b" "/usr/xpg4/bin/tail"
490*12068SRoger.Faulkner@Oracle.COM# fixme: later we should test this, too:
491*12068SRoger.Faulkner@Oracle.COM#followtest2 "test6c" "/usr/bin/tail"
492*12068SRoger.Faulkner@Oracle.COM
493*12068SRoger.Faulkner@Oracle.COM
49410898Sroland.mainz@nrubsig.org# cleanup
49510898Sroland.mainz@nrubsig.orgcd "${ocwd}"
49610898Sroland.mainz@nrubsig.orgrmdir "${tmpdir}" || err_exit "Cannot remove temporary directory ${tmpdir}".
49710898Sroland.mainz@nrubsig.org
49810898Sroland.mainz@nrubsig.org
49910898Sroland.mainz@nrubsig.org# tests done
50010898Sroland.mainz@nrubsig.orgexit $((Errors))
501