1########################################################################
2#                                                                      #
3#               This software is part of the ast package               #
4#          Copyright (c) 1982-2014 AT&T Intellectual Property          #
5#                      and is licensed under the                       #
6#                 Eclipse Public License, Version 1.0                  #
7#                    by AT&T Intellectual Property                     #
8#                                                                      #
9#                A copy of the License is available at                 #
10#          http://www.eclipse.org/org/documents/epl-v10.html           #
11#         (with md5 checksum b35adb5213ca9657e911e9befb180842)         #
12#                                                                      #
13#              Information and Software Systems Research               #
14#                            AT&T Research                             #
15#                           Florham Park NJ                            #
16#                                                                      #
17#                    David Korn <dgkorn@gmail.com>                     #
18#                                                                      #
19########################################################################
20
21unset HISTFILE
22export LC_ALL=C ENV=
23
24if [[ $( ${SHELL-ksh} -s hello<<-\!
25	print $1
26	!
27     ) != hello ]]
28then
29    log_error "${SHELL-ksh} -s not working"
30fi
31
32x=$(
33    set -e
34    false && print bad
35    print good
36)
37if [[ $x != good ]]
38then
39    log_error 'sh -e not working'
40fi
41
42[[ $($SHELL -D -c 'print hi; print $"hello"') == '"hello"' ]] || log_error 'ksh -D not working'
43
44env=$TEST_DIR/.env
45print $'(print -u1 aha) &>/dev/null\n(print -u2 aha) &>/dev/null' > $env
46rc=$TEST_DIR/.kshrc
47print $'PS1=""\nfunction env_hit\n{\n\tprint OK\n}' > $rc
48
49export ENV=/.$env
50if [[ ! -o privileged ]]
51then
52    got=$($SHELL -E -c : 2>/dev/null)
53    if [[ $got ]]
54    then
55        got=$(printf %q "$got")
56        log_error "\$ENV file &>/dev/null does not redirect stdout -- expected '', got $got"
57    fi
58
59    got=$($SHELL -E -c : 2>&1 >/dev/null)
60    if [[ $got != *nonstandard* || $got == *$'\n'* ]]
61    then
62        got=$(printf %q "$got")
63        log_error "\$ENV file &>/dev/null does not redirect stderr -- expected one diagnostic line, got $got"
64    fi
65fi
66
67export ENV=/.$rc
68if [[ -o privileged ]]
69then
70    [[ $(print env_hit | $SHELL 2>&1) == "OK" ]] &&
71        log_error 'privileged nointeractive shell reads $ENV file'
72    [[ $(print env_hit | $SHELL -E 2>&1) == "OK" ]] &&
73        log_error 'privileged -E reads $ENV file'
74    [[ $(print env_hit | $SHELL +E 2>&1) == "OK" ]] &&
75        log_error 'privileged +E reads $ENV file'
76    [[ $(print env_hit | $SHELL --rc 2>&1) == "OK" ]] &&
77        log_error 'privileged --rc reads $ENV file'
78    [[ $(print env_hit | $SHELL --norc 2>&1) == "OK" ]] &&
79        log_error 'privileged --norc reads $ENV file'
80else
81    [[ $(print env_hit | $SHELL 2>&1) == "OK" ]] &&
82        log_error 'nointeractive shell reads $ENV file'
83    [[ $(print env_hit | $SHELL -E 2>&1) == "OK" ]] ||
84        log_error '-E ignores $ENV file'
85    [[ $(print env_hit | $SHELL +E 2>&1) == "OK" ]] &&
86        log_error '+E reads $ENV file'
87    [[ $(print env_hit | $SHELL --rc 2>&1) == "OK" ]] ||
88        log_error '--rc ignores $ENV file'
89    [[ $(print env_hit | $SHELL --norc 2>&1) == "OK" ]] &&
90        log_error '--norc reads $ENV file'
91    [[ $(print env_hit | $SHELL -i 2>&1) == "OK" ]] ||
92        log_error '-i ignores $ENV file'
93fi
94
95export ENV=
96if [[ -o privileged ]]
97then
98    [[ $(print env_hit | HOME=$TEST_DIR $SHELL 2>&1) == "OK" ]] &&
99        log_error 'privileged nointeractive shell reads $HOME/.kshrc file'
100    [[ $(print env_hit | HOME=$TEST_DIR $SHELL -E 2>&1) == "OK" ]] &&
101        log_error 'privileged -E ignores empty $ENV'
102    [[ $(print env_hit | HOME=$TEST_DIR $SHELL +E 2>&1) == "OK" ]] &&
103        log_error 'privileged +E reads $HOME/.kshrc file'
104    [[ $(print env_hit | HOME=$TEST_DIR $SHELL --rc 2>&1) == "OK" ]] &&
105        log_error 'privileged --rc ignores empty $ENV'
106    [[ $(print env_hit | HOME=$TEST_DIR $SHELL --norc 2>&1) == "OK" ]] &&
107        log_error 'privileged --norc reads $HOME/.kshrc file'
108else
109    [[ $(print env_hit | HOME=$TEST_DIR $SHELL 2>&1) == "OK" ]] &&
110        log_error 'nointeractive shell reads $HOME/.kshrc file'
111    [[ $(print env_hit | HOME=$TEST_DIR $SHELL -E 2>&1) == "OK" ]] &&
112        log_error '-E ignores empty $ENV'
113    [[ $(print env_hit | HOME=$TEST_DIR $SHELL +E 2>&1) == "OK" ]] &&
114        log_error '+E reads $HOME/.kshrc file'
115    [[ $(print env_hit | HOME=$TEST_DIR $SHELL --rc 2>&1) == "OK" ]] &&
116        log_error '--rc ignores empty $ENV'
117    [[ $(print env_hit | HOME=$TEST_DIR $SHELL --norc 2>&1) == "OK" ]] &&
118        log_error '--norc reads $HOME/.kshrc file'
119fi
120
121unset ENV
122if [[ -o privileged ]]
123then
124    [[ $(print env_hit | HOME=$TEST_DIR $SHELL 2>&1) == "OK" ]] &&
125        log_error 'privileged nointeractive shell reads $HOME/.kshrc file'
126    [[ $(print env_hit | HOME=$TEST_DIR $SHELL -E 2>&1) == "OK" ]] &&
127        log_error 'privileged -E reads $HOME/.kshrc file'
128    [[ $(print env_hit | HOME=$TEST_DIR $SHELL +E 2>&1) == "OK" ]] &&
129        log_error 'privileged +E reads $HOME/.kshrc file'
130    [[ $(print env_hit | HOME=$TEST_DIR $SHELL --rc 2>&1) == "OK" ]] &&
131        log_error 'privileged --rc reads $HOME/.kshrc file'
132    [[ $(print env_hit | HOME=$TEST_DIR $SHELL --norc 2>&1) == "OK" ]] &&
133        log_error 'privileged --norc reads $HOME/.kshrc file'
134else
135    [[ $(print env_hit | HOME=$TEST_DIR $SHELL 2>&1) == "OK" ]] &&
136        log_error 'nointeractive shell reads $HOME/.kshrc file'
137    [[ $(print env_hit | HOME=$TEST_DIR $SHELL -E 2>&1) == "OK" ]] ||
138        log_error '-E ignores $HOME/.kshrc file'
139    [[ $(print env_hit | HOME=$TEST_DIR $SHELL +E 2>&1) == "OK" ]] &&
140        log_error '+E reads $HOME/.kshrc file'
141    [[ $(print env_hit | HOME=$TEST_DIR $SHELL --rc 2>&1) == "OK" ]] ||
142        log_error '--rc ignores $HOME/.kshrc file'
143    [[ $(print env_hit | HOME=$TEST_DIR $SHELL --norc 2>&1) == "OK" ]] &&
144        log_error '--norc reads $HOME/.kshrc file'
145fi
146
147rm -rf $TEST_DIR/.kshrc
148
149if command set -G 2> /dev/null
150then
151    mkdir subdir
152    cd subdir
153    mkdir bar foo
154    > bar.c > bam.c
155    > bar/foo.c > bar/bam.c
156    > foo/bam.c
157    set -- **.c
158    expected='bam.c bar.c'
159    [[ $* == $expected ]] ||
160        log_error '-G **.c failed' "$expected" "$*"
161    set -- **
162    expected='bam.c bar bar.c bar/bam.c bar/foo.c foo foo/bam.c'
163    [[ $* == $expected ]] ||
164        log_error '-G ** failed' "$expected" "$*"
165    set -- **/*.c
166    expected='bam.c bar.c bar/bam.c bar/foo.c foo/bam.c'
167    [[ $* == $expected ]] ||
168        log_error '-G **/*.c failed' "$expected" "$*"
169    set -- **/bam.c
170    expected='bam.c bar/bam.c foo/bam.c'
171    [[ $* == $expected ]] ||
172        log_error '-G **/bam.c failed' "$expected" "$*"
173    cd ..
174fi
175
176t="<$$>.profile.<$$>"
177echo "echo '$t'" > $HOME/.profile
178cp $SHELL ./-ksh
179if [[ -o privileged ]]
180then
181    actual=$($SHELL -l </dev/null 2>&1)
182    [[ "$actual" == *$t* ]] &&
183        log_error 'privileged -l reads .profile' "*$t*" "$actual"
184    actual=$($SHELL --login </dev/null 2>&1)
185    [[ "$actual" == *$t* ]] &&
186        log_error 'privileged --login reads .profile' "*$t*" "$actual"
187    actual=$($SHELL --login-shell </dev/null 2>&1)
188    [[ "$actual" == *$t* ]] &&
189        log_error 'privileged --login-shell reads .profile' "*$t*" "$actual"
190    actual=$($SHELL --login_shell </dev/null 2>&1)
191    [[ "$actual" == *$t* ]] &&
192        log_error 'privileged --login_shell reads .profile' "*$t*" "$actual"
193    actual=$(exec -a -ksh $SHELL </dev/null 2>&1)
194    [[ "$actual" == *$t* ]] &&
195        log_error 'privileged exec -a -ksh ksh reads .profile' "*$t*" "$actual"
196    actual=$(./-ksh -i </dev/null 2>&1)
197    [[ "$actual" == *$t* ]] &&
198        log_error 'privileged ./-ksh reads .profile' "*$t*" "$actual"
199    actual=$(./-ksh -ip </dev/null 2>&1)
200    [[ "$actual" == *$t* ]] &&
201        log_error 'privileged ./-ksh -p reads .profile' "*$t*" "$actual"
202else
203    actual=$($SHELL -l </dev/null 2>&1)
204    [[ "$actual" == *$t* ]] ||
205        log_error '-l ignores .profile' "*$t*" "$actual"
206    actual=$($SHELL --login </dev/null 2>&1)
207    [[ "$actual" == *$t* ]] ||
208        log_error '--login ignores .profile' "*$t*" "$actual"
209    actual=$($SHELL --login-shell </dev/null 2>&1)
210    [[ "$actual" == *$t* ]] ||
211        log_error '--login-shell ignores .profile' "*$t*" "$actual"
212    actual=$($SHELL --login_shell </dev/null 2>&1)
213    [[ "$actual" == *$t* ]] ||
214        log_error '--login_shell ignores .profile' "*$t*" "$actual"
215    actual=$(exec -a -ksh $SHELL </dev/null 2>/dev/null)
216    [[ "$actual" == *$t* ]] ||
217        log_error 'exec -a -ksh ksh 2>/dev/null ignores .profile' "*$t*" "$actual"
218    actual=$(exec -a -ksh $SHELL </dev/null 2>&1)
219    [[ "$actual" == *$t* ]] ||
220        log_error 'exec -a -ksh ksh 2>&1 ignores .profile' "*$t*" "$actual"
221    actual=$(./-ksh -i </dev/null 2>&1)
222    [[ "$actual" == *$t* ]] ||
223        log_error './-ksh ignores .profile' "*$t*" "$actual"
224    actual=$(./-ksh -ip </dev/null 2>&1)
225    [[ "$actual" == *$t* ]] &&
226        log_error './-ksh -p does not ignore .profile' "*$t*" "$actual"
227fi
228
229cd ~-
230rm -rf $TEST_DIR/.profile
231
232# { exec interactive login_shell restricted xtrace } in the following test
233
234for opt in \
235    allexport all-export all_export bgnice bg-nice bg_nice clobber emacs \
236    errexit err-exit err_exit glob globstar glob-star glob_star gmacs \
237    ignoreeof ignore-eof ignore_eof keyword log markdirs monitor notify \
238    pipefail pipe-fail pipe_fail trackall track-all track_all \
239    unset verbose vi viraw vi-raw vi_raw
240do
241    old=$opt
242    if [[ ! -o $opt ]]
243    then
244        old=no$opt
245    fi
246
247    set --$opt || log_error "set --$opt failed"
248    [[ -o $opt ]] || log_error "[[ -o $opt ]] failed"
249    [[ -o no$opt ]] && log_error "[[ -o no$opt ]] failed"
250    [[ -o no-$opt ]] && log_error "[[ -o no-$opt ]] failed"
251    [[ -o no_$opt ]] && log_error "[[ -o no_$opt ]] failed"
252    [[ -o ?$opt ]] || log_error "[[ -o ?$opt ]] failed"
253    [[ -o ?no$opt ]] || log_error "[[ -o ?no$opt ]] failed"
254    [[ -o ?no-$opt ]] || log_error "[[ -o ?no-$opt ]] failed"
255    [[ -o ?no_$opt ]] || log_error "[[ -o ?no_$opt ]] failed"
256
257    set --no$opt || log_error "set --no$opt failed"
258    [[ -o no$opt ]] || log_error "[[ -o no$opt ]] failed"
259    [[ -o $opt ]] && log_error "[[ -o $opt ]] failed"
260
261    set --no-$opt || log_error "set --no-$opt failed"
262    [[ -o no$opt ]] || log_error "[[ -o no$opt ]] failed"
263    [[ -o $opt ]] && log_error "[[ -o $opt ]] failed"
264
265    set --no_$opt || log_error "set --no_$opt failed"
266    [[ -o no$opt ]] || log_error "[[ -o no$opt ]] failed"
267    [[ -o $opt ]] && log_error "[[ -o $opt ]] failed"
268
269    set -o $opt || log_error "set -o $opt failed"
270    [[ -o $opt ]] || log_error "[[ -o $opt ]] failed"
271    set -o $opt=1 || log_error "set -o $opt=1 failed"
272    [[ -o $opt ]] || log_error "[[ -o $opt ]] failed"
273    set -o no$opt=0 || log_error "set -o no$opt=0 failed"
274    [[ -o $opt ]] || log_error "[[ -o $opt ]] failed"
275    set --$opt=1 || log_error "set --$opt=1 failed"
276    [[ -o $opt ]] || log_error "[[ -o $opt ]] failed"
277    set --no$opt=0 || log_error "set --no$opt=0 failed"
278    [[ -o $opt ]] || log_error "[[ -o $opt ]] failed"
279
280    set -o no$opt || log_error "set -o no$opt failed"
281    [[ -o no$opt ]] || log_error "[[ -o no$opt ]] failed"
282    set -o $opt=0 || log_error "set -o $opt=0 failed"
283    [[ -o no$opt ]] || log_error "[[ -o no$opt ]] failed"
284    set -o no$opt=1 || log_error "set -o no$opt=1 failed"
285    [[ -o no$opt ]] || log_error "[[ -o no$opt ]] failed"
286    set --$opt=0 || log_error "set --$opt=0 failed"
287    [[ -o no$opt ]] || log_error "[[ -o no$opt ]] failed"
288    set --no$opt=1 || log_error "set --no$opt=1 failed"
289    [[ -o no$opt ]] || log_error "[[ -o no$opt ]] failed"
290
291    set -o no-$opt || log_error "set -o no-$opt failed"
292    [[ -o no-$opt ]] || log_error "[[ -o no-$opt ]] failed"
293
294    set -o no_$opt || log_error "set -o no_$opt failed"
295    [[ -o no_$opt ]] || log_error "[[ -o no_$opt ]] failed"
296
297    set +o $opt || log_error "set +o $opt failed"
298    [[ -o no$opt ]] || log_error "[[ -o no$opt ]] failed"
299
300    set +o no$opt || log_error "set +o no$opt failed"
301    [[ -o $opt ]] || log_error "[[ -o $opt ]] failed"
302
303    set +o no-$opt || log_error "set +o no-$opt failed"
304    [[ -o $opt ]] || log_error "[[ -o $opt ]] failed"
305
306    set +o no_$opt || log_error "set +o no_$opt failed"
307    [[ -o $opt ]] || log_error "[[ -o $opt ]] failed"
308
309    set --$old
310done
311
312for opt in \
313    exec interactive login_shell login-shell logi privileged \
314    rc restricted xtrace
315do
316    [[ -o $opt ]]
317    y=$?
318    [[ -o no$opt ]]
319    n=$?
320    case $y$n in
321    10|01)    ;;
322    *)    log_error "[[ -o $opt ]] == [[ -o no$opt ]]" ;;
323    esac
324done
325
326for opt in \
327    foo foo-bar foo_bar
328do
329    if [[ -o ?$opt ]]
330    then
331        log_error "[[ -o ?$opt ]] should fail"
332    fi
333
334    if [[ -o ?no$opt ]]
335    then
336        log_error "[[ -o ?no$opt ]] should fail"
337    fi
338done
339
340[[ $(set +o) == $(set --state) ]] || log_error "set --state different from set +o"
341set -- $(set --state)
342[[ $1 == set && $2 == --default ]] || log_error "set --state failed -- expected 'set --default *', got '$1 $2 *'"
343shift
344restore=$*
345shift
346off=
347for opt
348do
349    case $opt in
350    --not*)    opt=${opt/--/--no} ;;
351    --no*)    opt=${opt/--no/--} ;;
352    --*)    opt=${opt/--/--no} ;;
353    esac
354    off="$off $opt"
355done
356set $off
357state=$(set --state)
358default=$(set --default --state)
359[[ $state == $default ]] || log_error "set --state for default options failed: expected '$default', got '$state'"
360set $restore
361state=$(set --state)
362[[ $state == "set $restore" ]] || log_error "set --state after restore failed: expected 'set $restore', got '$state'"
363
364typeset -a pipeline
365pipeline=(
366    ( nopipefail=0 pipefail=1 command='false|true|true' )
367    ( nopipefail=0 pipefail=1 command='true|false|true' )
368    ( nopipefail=1 pipefail=1 command='true|true|false' )
369    ( nopipefail=1 pipefail=1 command='false|false|false' )
370    ( nopipefail=0 pipefail=0 command='true|true|true' )
371    ( nopipefail=0 pipefail=0 command='print hi|(sleep 1;/bin/cat)>/dev/null' )
372)
373set --nopipefail
374for ((i = 0; i < ${#pipeline[@]}; i++ ))
375do
376    eval ${pipeline[i].command}
377    status=$?
378    expected=${pipeline[i].nopipefail}
379    [[ $status == $expected ]] ||
380    log_error "--nopipefail '${pipeline[i].command}' exit status $status -- expected $expected"
381done
382ftt=0
383set --pipefail
384for ((i = 0; i < ${#pipeline[@]}; i++ ))
385do
386    eval ${pipeline[i].command}
387    status=$?
388    expected=${pipeline[i].pipefail}
389    if [[ $status != $expected ]]
390    then
391        log_error "--pipefail '${pipeline[i].command}' exit status $status -- expected $expected"
392        (( i == 0 )) && ftt=1
393    fi
394done
395
396if (( ! ftt ))
397then
398    exp=10
399    got=$(for((n=1;n<exp;n++))do $SHELL --pipefail -c '(sleep 0.1;false)|true|true' && break; done; print $n)
400    [[ $got == $exp ]] || log_error "--pipefail -c '(sleep 0.1;false)|true|true' fails with exit status 0 (after $got/$exp iterations)"
401fi
402
403for ((i=0; i < 20; i++))
404do
405    if ! x=$(true | $bin_echo 123)
406    then
407        log_error 'command substitution with wrong exit status with pipefai'
408        break
409    fi
410done
411(
412    set -o pipefail
413    false | true
414    (( $? )) || log_error 'pipe not failing in subshell with pipefail'
415) | wc >/dev/null
416
417$SHELL -c 'set -o pipefail; false | $bin_true;' && log_error 'pipefail not returning failure with sh -c'
418exp='1212 or 1221'
419got=$(
420    set --pipefail
421    pipe() { date | cat > /dev/null ;}
422    print $'1\n2' |
423    while read i
424    do
425        if pipe $TEST_DIR
426        then
427            { print -n $i; sleep 2; print -n $i; } &
428        fi
429    done
430    wait
431)
432[[ $got == @((12|21)(12|21)) ]] || log_error "& job delayed by --pipefail, expected '$exp', got '$got'"
433$SHELL -c '[[ $- == *c* ]]' || log_error 'option c not in $-'
434> $TEST_DIR/.profile
435
436for i in i l r s D E a b e f h k n t u v x B C G H
437do
438    HOME=$TEST_DIR ENV= $SHELL -$i >/dev/null 2>&1 <<- ++EOF++ || log_error "option $i not in \$-"
439	[[ \$- == *$i* ]] || exit 1
440	++EOF++
441done
442
443letters=ilrabefhknuvxBCGE
444integer j=0
445for i in interactive login restricted allexport notify errexit \
446    noglob trackall keyword noexec nounset verbose xtrace braceexpand \
447    noclobber globstar rc
448do
449    HOME=$TEST_DIR ENV= $SHELL -o $i >/dev/null 2>&1 <<- ++EOF++ || log_error "option $i not equivalent to ${letters:j:1}"
450	[[ \$- == *${letters:j:1}* ]] || exit 1
451	++EOF++
452    ((j++))
453done
454
455export ENV= PS1="(:$$:)"
456histfile=$TEST_DIR/history
457exp=$(HISTFILE=$histfile $SHELL -c $'function foo\n{\ncat\n}\ntype foo')
458for var in HISTSIZE HISTFILE
459do
460    got=$( ( HISTFILE=$histfile $SHELL +E -ic $'unset '$var$'\nfunction foo\n{\ncat\n}\ntype foo\nexit' ) 2>&1 )
461    got=${got##*"$PS1"}
462    [[ $got == "$exp" ]] || log_error "function definition inside (...) with $var unset fails -- got '$got', expected '$exp'"
463    got=$( { HISTFILE=$histfile $SHELL +E -ic $'unset '$var$'\nfunction foo\n{\ncat\n}\ntype foo\nexit' ;} 2>&1 )
464    got=${got##*"$PS1"}
465    [[ $got == "$exp" ]] || log_error "function definition inside {...;} with $var unset fails -- got '$got', expected '$exp'"
466done
467( unset HISTFILE; $SHELL -ic "HISTFILE=$histfile" 2>/dev/null ) || log_error "setting HISTFILE when not in environment fails"
468
469# the next tests loop on all combinations of
470#    { SUB PAR CMD ADD }
471
472SUB=(
473    ( BEG='$( '    END=' )'    )
474    ( BEG='${ '    END='; }'    )
475)
476PAR=(
477    ( BEG='( '    END=' )'    )
478    ( BEG='{ '    END='; }'    )
479)
480CMD=(    command-kill    script-kill    )
481ADD=(    ''        '; :'        )
482
483cd $TEST_DIR
484print $'#!'$SHELL$'\nkill -KILL $$' > command-kill
485print $'kill -KILL $$' > script-kill
486chmod +x command-kill script-kill
487export PATH=.:$PATH
488exp='Killed'
489for ((S=0; S<${#SUB[@]}; S++))
490do
491    for ((P=0; P<${#PAR[@]}; P++))
492    do
493        for ((C=0; C<${#CMD[@]}; C++))
494        do
495            for ((A=0; A<${#ADD[@]}; A++))
496            do
497                cmd="${SUB[S].BEG}${PAR[P].BEG}${CMD[C]}${PAR[P].END} 2>&1${ADD[A]}${SUB[S].END}"
498                eval got="$cmd"
499                got=${got##*': '}
500                got=${got%%'('*}
501                [[ $got == "$exp" ]] || log_error "$cmd failed -- got '$got', expected '$exp'"
502            done
503        done
504    done
505done
506
507$SHELL 2> /dev/null -c '{; true ;}' || log_error 'leading ; causes syntax error in brace group'
508$SHELL 2> /dev/null -c '(; true ;)' || log_error 'leading ; causes syntax error in parenthesis group'
509
510print 'for ((i = 0; i < ${1:-10000}; i++ )); do printf "%.*c\n" 15 x; done' > pipefail
511chmod +x pipefail
512$SHELL --pipefail -c './pipefail 10000 | sed 1q' >/dev/null 2>&1 &
513tst=$!
514{ sleep 4; kill $tst; } 2>/dev/null &
515spy=$!
516wait $tst 2>/dev/null
517status=$?
518if [[ $status == 0 || $(kill -l $status) == PIPE ]]
519then
520    kill $spy 2>/dev/null
521else
522    log_error "pipefail pipeline bypasses SIGPIPE and hangs"
523fi
524
525wait
526
527[[ $($SHELL -uc '[[ "${d1.u[z asd].revents}" ]]' 2>&1) == *'d1.u[z asd].revents'* ]] || log_error 'name of unset parameter not in error message'
528
529[[ $($SHELL 2> /dev/null -xc $'set --showme\nprint 1\n; print 2') == 1 ]] || log_error  'showme option with xtrace not working correctly'
530
531$SHELL -uc 'var=foo;unset var;: ${var%foo}' >/dev/null 2>&1 && log_error '${var%foo} should fail with set -u'
532$SHELL -uc 'var=foo;unset var;: ${!var}' >/dev/null 2>&1 && log_error '${!var} should fail with set -u'
533$SHELL -uc 'var=foo;unset var;: ${#var}' >/dev/null 2>&1 && log_error '${#var} should fail with set -u'
534$SHELL -uc 'var=foo;unset var;: ${var-OK}' >/dev/null 2>&1 || log_error '${var-OK} should not fail with set -u'
535$SHELL -uc 'var=foo;nset var;: ${var:-OK}' >/dev/null 2>&1 || log_error '${var:-OK} should not fail with set -u'
536
537z=$($SHELL 2>&1 -uc 'print ${X23456789012345}')
538[[ $z == *X23456789012345:* ]] || log_error "error message garbled with set -u got $z"
539
540# pipe hang bug fixed 2011-03-15
541float start=SECONDS toolong=3
542( $SHELL <<-EOF
543	set -o pipefail
544	(sleep $toolong;kill \$\$> /dev/null) &
545	cat $SHELL | for ((i=0; i < 5; i++))
546	do
547		date | wc > /dev/null
548		$SHELL -c 'read -N1'
549	done
550EOF
551) 2> /dev/null
552(( (SECONDS-start) > (toolong-0.5) )) && log_error "pipefail causes script to hang"
553
554# showme with arithmetic for loops
555$SHELL -n -c $'for((;1;))\ndo ; nothing\ndone'  2>/dev/null  || log_error 'showme commands give syntax error inside arithmetic for loops'
556
557#set -x
558float t1=SECONDS
559set -o pipefail
560print  | while read
561do
562        if { date | true;} ; true
563        then
564            sleep 2 &
565        fi
566done
567(( (SECONDS-t1) > .5 )) && log_error 'pipefail should not wait for background processes'
568
569# process source files from profiles as profile files
570print '. ./dotfile' > envfile
571print $'alias print=:\nprint foobar' > dotfile
572[[ $(ENV=$PWD/envfile $SHELL -i -c : 2>/dev/null) == foobar ]] &&
573    log_error 'files source from profile does not process aliases correctly'
574
575# tests the set -m puts background jobs in separate process group
576Command=$Command LINENO=$LINENO $SHELL -m  <<- \EOF
577	error_count=0
578	function log_error
579	{
580		print -u2 -n "\t"
581		print -u2 -r ${Command}[$LINENO]: "${@:1}"
582		((error_count++))
583	}
584	[[ $- == *m* ]] || log_error '$- does not contain m when monitor mode specified'
585	float t=SECONDS
586	sleep 2 & pid=$!
587	kill -KILL -$pid 2> /dev/null || log_error 'kill to background group failed'
588	wait 2> /dev/null
589	(( (SECONDS-t) > 1 )) && log_error 'kill did not kill background sleep'
590	exit $error_count
591EOF
592((error_count+=$?))
593
594# ==========
595$SHELL 2> /dev/null <<- \EOF && log_error 'unset variable with set -u on does not terminate script'
596	set -e -u -o pipefail
597	ls | while read file
598	do
599		files[${#files[*]}]=$fil
600	done
601	exit
602EOF
603
604# ==========
605actual="$($SHELL -vc 'print yes' 2>&1)"
606expect="print yes"
607[[ "$actual" =~ .*"$expect".* ]] || log_error 'incorrect output from ksh -v' "$expect" "$actual"
608