xref: /titanic_50/usr/src/lib/libshell/common/tests/basic.sh (revision 4045d94132614e1de2073685a6cdd4fbd86bec33)
1########################################################################
2#                                                                      #
3#               This software is part of the ast package               #
4#           Copyright (c) 1982-2007 AT&T Knowledge Ventures            #
5#                      and is licensed under the                       #
6#                  Common Public License, Version 1.0                  #
7#                      by AT&T Knowledge Ventures                      #
8#                                                                      #
9#                A copy of the License is available at                 #
10#            http://www.opensource.org/licenses/cpl1.0.txt             #
11#         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         #
12#                                                                      #
13#              Information and Software Systems Research               #
14#                            AT&T Research                             #
15#                           Florham Park NJ                            #
16#                                                                      #
17#                  David Korn <dgk@research.att.com>                   #
18#                                                                      #
19########################################################################
20function err_exit
21{
22	print -u2 -n "\t"
23	print -u2 -r ${Command}[$1]: "${@:2}"
24	let Errors+=1
25}
26alias err_exit='err_exit $LINENO'
27
28# test basic file operations like redirection, pipes, file expansion
29Command=${0##*/}
30integer Errors=0
31umask u=rwx,go=rx || err_exit "umask u=rws,go=rx failed"
32if	[[ $(umask -S) != u=rwx,g=rx,o=rx ]]
33then	err_exit 'umask -S incorrect'
34fi
35mkdir  /tmp/ksh$$ || err_exit "mkdir /tmp/ksh$$ failed"
36trap "cd /; rm -rf /tmp/ksh$$" EXIT
37pwd=$PWD
38[[ $SHELL != /* ]] && SHELL=$pwd/$SHELL
39cd /tmp/ksh$$ || err_exit "cd /tmp/ksh$$ failed"
40# optimizer bug test
41> foobar
42for i in 1 2
43do      print foobar*
44        rm -f foobar
45done > out$$
46if      [[ "$(<out$$)"  != "foobar"$'\n'"foobar*" ]]
47then    print -u2 "optimizer bug with file expansion"
48fi
49rm -f out$$ foobar
50mkdir dir
51if	[[ $(print */) != dir/ ]]
52then	err_exit 'file expansion with trailing / not working'
53fi
54if	[[ $(print *) != dir ]]
55then	err_exit 'file expansion with single file not working'
56fi
57print hi > .foo
58if	[[ $(print *) != dir ]]
59then	err_exit 'file expansion leading . not working'
60fi
61date > dat1 || err_exit "date > dat1 failed"
62test -r dat1 || err_exit "dat1 is not readable"
63x=dat1
64cat <$x > dat2 || err_exit "cat < $x > dat2 failed"
65cat dat1 dat2 | cat  | cat | cat > dat3 || err_exit "cat pipe failed"
66cat > dat4 <<!
67$(date)
68!
69cat dat1 dat2 | cat  | cat | cat > dat5 &
70wait $!
71set -- dat*
72if	(( $# != 5 ))
73then	err_exit "dat* matches only $# files"
74fi
75if	(command > foo\\abc) 2> /dev/null
76then	set -- foo*
77	if	[[ $1 != 'foo\abc' ]]
78	then	err_exit 'foo* does not match foo\abc'
79	fi
80fi
81if ( : > TT* && : > TTfoo ) 2>/dev/null
82then	set -- TT*
83	if	(( $# < 2 ))
84	then	err_exit 'TT* not expanding when file TT* exists'
85	fi
86fi
87cd ~- || err_exit "cd back failed"
88cat > /tmp/ksh$$/script <<- !
89	#! $SHELL
90	print -r -- \$0
91!
92chmod 755 /tmp/ksh$$/script
93if	[[ $(/tmp/ksh$$/script) != "/tmp/ksh$$/script" ]]
94then	err_exit '$0 not correct for #! script'
95fi
96rm -r /tmp/ksh$$ || err_exit "rm -r /tmp/ksh$$ failed"
97bar=foo
98eval foo=\$bar
99if	[[ $foo != foo ]]
100then	err_exit 'eval foo=\$bar not working'
101fi
102bar='foo=foo\ bar'
103eval $bar
104if	[[ $foo != 'foo bar' ]]
105then	err_exit 'eval foo=\$bar, with bar="foo\ bar" not working'
106fi
107cd /tmp
108cd ../../tmp || err_exit "cd ../../tmp failed"
109if	[[ $PWD != /tmp ]]
110then	err_exit 'cd ../../tmp is not /tmp'
111fi
112( sleep 2; cat <<!
113foobar
114!
115) | cat > /tmp/foobar$$ &
116wait $!
117foobar=$( < /tmp/foobar$$)
118if	[[ $foobar != foobar ]]
119then	err_exit "$foobar is not foobar"
120fi
121{
122	print foo
123	/bin/echo bar
124	print bam
125} > /tmp/foobar$$
126if	[[ $( < /tmp/foobar$$) != $'foo\nbar\nbam' ]]
127then	err_exit "Output file pointer not shared correctly."
128fi
129cat > /tmp/foobar$$ <<\!
130	print foo
131	/bin/echo bar
132	print bam
133!
134chmod +x /tmp/foobar$$
135if	[[ $(/tmp/foobar$$) != $'foo\nbar\nbam' ]]
136then	err_exit "Script not working."
137fi
138if	[[ $(/tmp/foobar$$ | /bin/cat) != $'foo\nbar\nbam' ]]
139then	err_exit "Script | cat not working."
140fi
141if	[[ $( /tmp/foobar$$) != $'foo\nbar\nbam' ]]
142then	err_exit "Output file pointer not shared correctly."
143fi
144rm -f /tmp/foobar$$
145x=$( (print foo) ; (print bar) )
146if	[[ $x != $'foo\nbar' ]]
147then	err_exit " ( (print foo);(print bar ) failed"
148fi
149x=$( (/bin/echo foo) ; (print bar) )
150if	[[ $x != $'foo\nbar' ]]
151then	err_exit " ( (/bin/echo);(print bar ) failed"
152fi
153x=$( (/bin/echo foo) ; (/bin/echo bar) )
154if	[[ $x != $'foo\nbar' ]]
155then	err_exit " ( (/bin/echo);(/bin/echo bar ) failed"
156fi
157cat > /tmp/ksh$$ <<\!
158if	[[ -p /dev/fd/0 ]]
159then	builtin cat
160	cat - > /dev/null
161	[[ -p /dev/fd/0 ]] && print ok
162else	print no
163fi
164!
165chmod +x /tmp/ksh$$
166case $( (print) | /tmp/ksh$$;:) in
167ok)	;;
168no)	err_exit "[[ -p /dev/fd/0 ]] fails for standard input pipe" ;;
169*)	err_exit "builtin replaces standard input pipe" ;;
170esac
171print 'print $0' > /tmp/ksh$$
172print ". /tmp/ksh$$" > /tmp/ksh$$x
173chmod +x /tmp/ksh$$x
174if	[[ $(/tmp/ksh$$x) != /tmp/ksh$$x ]]
175then	err_exit '$0 not correct for . script'
176fi
177rm -r /tmp/ksh$$ /tmp/ksh$$x
178mkdir  /tmp/ksh$$ || err_exit "mkdir /tmp/ksh$$ failed"
179cd /tmp/ksh$$ || err_exit "cd /tmp/ksh$$ failed"
180print ./b > ./a; print ./c > b; print ./d > c; print ./e > d; print "echo \"hello there\"" > e
181chmod 755 a b c d e
182x=$(./a)
183if	[[ $x != "hello there" ]]
184then	err_exit "nested scripts failed"
185fi
186x=$( (./a) | cat)
187if	[[ $x != "hello there" ]]
188then	err_exit "scripts in subshells fail"
189fi
190cd ~- || err_exit "cd back failed"
191rm -r /tmp/ksh$$ || err_exit "rm -r /tmp/ksh$$ failed"
192x=$( (/bin/echo foo) 2> /dev/null )
193if	[[ $x != foo ]]
194then	err_exit "subshell in command substitution fails"
195fi
196exec 1>&-
197x=$(print hello)
198if	[[ $x != hello ]]
199then	err_exit "command subsitution with stdout closed failed"
200fi
201cd $pwd
202x=$(cat <<\! | $SHELL
203/bin/echo | /bin/cat
204/bin/echo hello
205!
206)
207if	[[ $x != $'\n'hello ]]
208then	err_exit "$SHELL not working when standard input is a pipe"
209fi
210x=$( (/bin/echo hello) 2> /dev/null )
211if	[[ $x != hello ]]
212then	err_exit "subshell in command substitution with 1 closed fails"
213fi
214cat > /tmp/ksh$$ <<- \!
215read line 2> /dev/null
216print done
217!
218if	[[ $($SHELL /tmp/ksh$$ <&-) != done ]]
219then	err_exit "executing script with 0 closed fails"
220fi
221trap '' INT
222cat > /tmp/ksh$$ <<- \!
223trap 'print bad' INT
224kill -s INT $$
225print good
226!
227chmod +x /tmp/ksh$$
228if	[[ $($SHELL  /tmp/ksh$$) != good ]]
229then	err_exit "traps ignored by parent not ignored"
230fi
231trap - INT
232cat > /tmp/ksh$$ <<- \!
233read line
234/bin/cat
235!
236if	[[ $($SHELL /tmp/ksh$$ <<!
237one
238two
239!
240)	!= two ]]
241then	err_exit "standard input not positioned correctly"
242fi
243word=$(print $'foo\nbar' | { read line; /bin/cat;})
244if	[[ $word != bar ]]
245then	err_exit "pipe to { read line; /bin/cat;} not working"
246fi
247word=$(print $'foo\nbar' | ( read line; /bin/cat) )
248if	[[ $word != bar ]]
249then	err_exit "pipe to ( read line; /bin/cat) not working"
250fi
251if	[[ $(print x{a,b}y) != 'xay xby' ]]
252then	err_exit 'brace expansion not working'
253fi
254if	[[ $(for i in foo bar
255	  do ( tgz=$(print $i)
256	  print $tgz)
257	  done) != $'foo\nbar' ]]
258then	err_exit 'for loop subshell optimizer bug'
259fi
260unset a1
261optbug()
262{
263	set -A a1  foo bar bam
264	integer i
265	for ((i=0; i < 3; i++))
266	do
267		(( ${#a1[@]} < 2 )) && return 0
268		set -- "${a1[@]}"
269		shift
270		set -A a1 -- "$@"
271	done
272	return 1
273}
274optbug ||  err_exit 'array size optimzation bug'
275wait # not running --pipefile which would interfere with subsequent tests
276: $(jobs -p) # required to clear jobs for next jobs -p (interactive side effect)
277sleep 20 &
278if	[[ $(jobs -p) != $! ]]
279then	err_exit 'jobs -p not reporting a background job'
280fi
281sleep 20 &
282foo()
283{
284	set -- $(jobs -p)
285	(( $# == 2 )) || err_exit "$# jobs not reported -- 2 expected"
286}
287foo
288[[ $( (trap 'print alarm' ALRM; sleep 4) & sleep 2; kill -ALRM $!) == alarm ]] || err_exit 'ALRM signal not working'
289[[ $($SHELL -c 'trap "" HUP; $SHELL -c "(sleep 2;kill -HUP $$)& sleep 4;print done"') != done ]] && err_exit 'ignored traps not being ignored'
290[[ $($SHELL -c 'o=foobar; for x in foo bar; do (o=save);print $o;done' 2> /dev/null ) == $'foobar\nfoobar' ]] || err_exit 'for loop optimization subshell bug'
291command exec 3<> /dev/null
292if	cat /dev/fd/3 >/dev/null 2>&1
293then	[[ $($SHELL -c 'cat <(print foo)' 2> /dev/null) == foo ]] || err_exit 'process substitution not working'
294	[[ $($SHELL -c 'print $(cat <(print foo) )' 2> /dev/null) == foo ]] || err_exit 'process substitution in subshell not working'
295	[[ $($SHELL -c  $'tee >(grep \'1$\' > /tmp/ksh'$$'x) > /dev/null <<-  \!!!
296	line0
297	line1
298	line2
299	!!!
300	wait
301	cat /tmp/ksh'$$x 2> /dev/null)  == line1 ]] || err_exit '>() process substitution fails'
302	> /tmp/ksh$$x
303	[[ $($SHELL -c  $'
304	for i in 1
305	do	tee >(grep \'1$\' > /tmp/ksh'$$'x) > /dev/null  <<-  \!!!
306		line0
307		line1
308		line2
309		!!!
310	done
311	wait
312	cat /tmp/ksh'$$x 2>> /dev/null) == line1 ]] || err_exit '>() process substitution fails in for loop'
313	[[ $({ $SHELL -c 'cat <(for i in x y z; do print $i; done)';} 2> /dev/null) == $'x\ny\nz' ]] ||
314		err_exit 'process substitution of compound commands not working'
315fi
316[[ $($SHELL -r 'command -p :' 2>&1) == *restricted* ]]  || err_exit 'command -p not restricted'
317print cat >  /tmp/ksh$$x
318chmod +x /tmp/ksh$$x
319[[ $($SHELL -c "print foo | /tmp/ksh$$x ;:" 2> /dev/null ) == foo ]] || err_exit 'piping into script fails'
320[[ $($SHELL -c 'X=1;print -r -- ${X:=$(expr "a(0)" : '"'a*(\([^)]\))')}'" 2> /dev/null) == 1 ]] || err_exit 'x=1;${x:=$(..."...")} failure'
321[[ $($SHELL -c 'print -r -- ${X:=$(expr "a(0)" : '"'a*(\([^)]\))')}'" 2> /dev/null) == 0 ]] || err_exit '${x:=$(..."...")} failure'
322if	[[ -d /dev/fd  && -w /dev/fd/3 ]]
323then	[[ $(cat <(print hello) ) == hello ]] || err_exit "process substitution not working outside for or while loop"
324	$SHELL -c '[[ $(for i in 1;do cat <(print hello);done ) == hello ]]' 2> /dev/null|| err_exit "process substitution not working in for or while loop"
325fi
326exec 3> /dev/null
327print 'print foo "$@"' > /tmp/ksh$$x
328[[ $( print "(/tmp/ksh$$x bar)" | $SHELL 2>/dev/null) == 'foo bar' ]] || err_exit 'script pipe to shell fails'
329print "#! $SHELL" > /tmp/ksh$$x
330print 'print  -- $0' >> /tmp/ksh$$x
331chmod +x /tmp/ksh$$x
332[[ $(/tmp/ksh$$x) == /tmp/ksh$$x ]] || err_exit  "\$0 is $0 instead of /tmp/ksh$$x"
333rm -f /tmp/ksh$$x
334exec 3<&-
335( typeset -r foo=bar) 2> /dev/null || err_exit 'readonly variables set in a subshell cannot unset'
336exit $((Errors))
337