sd: remove 'ssd' driver support
[unleashed/tickless.git] / usr / src / lib / libshell / common / tests / basic.sh
blob04d2532b68219b71f4928c8593924218cd8cef25
1 ########################################################################
2 # #
3 # This software is part of the ast package #
4 # Copyright (c) 1982-2010 AT&T Intellectual Property #
5 # and is licensed under the #
6 # Common Public License, Version 1.0 #
7 # by AT&T Intellectual Property #
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 ########################################################################
20 function err_exit
22 print -u2 -n "\t"
23 print -u2 -r ${Command}[$1]: "${@:2}"
24 let Errors+=1
26 alias err_exit='err_exit $LINENO'
28 Command=${0##*/}
29 integer Errors=0
31 tmp=$(mktemp -dt) || { err_exit mktemp -dt failed; exit 1; }
32 trap "cd /; rm -rf $tmp" EXIT
34 # test basic file operations like redirection, pipes, file expansion
35 set -- \
36 go+r 0000 \
37 go-r 0044 \
38 ug=r 0330 \
39 go+w 0000 \
40 go-w 0022 \
41 ug=w 0550 \
42 go+x 0000 \
43 go-x 0011 \
44 ug=x 0660 \
45 go-rx 0055 \
46 uo-wx 0303 \
47 ug-rw 0660 \
48 o= 0007
49 while (( $# >= 2 ))
50 do umask 0
51 umask $1
52 g=$(umask)
53 [[ $g == $2 ]] || err_exit "umask 0; umask $1 failed -- expected $2, got $g"
54 shift 2
55 done
56 umask u=rwx,go=rx || err_exit "umask u=rws,go=rx failed"
57 if [[ $(umask -S) != u=rwx,g=rx,o=rx ]]
58 then err_exit 'umask -S incorrect'
60 pwd=$PWD
61 [[ $SHELL != /* ]] && SHELL=$pwd/$SHELL
62 cd $tmp || { err_exit "cd $tmp failed"; exit 1; }
63 um=$(umask -S)
64 ( umask 0777; > foobar )
65 rm -f foobar
66 > foobar
67 [[ -r foobar ]] || err_exit 'umask not being restored after subshell'
68 umask "$um"
69 rm -f foobar
70 # optimizer bug test
71 > foobar
72 for i in 1 2
73 do print foobar*
74 rm -f foobar
75 done > out
76 if [[ "$(<out)" != "foobar"$'\n'"foobar*" ]]
77 then print -u2 "optimizer bug with file expansion"
79 rm -f out foobar
80 mkdir dir
81 if [[ $(print */) != dir/ ]]
82 then err_exit 'file expansion with trailing / not working'
84 if [[ $(print *) != dir ]]
85 then err_exit 'file expansion with single file not working'
87 print hi > .foo
88 if [[ $(print *) != dir ]]
89 then err_exit 'file expansion leading . not working'
91 date > dat1 || err_exit "date > dat1 failed"
92 test -r dat1 || err_exit "dat1 is not readable"
93 x=dat1
94 cat <$x > dat2 || err_exit "cat < $x > dat2 failed"
95 cat dat1 dat2 | cat | cat | cat > dat3 || err_exit "cat pipe failed"
96 cat > dat4 <<!
97 $(date)
99 cat dat1 dat2 | cat | cat | cat > dat5 &
100 wait $!
101 set -- dat*
102 if (( $# != 5 ))
103 then err_exit "dat* matches only $# files"
105 if (command > foo\\abc) 2> /dev/null
106 then set -- foo*
107 if [[ $1 != 'foo\abc' ]]
108 then err_exit 'foo* does not match foo\abc'
111 if ( : > TT* && : > TTfoo ) 2>/dev/null
112 then set -- TT*
113 if (( $# < 2 ))
114 then err_exit 'TT* not expanding when file TT* exists'
117 cd ~- || err_exit "cd back failed"
118 cat > $tmp/script <<- !
119 #! $SHELL
120 print -r -- \$0
122 chmod 755 $tmp/script
123 if [[ $($tmp/script) != "$tmp/script" ]]
124 then err_exit '$0 not correct for #! script'
126 bar=foo
127 eval foo=\$bar
128 if [[ $foo != foo ]]
129 then err_exit 'eval foo=\$bar not working'
131 bar='foo=foo\ bar'
132 eval $bar
133 if [[ $foo != 'foo bar' ]]
134 then err_exit 'eval foo=\$bar, with bar="foo\ bar" not working'
136 cd /tmp
137 cd ../../tmp || err_exit "cd ../../tmp failed"
138 if [[ $PWD != /tmp ]]
139 then err_exit 'cd ../../tmp is not /tmp'
141 ( sleep 2; cat <<!
142 foobar
144 ) | cat > $tmp/foobar &
145 wait $!
146 foobar=$( < $tmp/foobar)
147 if [[ $foobar != foobar ]]
148 then err_exit "$foobar is not foobar"
151 print foo
152 /bin/echo bar
153 print bam
154 } > $tmp/foobar
155 if [[ $( < $tmp/foobar) != $'foo\nbar\nbam' ]]
156 then err_exit "output file pointer not shared correctly"
158 cat > $tmp/foobar <<\!
159 print foo
160 /bin/echo bar
161 print bam
163 chmod +x $tmp/foobar
164 if [[ $($tmp/foobar) != $'foo\nbar\nbam' ]]
165 then err_exit "script not working"
167 if [[ $($tmp/foobar | /bin/cat) != $'foo\nbar\nbam' ]]
168 then err_exit "script | cat not working"
170 if [[ $( $tmp/foobar) != $'foo\nbar\nbam' ]]
171 then err_exit "output file pointer not shared correctly"
173 rm -f $tmp/foobar
174 x=$( (print foo) ; (print bar) )
175 if [[ $x != $'foo\nbar' ]]
176 then err_exit " ( (print foo);(print bar ) failed"
178 x=$( (/bin/echo foo) ; (print bar) )
179 if [[ $x != $'foo\nbar' ]]
180 then err_exit " ( (/bin/echo);(print bar ) failed"
182 x=$( (/bin/echo foo) ; (/bin/echo bar) )
183 if [[ $x != $'foo\nbar' ]]
184 then err_exit " ( (/bin/echo);(/bin/echo bar ) failed"
186 cat > $tmp/script <<\!
187 if [[ -p /dev/fd/0 ]]
188 then builtin cat
189 cat - > /dev/null
190 [[ -p /dev/fd/0 ]] && print ok
191 else print no
194 chmod +x $tmp/script
195 case $( (print) | $tmp/script;:) in
196 ok) ;;
197 no) err_exit "[[ -p /dev/fd/0 ]] fails for standard input pipe" ;;
198 *) err_exit "builtin replaces standard input pipe" ;;
199 esac
200 print 'print $0' > $tmp/script
201 print ". $tmp/script" > $tmp/scriptx
202 chmod +x $tmp/scriptx
203 if [[ $($tmp/scriptx) != $tmp/scriptx ]]
204 then err_exit '$0 not correct for . script'
206 cd $tmp || { err_exit "cd $tmp failed"; exit 1; }
207 print ./b > ./a; print ./c > b; print ./d > c; print ./e > d; print "echo \"hello there\"" > e
208 chmod 755 a b c d e
209 x=$(./a)
210 if [[ $x != "hello there" ]]
211 then err_exit "nested scripts failed"
213 x=$( (./a) | cat)
214 if [[ $x != "hello there" ]]
215 then err_exit "scripts in subshells fail"
217 cd ~- || err_exit "cd back failed"
218 x=$( (/bin/echo foo) 2> /dev/null )
219 if [[ $x != foo ]]
220 then err_exit "subshell in command substitution fails"
222 exec 1>&-
223 x=$(print hello)
224 if [[ $x != hello ]]
225 then err_exit "command subsitution with stdout closed failed"
227 cd $pwd
228 x=$(cat <<\! | $SHELL
229 /bin/echo | /bin/cat
230 /bin/echo hello
233 if [[ $x != $'\n'hello ]]
234 then err_exit "$SHELL not working when standard input is a pipe"
236 x=$( (/bin/echo hello) 2> /dev/null )
237 if [[ $x != hello ]]
238 then err_exit "subshell in command substitution with 1 closed fails"
240 cat > $tmp/script <<- \!
241 read line 2> /dev/null
242 print done
244 if [[ $($SHELL $tmp/script <&-) != done ]]
245 then err_exit "executing script with 0 closed fails"
247 trap '' INT
248 cat > $tmp/script <<- \!
249 trap 'print bad' INT
250 kill -s INT $$
251 print good
253 chmod +x $tmp/script
254 if [[ $($SHELL $tmp/script) != good ]]
255 then err_exit "traps ignored by parent not ignored"
257 trap - INT
258 cat > $tmp/script <<- \!
259 read line
260 /bin/cat
262 if [[ $($SHELL $tmp/script <<!
266 ) != two ]]
267 then err_exit "standard input not positioned correctly"
269 word=$(print $'foo\nbar' | { read line; /bin/cat;})
270 if [[ $word != bar ]]
271 then err_exit "pipe to { read line; /bin/cat;} not working"
273 word=$(print $'foo\nbar' | ( read line; /bin/cat) )
274 if [[ $word != bar ]]
275 then err_exit "pipe to ( read line; /bin/cat) not working"
277 if [[ $(print x{a,b}y) != 'xay xby' ]]
278 then err_exit 'brace expansion not working'
280 if [[ $(for i in foo bar
281 do ( tgz=$(print $i)
282 print $tgz)
283 done) != $'foo\nbar' ]]
284 then err_exit 'for loop subshell optimizer bug'
286 unset a1
287 optbug()
289 set -A a1 foo bar bam
290 integer i
291 for ((i=0; i < 3; i++))
293 (( ${#a1[@]} < 2 )) && return 0
294 set -- "${a1[@]}"
295 shift
296 set -A a1 -- "$@"
297 done
298 return 1
300 optbug || err_exit 'array size optimzation bug'
301 wait # not running --pipefail which would interfere with subsequent tests
302 : $(jobs -p) # required to clear jobs for next jobs -p (interactive side effect)
303 sleep 20 &
304 pids=$!
305 if [[ $(jobs -p) != $! ]]
306 then err_exit 'jobs -p not reporting a background job'
308 sleep 20 &
309 pids="$pids $!"
310 foo()
312 set -- $(jobs -p)
313 (( $# == 2 )) || err_exit "$# jobs not reported -- 2 expected"
316 kill $pids
318 [[ $( (trap 'print alarm' ALRM; sleep 4) & sleep 2; kill -ALRM $!; sleep 2; wait) == alarm ]] || err_exit 'ALRM signal not working'
319 [[ $($SHELL -c 'trap "" HUP; $SHELL -c "(sleep 2;kill -HUP $$)& sleep 4;print done"') != done ]] && err_exit 'ignored traps not being ignored'
320 [[ $($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'
321 command exec 3<> /dev/null
322 if cat /dev/fd/3 >/dev/null 2>&1
323 then [[ $($SHELL -c 'cat <(print foo)' 2> /dev/null) == foo ]] || err_exit 'process substitution not working'
324 [[ $($SHELL -c $'tee >(grep \'1$\' > '$tmp/scriptx$') > /dev/null <<- \!!!
325 line0
326 line1
327 line2
329 wait
330 cat '$tmp/scriptx 2> /dev/null) == line1 ]] || err_exit '>() process substitution fails'
331 > $tmp/scriptx
332 [[ $($SHELL -c $'
333 for i in 1
334 do tee >(grep \'1$\' > '$tmp/scriptx$') > /dev/null <<- \!!!
335 line0
336 line1
337 line2
339 done
340 wait
341 cat '$tmp/scriptx 2>> /dev/null) == line1 ]] || err_exit '>() process substitution fails in for loop'
342 [[ $({ $SHELL -c 'cat <(for i in x y z; do print $i; done)';} 2> /dev/null) == $'x\ny\nz' ]] ||
343 err_exit 'process substitution of compound commands not working'
345 [[ $($SHELL -r 'command -p :' 2>&1) == *restricted* ]] || err_exit 'command -p not restricted'
346 print cat > $tmp/scriptx
347 chmod +x $tmp/scriptx
348 [[ $($SHELL -c "print foo | $tmp/scriptx ;:" 2> /dev/null ) == foo ]] || err_exit 'piping into script fails'
349 [[ $($SHELL -c 'X=1;print -r -- ${X:=$(expr "a(0)" : '"'a*(\([^)]\))')}'" 2> /dev/null) == 1 ]] || err_exit 'x=1;${x:=$(..."...")} failure'
350 [[ $($SHELL -c 'print -r -- ${X:=$(expr "a(0)" : '"'a*(\([^)]\))')}'" 2> /dev/null) == 0 ]] || err_exit '${x:=$(..."...")} failure'
351 exec 3<&-
352 if [[ -d /dev/fd && -w /dev/fd/3 ]]
353 then [[ $(cat <(print hello) ) == hello ]] || err_exit "process substitution not working outside for or while loop"
354 $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"
356 exec 3> /dev/null
357 print 'print foo "$@"' > $tmp/scriptx
358 [[ $( print "($tmp/scriptx bar)" | $SHELL 2>/dev/null) == 'foo bar' ]] || err_exit 'script pipe to shell fails'
359 print "#! $SHELL" > $tmp/scriptx
360 print 'print -- $0' >> $tmp/scriptx
361 chmod +x $tmp/scriptx
362 [[ $($tmp/scriptx) == $tmp/scriptx ]] || err_exit "\$0 is $0 instead of $tmp/scriptx"
363 cat > $tmp/scriptx <<- \EOF
364 myfilter() { x=$(print ok | cat); print -r -- $SECONDS;}
365 set -o pipefail
366 sleep 3 | myfilter
368 (( $($SHELL $tmp/scriptx) > 2.0 )) && err_exit 'command substitution causes pipefail option to hang'
369 exec 3<&-
370 ( typeset -r foo=bar) 2> /dev/null || err_exit 'readonly variables set in a subshell cannot unset'
371 $SHELL -c 'x=${ print hello;}; [[ $x == hello ]]' 2> /dev/null || err_exit '${ command;} not supported'
372 $SHELL 2> /dev/null <<- \EOF || err_exit 'multiline ${...} command substitution not supported'
373 x=${
374 print hello
376 [[ $x == hello ]]
378 $SHELL 2> /dev/null <<- \EOF || err_exit '${...} command substitution with side effects not supported '
379 y=bye
380 x=${
381 y=hello
382 print hello
384 [[ $y == $x ]]
386 $SHELL 2> /dev/null <<- \EOF || err_exit 'nested ${...} command substitution not supported'
387 x=${
388 print ${ print hello;} $(print world)
390 [[ $x == 'hello world' ]]
392 $SHELL 2> /dev/null <<- \EOF || err_exit 'terminating } is not a reserved word with ${ command }'
393 x=${ { print -n } ; print -n hello ; } ; print ' world' }
394 [[ $x == '}hello world' ]]
396 $SHELL 2> /dev/null <<- \EOF || err_exit '${ command;}xxx not working'
399 print foo
401 [[ ${ f;}bar == foobar ]]
404 unset foo
405 [[ ! ${foo[@]} ]] || err_exit '${foo[@]} is not empty when foo is unset'
406 [[ ! ${foo[3]} ]] || err_exit '${foo[3]} is not empty when foo is unset'
407 [[ $(print "[${ print foo }]") == '[foo]' ]] || err_exit '${...} not working when } is followed by ]'
408 [[ $(print "${ print "[${ print foo }]" }") == '[foo]' ]] || err_exit 'nested ${...} not working when } is followed by ]'
409 unset foo
410 foo=$(false) > /dev/null && err_exit 'failed command substitution with redirection not returning false'
411 expected=foreback
412 got=$(print -n fore;(sleep 2;print back)&)
413 [[ $got == $expected ]] || err_exit "command substitution background process output error -- got '$got', expected '$expected'"
415 binfalse=$(whence -p false)
416 for false in false $binfalse
417 do x=$($false) && err_exit "x=\$($false) should fail"
418 $($false) && err_exit "\$($false) should fail"
419 $($false) > /dev/null && err_exit "\$($false) > /dev/null should fail"
420 done
421 if env x-a=y >/dev/null 2>&1
422 then [[ $(env 'x-a=y' $SHELL -c 'env | grep x-a') == *x-a=y* ]] || err_exit 'invalid environment variables not preserved'
424 float s=SECONDS
425 sleep=$(whence -p sleep)
426 for i in 1 2
427 do print $i
428 done | while read sec; do ( $sleep $sec; $sleep $sec) done
429 (( (SECONDS-s) < 4)) && err_exit '"command | while read...done" finishing too fast'
430 s=SECONDS
431 set -o pipefail
432 for ((i=0; i < 30; i++))
433 do print hello
434 sleep .1
435 done | $sleep 1
436 (( (SECONDS-s) < 2 )) || err_exit 'early termination not causing broken pipe'
437 [[ $({ trap 'print trap' 0; print -n | $(whence -p cat); } & wait $!) == trap ]] || err_exit 'trap on exit not getting triggered'
438 var=$({ trap 'print trap' ERR; print -n | $binfalse; } & wait $!)
439 [[ $var == trap ]] || err_exit 'trap on ERR not getting triggered'
441 exp=
442 got=$(
443 function fun
445 $binfalse && echo FAILED
447 : works if this line deleted : |
449 : works if this line deleted :
451 [[ $got == $exp ]] || err_exit "pipe to function with conditional fails -- expected '$exp', got '$got'"
452 got=$(
453 : works if this line deleted : |
454 { $binfalse && echo FAILED; }
455 : works if this line deleted :
457 [[ $got == $exp ]] || err_exit "pipe to { ... } with conditional fails -- expected '$exp', got '$got'"
459 got=$(
460 : works if this line deleted : |
461 ( $binfalse && echo FAILED )
462 : works if this line deleted :
464 [[ $got == $exp ]] || err_exit "pipe to ( ... ) with conditional fails -- expected '$exp', got '$got'"
466 ( $SHELL -c 'trap : DEBUG; x=( $foo); exit 0') 2> /dev/null || err_exit 'trap DEBUG fails'
468 true=$(whence -p true)
469 set -o pipefail
470 float start=$SECONDS end
471 for ((i=0; i < 2; i++))
472 do print foo
473 sleep 1.5
474 done | { read; $true; end=$SECONDS ;}
475 (( (SECONDS-start) < 1 )) && err_exit "pipefail not waiting for pipe to finish"
476 set +o pipefail
477 (( (SECONDS-start) > 2 )) && err_exit "pipefail causing /bin/true to wait for other end of pipe"
480 { env A__z=C+SHLVL $SHELL -c : ;} 2> /dev/null || err_exit "SHLVL with wrong attribute fails"
482 exit $((Errors))