xref: /titanic_50/usr/src/lib/libshell/common/tests/options.sh (revision 3e14f97f673e8a630f076077de35afdd43dc1587)
1da2e3ebdSchin########################################################################
2da2e3ebdSchin#                                                                      #
3da2e3ebdSchin#               This software is part of the ast package               #
4*3e14f97fSRoger A. Faulkner#          Copyright (c) 1982-2010 AT&T Intellectual Property          #
5da2e3ebdSchin#                      and is licensed under the                       #
6da2e3ebdSchin#                  Common Public License, Version 1.0                  #
77c2fbfb3SApril Chin#                    by AT&T Intellectual Property                     #
8da2e3ebdSchin#                                                                      #
9da2e3ebdSchin#                A copy of the License is available at                 #
10da2e3ebdSchin#            http://www.opensource.org/licenses/cpl1.0.txt             #
11da2e3ebdSchin#         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         #
12da2e3ebdSchin#                                                                      #
13da2e3ebdSchin#              Information and Software Systems Research               #
14da2e3ebdSchin#                            AT&T Research                             #
15da2e3ebdSchin#                           Florham Park NJ                            #
16da2e3ebdSchin#                                                                      #
17da2e3ebdSchin#                  David Korn <dgk@research.att.com>                   #
18da2e3ebdSchin#                                                                      #
19da2e3ebdSchin########################################################################
20da2e3ebdSchinfunction err_exit
21da2e3ebdSchin{
22da2e3ebdSchin	print -u2 -n "\t"
23da2e3ebdSchin	print -u2 -r ${Command}[$1]: "${@:2}"
24da2e3ebdSchin	let Errors+=1
25da2e3ebdSchin}
26da2e3ebdSchinalias err_exit='err_exit $LINENO'
27da2e3ebdSchin
28da2e3ebdSchinCommand=${0##*/}
29da2e3ebdSchininteger Errors=0
307c2fbfb3SApril Chin
317c2fbfb3SApril Chinunset HISTFILE
3234f9b3eeSRoland Mainzexport LC_ALL=C ENV=
3334f9b3eeSRoland Mainz
3434f9b3eeSRoland Mainzulimit -c 0
3534f9b3eeSRoland Mainz
3634f9b3eeSRoland Mainztmp=$(mktemp -dt) || { err_exit mktemp -dt failed; exit 1; }
3734f9b3eeSRoland Mainztrap "cd /; rm -rf $tmp" EXIT
387c2fbfb3SApril Chin
39da2e3ebdSchinif	[[ $( ${SHELL-ksh} -s hello<<-\!
40da2e3ebdSchin		print $1
41da2e3ebdSchin		!
42da2e3ebdSchin	 ) != hello ]]
43da2e3ebdSchinthen	err_exit "${SHELL-ksh} -s not working"
44da2e3ebdSchinfi
45da2e3ebdSchinx=$(
46da2e3ebdSchin	set -e
47da2e3ebdSchin	false && print bad
48da2e3ebdSchin	print good
49da2e3ebdSchin)
50da2e3ebdSchinif	[[ $x != good ]]
5134f9b3eeSRoland Mainzthen	err_exit 'sh -e not working'
52da2e3ebdSchinfi
53da2e3ebdSchin[[ $($SHELL -D -c 'print hi; print $"hello"') == '"hello"' ]] || err_exit 'ksh -D not working'
54da2e3ebdSchin
5534f9b3eeSRoland Mainzenv=$tmp/.env
5634f9b3eeSRoland Mainzprint $'(print -u1 aha) &>/dev/null\n(print -u2 aha) &>/dev/null' > $env
57da2e3ebdSchinrc=$tmp/.kshrc
587c2fbfb3SApril Chinprint $'PS1=""\nfunction env_hit\n{\n\tprint OK\n}' > $rc
59da2e3ebdSchin
6034f9b3eeSRoland Mainzexport ENV=/.$env
6134f9b3eeSRoland Mainzif	[[ ! -o privileged ]]
6234f9b3eeSRoland Mainzthen
6334f9b3eeSRoland Mainz	got=$($SHELL -E -c : 2>/dev/null)
6434f9b3eeSRoland Mainz	if	[[ $g ]]
6534f9b3eeSRoland Mainz	then
6634f9b3eeSRoland Mainz		got=$(printf %q "$got")
6734f9b3eeSRoland Mainz		err_exit "\$ENV file &>/dev/null does not redirect stdout -- expected '', got $got"
6834f9b3eeSRoland Mainz	fi
6934f9b3eeSRoland Mainz	got=$($SHELL -E -c : 2>&1 >/dev/null)
7034f9b3eeSRoland Mainz	if	[[ $got != *nonstandard* || $got == *$'\n'* ]]
7134f9b3eeSRoland Mainz	then
7234f9b3eeSRoland Mainz		got=$(printf %q "$got")
7334f9b3eeSRoland Mainz		err_exit "\$ENV file &>/dev/null does not redirect stderr -- expected one diagnostic line, got $got"
7434f9b3eeSRoland Mainz	fi
7534f9b3eeSRoland Mainzfi
7634f9b3eeSRoland Mainz
7734f9b3eeSRoland Mainzexport ENV=/.$rc
78da2e3ebdSchinif	[[ -o privileged ]]
79da2e3ebdSchinthen
8034f9b3eeSRoland Mainz	[[ $(print env_hit | $SHELL 2>&1) == "OK" ]] &&
81da2e3ebdSchin		err_exit 'privileged nointeractive shell reads $ENV file'
8234f9b3eeSRoland Mainz	[[ $(print env_hit | $SHELL -E 2>&1) == "OK" ]] &&
83da2e3ebdSchin		err_exit 'privileged -E reads $ENV file'
8434f9b3eeSRoland Mainz	[[ $(print env_hit | $SHELL +E 2>&1) == "OK" ]] &&
85da2e3ebdSchin		err_exit 'privileged +E reads $ENV file'
8634f9b3eeSRoland Mainz	[[ $(print env_hit | $SHELL --rc 2>&1) == "OK" ]] &&
87da2e3ebdSchin		err_exit 'privileged --rc reads $ENV file'
8834f9b3eeSRoland Mainz	[[ $(print env_hit | $SHELL --norc 2>&1) == "OK" ]] &&
89da2e3ebdSchin		err_exit 'privileged --norc reads $ENV file'
90da2e3ebdSchinelse
9134f9b3eeSRoland Mainz	[[ $(print env_hit | $SHELL 2>&1) == "OK" ]] &&
92da2e3ebdSchin		err_exit 'nointeractive shell reads $ENV file'
9334f9b3eeSRoland Mainz	[[ $(print env_hit | $SHELL -E 2>&1) == "OK" ]] ||
94da2e3ebdSchin		err_exit '-E ignores $ENV file'
9534f9b3eeSRoland Mainz	[[ $(print env_hit | $SHELL +E 2>&1) == "OK" ]] &&
96da2e3ebdSchin		err_exit '+E reads $ENV file'
9734f9b3eeSRoland Mainz	[[ $(print env_hit | $SHELL --rc 2>&1) == "OK" ]] ||
98da2e3ebdSchin		err_exit '--rc ignores $ENV file'
9934f9b3eeSRoland Mainz	[[ $(print env_hit | $SHELL --norc 2>&1) == "OK" ]] &&
100da2e3ebdSchin		err_exit '--norc reads $ENV file'
10134f9b3eeSRoland Mainz	[[ $(print env_hit | $SHELL -i 2>&1) == "OK" ]] ||
1027c2fbfb3SApril Chin		err_exit '-i ignores $ENV file'
103da2e3ebdSchinfi
104da2e3ebdSchin
105da2e3ebdSchinexport ENV=
106da2e3ebdSchinif	[[ -o privileged ]]
107da2e3ebdSchinthen
10834f9b3eeSRoland Mainz	[[ $(print env_hit | HOME=$tmp $SHELL 2>&1) == "OK" ]] &&
109da2e3ebdSchin		err_exit 'privileged nointeractive shell reads $HOME/.kshrc file'
11034f9b3eeSRoland Mainz	[[ $(print env_hit | HOME=$tmp $SHELL -E 2>&1) == "OK" ]] &&
111da2e3ebdSchin		err_exit 'privileged -E ignores empty $ENV'
11234f9b3eeSRoland Mainz	[[ $(print env_hit | HOME=$tmp $SHELL +E 2>&1) == "OK" ]] &&
113da2e3ebdSchin		err_exit 'privileged +E reads $HOME/.kshrc file'
11434f9b3eeSRoland Mainz	[[ $(print env_hit | HOME=$tmp $SHELL --rc 2>&1) == "OK" ]] &&
115da2e3ebdSchin		err_exit 'privileged --rc ignores empty $ENV'
11634f9b3eeSRoland Mainz	[[ $(print env_hit | HOME=$tmp $SHELL --norc 2>&1) == "OK" ]] &&
117da2e3ebdSchin		err_exit 'privileged --norc reads $HOME/.kshrc file'
118da2e3ebdSchinelse
11934f9b3eeSRoland Mainz	[[ $(print env_hit | HOME=$tmp $SHELL 2>&1) == "OK" ]] &&
120da2e3ebdSchin		err_exit 'nointeractive shell reads $HOME/.kshrc file'
12134f9b3eeSRoland Mainz	[[ $(print env_hit | HOME=$tmp $SHELL -E 2>&1) == "OK" ]] &&
122da2e3ebdSchin		err_exit '-E ignores empty $ENV'
12334f9b3eeSRoland Mainz	[[ $(print env_hit | HOME=$tmp $SHELL +E 2>&1) == "OK" ]] &&
124da2e3ebdSchin		err_exit '+E reads $HOME/.kshrc file'
12534f9b3eeSRoland Mainz	[[ $(print env_hit | HOME=$tmp $SHELL --rc 2>&1) == "OK" ]] &&
126da2e3ebdSchin		err_exit '--rc ignores empty $ENV'
12734f9b3eeSRoland Mainz	[[ $(print env_hit | HOME=$tmp $SHELL --norc 2>&1) == "OK" ]] &&
128da2e3ebdSchin		err_exit '--norc reads $HOME/.kshrc file'
129da2e3ebdSchinfi
130da2e3ebdSchin
131da2e3ebdSchinunset ENV
132da2e3ebdSchinif	[[ -o privileged ]]
133da2e3ebdSchinthen
13434f9b3eeSRoland Mainz	[[ $(print env_hit | HOME=$tmp $SHELL 2>&1) == "OK" ]] &&
135da2e3ebdSchin		err_exit 'privileged nointeractive shell reads $HOME/.kshrc file'
13634f9b3eeSRoland Mainz	[[ $(print env_hit | HOME=$tmp $SHELL -E 2>&1) == "OK" ]] &&
137da2e3ebdSchin		err_exit 'privileged -E reads $HOME/.kshrc file'
13834f9b3eeSRoland Mainz	[[ $(print env_hit | HOME=$tmp $SHELL +E 2>&1) == "OK" ]] &&
139da2e3ebdSchin		err_exit 'privileged +E reads $HOME/.kshrc file'
14034f9b3eeSRoland Mainz	[[ $(print env_hit | HOME=$tmp $SHELL --rc 2>&1) == "OK" ]] &&
141da2e3ebdSchin		err_exit 'privileged --rc reads $HOME/.kshrc file'
14234f9b3eeSRoland Mainz	[[ $(print env_hit | HOME=$tmp $SHELL --norc 2>&1) == "OK" ]] &&
143da2e3ebdSchin		err_exit 'privileged --norc reads $HOME/.kshrc file'
144da2e3ebdSchinelse
14534f9b3eeSRoland Mainz	[[ $(print env_hit | HOME=$tmp $SHELL 2>&1) == "OK" ]] &&
146da2e3ebdSchin		err_exit 'nointeractive shell reads $HOME/.kshrc file'
14734f9b3eeSRoland Mainz	[[ $(print env_hit | HOME=$tmp $SHELL -E 2>&1) == "OK" ]] ||
148da2e3ebdSchin		err_exit '-E ignores $HOME/.kshrc file'
14934f9b3eeSRoland Mainz	[[ $(print env_hit | HOME=$tmp $SHELL +E 2>&1) == "OK" ]] &&
150da2e3ebdSchin		err_exit '+E reads $HOME/.kshrc file'
15134f9b3eeSRoland Mainz	[[ $(print env_hit | HOME=$tmp $SHELL --rc 2>&1) == "OK" ]] ||
152da2e3ebdSchin		err_exit '--rc ignores $HOME/.kshrc file'
15334f9b3eeSRoland Mainz	[[ $(print env_hit | HOME=$tmp $SHELL --norc 2>&1) == "OK" ]] &&
154da2e3ebdSchin		err_exit '--norc reads $HOME/.kshrc file'
155da2e3ebdSchinfi
156da2e3ebdSchin
15734f9b3eeSRoland Mainzrm -rf $tmp/.kshrc
158da2e3ebdSchin
159da2e3ebdSchinif	command set -G 2> /dev/null
16034f9b3eeSRoland Mainzthen	cd $tmp
161da2e3ebdSchin	mkdir bar foo
162da2e3ebdSchin	> bar.c > bam.c
163da2e3ebdSchin	> bar/foo.c > bar/bam.c
164da2e3ebdSchin	> foo/bam.c
165da2e3ebdSchin	set -- **.c
166da2e3ebdSchin	expected='bam.c bar.c'
167da2e3ebdSchin	[[ $* == $expected ]] ||
168da2e3ebdSchin		err_exit "-G **.c failed -- expected '$expected', got '$*'"
169da2e3ebdSchin	set -- **
170da2e3ebdSchin	expected='bam.c bar bar.c bar/bam.c bar/foo.c foo foo/bam.c'
171da2e3ebdSchin	[[ $* == $expected ]] ||
172da2e3ebdSchin		err_exit "-G ** failed -- expected '$expected', got '$*'"
173da2e3ebdSchin	set -- **/*.c
174da2e3ebdSchin	expected='bam.c bar.c bar/bam.c bar/foo.c foo/bam.c'
175da2e3ebdSchin	[[ $* == $expected ]] ||
176da2e3ebdSchin		err_exit "-G **/*.c failed -- expected '$expected', got '$*'"
177da2e3ebdSchin	set -- **/bam.c
178da2e3ebdSchin	expected='bam.c bar/bam.c foo/bam.c'
179da2e3ebdSchin	[[ $* == $expected ]] ||
180da2e3ebdSchin		err_exit "-G **/bam.c failed -- expected '$expected', got '$*'"
181da2e3ebdSchin	cd ~-
182da2e3ebdSchinfi
183da2e3ebdSchin
18434f9b3eeSRoland Mainzcd $tmp
185da2e3ebdSchint="<$$>.profile.<$$>"
186da2e3ebdSchinecho "echo '$t'" > .profile
187da2e3ebdSchincp $SHELL ./-ksh
188da2e3ebdSchinif	[[ -o privileged ]]
189da2e3ebdSchinthen
19034f9b3eeSRoland Mainz	[[ $(HOME=$PWD $SHELL -l </dev/null 2>&1) == *$t* ]] &&
191da2e3ebdSchin		err_exit 'privileged -l reads .profile'
19234f9b3eeSRoland Mainz	[[ $(HOME=$PWD $SHELL --login </dev/null 2>&1) == *$t* ]] &&
193da2e3ebdSchin		err_exit 'privileged --login reads .profile'
19434f9b3eeSRoland Mainz	[[ $(HOME=$PWD $SHELL --login-shell </dev/null 2>&1) == *$t* ]] &&
195da2e3ebdSchin		err_exit 'privileged --login-shell reads .profile'
19634f9b3eeSRoland Mainz	[[ $(HOME=$PWD $SHELL --login_shell </dev/null 2>&1) == *$t* ]] &&
197da2e3ebdSchin		err_exit 'privileged --login_shell reads .profile'
19834f9b3eeSRoland Mainz	[[ $(HOME=$PWD exec -a -ksh $SHELL </dev/null 2>&1) == *$t* ]] &&
199da2e3ebdSchin		err_exit 'privileged exec -a -ksh ksh reads .profile'
20034f9b3eeSRoland Mainz	[[ $(HOME=$PWD ./-ksh -i </dev/null 2>&1) == *$t* ]] &&
201da2e3ebdSchin		err_exit 'privileged ./-ksh reads .profile'
20234f9b3eeSRoland Mainz	[[ $(HOME=$PWD ./-ksh -ip </dev/null 2>&1) == *$t* ]] &&
203da2e3ebdSchin		err_exit 'privileged ./-ksh -p reads .profile'
204da2e3ebdSchinelse
20534f9b3eeSRoland Mainz	[[ $(HOME=$PWD $SHELL -l </dev/null 2>&1) == *$t* ]] ||
206da2e3ebdSchin		err_exit '-l ignores .profile'
20734f9b3eeSRoland Mainz	[[ $(HOME=$PWD $SHELL --login </dev/null 2>&1) == *$t* ]] ||
208da2e3ebdSchin		err_exit '--login ignores .profile'
20934f9b3eeSRoland Mainz	[[ $(HOME=$PWD $SHELL --login-shell </dev/null 2>&1) == *$t* ]] ||
210da2e3ebdSchin		err_exit '--login-shell ignores .profile'
21134f9b3eeSRoland Mainz	[[ $(HOME=$PWD $SHELL --login_shell </dev/null 2>&1) == *$t* ]] ||
212da2e3ebdSchin		err_exit '--login_shell ignores .profile'
2137c2fbfb3SApril Chin	[[ $(HOME=$PWD exec -a -ksh $SHELL </dev/null 2>/dev/null) == *$t* ]] ||
21434f9b3eeSRoland Mainz		err_exit 'exec -a -ksh ksh 2>/dev/null ignores .profile'
21534f9b3eeSRoland Mainz	[[ $(HOME=$PWD exec -a -ksh $SHELL </dev/null 2>&1) == *$t* ]] ||
21634f9b3eeSRoland Mainz		err_exit 'exec -a -ksh ksh 2>&1 ignores .profile'
21734f9b3eeSRoland Mainz	[[ $(HOME=$PWD ./-ksh -i </dev/null 2>&1) == *$t* ]] ||
218da2e3ebdSchin		err_exit './-ksh ignores .profile'
21934f9b3eeSRoland Mainz	[[ $(HOME=$PWD ./-ksh -ip </dev/null 2>&1) == *$t* ]] &&
220da2e3ebdSchin		err_exit './-ksh -p does not ignore .profile'
221da2e3ebdSchinfi
222da2e3ebdSchincd ~-
22334f9b3eeSRoland Mainzrm -rf $tmp/.profile
224da2e3ebdSchin
225da2e3ebdSchin# { exec interactive login_shell restricted xtrace } in the following test
226da2e3ebdSchin
227da2e3ebdSchinfor opt in \
228da2e3ebdSchin	allexport all-export all_export \
229da2e3ebdSchin	bgnice bg-nice bg_nice \
230da2e3ebdSchin	clobber emacs \
231da2e3ebdSchin	errexit err-exit err_exit \
232da2e3ebdSchin	glob \
233da2e3ebdSchin	globstar glob-star glob_star \
234da2e3ebdSchin	gmacs \
235da2e3ebdSchin	ignoreeof ignore-eof ignore_eof \
236da2e3ebdSchin	keyword log markdirs monitor notify \
237da2e3ebdSchin	pipefail pipe-fail pipe_fail \
238da2e3ebdSchin	trackall track-all track_all \
239da2e3ebdSchin	unset verbose vi \
240da2e3ebdSchin	viraw vi-raw vi_raw
241da2e3ebdSchindo	old=$opt
242da2e3ebdSchin	if [[ ! -o $opt ]]
243da2e3ebdSchin	then	old=no$opt
244da2e3ebdSchin	fi
245da2e3ebdSchin
246da2e3ebdSchin	set --$opt || err_exit "set --$opt failed"
247da2e3ebdSchin	[[ -o $opt ]] || err_exit "[[ -o $opt ]] failed"
248da2e3ebdSchin	[[ -o no$opt ]] && err_exit "[[ -o no$opt ]] failed"
249da2e3ebdSchin	[[ -o no-$opt ]] && err_exit "[[ -o no-$opt ]] failed"
250da2e3ebdSchin	[[ -o no_$opt ]] && err_exit "[[ -o no_$opt ]] failed"
251da2e3ebdSchin	[[ -o ?$opt ]] || err_exit "[[ -o ?$opt ]] failed"
252da2e3ebdSchin	[[ -o ?no$opt ]] || err_exit "[[ -o ?no$opt ]] failed"
253da2e3ebdSchin	[[ -o ?no-$opt ]] || err_exit "[[ -o ?no-$opt ]] failed"
254da2e3ebdSchin	[[ -o ?no_$opt ]] || err_exit "[[ -o ?no_$opt ]] failed"
255da2e3ebdSchin
256da2e3ebdSchin	set --no$opt || err_exit "set --no$opt failed"
257da2e3ebdSchin	[[ -o no$opt ]] || err_exit "[[ -o no$opt ]] failed"
258da2e3ebdSchin	[[ -o $opt ]] && err_exit "[[ -o $opt ]] failed"
259da2e3ebdSchin
260da2e3ebdSchin	set --no-$opt || err_exit "set --no-$opt failed"
261da2e3ebdSchin	[[ -o no$opt ]] || err_exit "[[ -o no$opt ]] failed"
262da2e3ebdSchin	[[ -o $opt ]] && err_exit "[[ -o $opt ]] failed"
263da2e3ebdSchin
264da2e3ebdSchin	set --no_$opt || err_exit "set --no_$opt failed"
265da2e3ebdSchin	[[ -o no$opt ]] || err_exit "[[ -o no$opt ]] failed"
266da2e3ebdSchin	[[ -o $opt ]] && err_exit "[[ -o $opt ]] failed"
267da2e3ebdSchin
268da2e3ebdSchin	set -o $opt || err_exit "set -o $opt failed"
269da2e3ebdSchin	[[ -o $opt ]] || err_exit "[[ -o $opt ]] failed"
270da2e3ebdSchin	set -o $opt=1 || err_exit "set -o $opt=1 failed"
271da2e3ebdSchin	[[ -o $opt ]] || err_exit "[[ -o $opt ]] failed"
272da2e3ebdSchin	set -o no$opt=0 || err_exit "set -o no$opt=0 failed"
273da2e3ebdSchin	[[ -o $opt ]] || err_exit "[[ -o $opt ]] failed"
274da2e3ebdSchin	set --$opt=1 || err_exit "set --$opt=1 failed"
275da2e3ebdSchin	[[ -o $opt ]] || err_exit "[[ -o $opt ]] failed"
276da2e3ebdSchin	set --no$opt=0 || err_exit "set --no$opt=0 failed"
277da2e3ebdSchin	[[ -o $opt ]] || err_exit "[[ -o $opt ]] failed"
278da2e3ebdSchin
279da2e3ebdSchin	set -o no$opt || err_exit "set -o no$opt failed"
280da2e3ebdSchin	[[ -o no$opt ]] || err_exit "[[ -o no$opt ]] failed"
281da2e3ebdSchin	set -o $opt=0 || err_exit "set -o $opt=0 failed"
282da2e3ebdSchin	[[ -o no$opt ]] || err_exit "[[ -o no$opt ]] failed"
283da2e3ebdSchin	set -o no$opt=1 || err_exit "set -o no$opt=1 failed"
284da2e3ebdSchin	[[ -o no$opt ]] || err_exit "[[ -o no$opt ]] failed"
285da2e3ebdSchin	set --$opt=0 || err_exit "set --$opt=0 failed"
286da2e3ebdSchin	[[ -o no$opt ]] || err_exit "[[ -o no$opt ]] failed"
287da2e3ebdSchin	set --no$opt=1 || err_exit "set --no$opt=1 failed"
288da2e3ebdSchin	[[ -o no$opt ]] || err_exit "[[ -o no$opt ]] failed"
289da2e3ebdSchin
290da2e3ebdSchin	set -o no-$opt || err_exit "set -o no-$opt failed"
291da2e3ebdSchin	[[ -o no-$opt ]] || err_exit "[[ -o no-$opt ]] failed"
292da2e3ebdSchin
293da2e3ebdSchin	set -o no_$opt || err_exit "set -o no_$opt failed"
294da2e3ebdSchin	[[ -o no_$opt ]] || err_exit "[[ -o no_$opt ]] failed"
295da2e3ebdSchin
296da2e3ebdSchin	set +o $opt || err_exit "set +o $opt failed"
297da2e3ebdSchin	[[ -o no$opt ]] || err_exit "[[ -o no$opt ]] failed"
298da2e3ebdSchin
299da2e3ebdSchin	set +o no$opt || err_exit "set +o no$opt failed"
300da2e3ebdSchin	[[ -o $opt ]] || err_exit "[[ -o $opt ]] failed"
301da2e3ebdSchin
302da2e3ebdSchin	set +o no-$opt || err_exit "set +o no-$opt failed"
303da2e3ebdSchin	[[ -o $opt ]] || err_exit "[[ -o $opt ]] failed"
304da2e3ebdSchin
305da2e3ebdSchin	set +o no_$opt || err_exit "set +o no_$opt failed"
306da2e3ebdSchin	[[ -o $opt ]] || err_exit "[[ -o $opt ]] failed"
307da2e3ebdSchin
308da2e3ebdSchin	set --$old
309da2e3ebdSchindone
310da2e3ebdSchin
311da2e3ebdSchinfor opt in \
312da2e3ebdSchin	exec interactive login_shell login-shell logi privileged \
313da2e3ebdSchin	rc restricted xtrace
314da2e3ebdSchindo	[[ -o $opt ]]
315da2e3ebdSchin	y=$?
316da2e3ebdSchin	[[ -o no$opt ]]
317da2e3ebdSchin	n=$?
318da2e3ebdSchin	case $y$n in
319da2e3ebdSchin	10|01)	;;
320da2e3ebdSchin	*)	err_exit "[[ -o $opt ]] == [[ -o no$opt ]]" ;;
321da2e3ebdSchin	esac
322da2e3ebdSchindone
323da2e3ebdSchin
324da2e3ebdSchinfor opt in \
325da2e3ebdSchin	foo foo-bar foo_bar
326da2e3ebdSchindo	if	[[ -o ?$opt ]]
327da2e3ebdSchin	then	err_exit "[[ -o ?$opt ]] should fail"
328da2e3ebdSchin	fi
329da2e3ebdSchin	if	[[ -o ?no$opt ]]
330da2e3ebdSchin	then	err_exit "[[ -o ?no$opt ]] should fail"
331da2e3ebdSchin	fi
332da2e3ebdSchindone
3337c2fbfb3SApril Chin
3347c2fbfb3SApril Chin[[ $(set +o) == $(set --state) ]] || err_exit "set --state different from set +o"
3357c2fbfb3SApril Chinset -- $(set --state)
3367c2fbfb3SApril Chin[[ $1 == set && $2 == --default ]] || err_exit "set --state failed -- expected 'set --default *', got '$1 $2 *'"
3377c2fbfb3SApril Chinshift
3387c2fbfb3SApril Chinrestore=$*
3397c2fbfb3SApril Chinshift
3407c2fbfb3SApril Chinoff=
3417c2fbfb3SApril Chinfor opt
3427c2fbfb3SApril Chindo	case $opt in
3437c2fbfb3SApril Chin	--not*)	opt=${opt/--/--no} ;;
3447c2fbfb3SApril Chin	--no*)	opt=${opt/--no/--} ;;
3457c2fbfb3SApril Chin	--*)	opt=${opt/--/--no} ;;
3467c2fbfb3SApril Chin	esac
3477c2fbfb3SApril Chin	off="$off $opt"
3487c2fbfb3SApril Chindone
3497c2fbfb3SApril Chinset $off
3507c2fbfb3SApril Chinstate=$(set --state)
3517c2fbfb3SApril Chindefault=$(set --default --state)
3527c2fbfb3SApril Chin[[ $state == $default ]] || err_exit "set --state for default options failed: expected '$default', got '$state'"
3537c2fbfb3SApril Chinset $restore
3547c2fbfb3SApril Chinstate=$(set --state)
3557c2fbfb3SApril Chin[[ $state == "set $restore" ]] || err_exit "set --state after restore failed: expected 'set $restore', got '$state'"
3567c2fbfb3SApril Chin
35734f9b3eeSRoland Mainztypeset -a pipeline
35834f9b3eeSRoland Mainzpipeline=(
35934f9b3eeSRoland Mainz	( nopipefail=0 pipefail=1 command='false|true|true' )
36034f9b3eeSRoland Mainz	( nopipefail=0 pipefail=1 command='true|false|true' )
36134f9b3eeSRoland Mainz	( nopipefail=1 pipefail=1 command='true|true|false' )
36234f9b3eeSRoland Mainz	( nopipefail=1 pipefail=1 command='false|false|false' )
36334f9b3eeSRoland Mainz	( nopipefail=0 pipefail=0 command='true|true|true' )
36434f9b3eeSRoland Mainz	( nopipefail=0 pipefail=0 command='print hi|(sleep 1;/bin/cat)>/dev/null' )
36534f9b3eeSRoland Mainz)
36634f9b3eeSRoland Mainzset --nopipefail
36734f9b3eeSRoland Mainzfor ((i = 0; i < ${#pipeline[@]}; i++ ))
36834f9b3eeSRoland Mainzdo	eval ${pipeline[i].command}
36934f9b3eeSRoland Mainz	status=$?
37034f9b3eeSRoland Mainz	expected=${pipeline[i].nopipefail}
37134f9b3eeSRoland Mainz	[[ $status == $expected ]] ||
37234f9b3eeSRoland Mainz	err_exit "--nopipefail '${pipeline[i].command}' exit status $status -- expected $expected"
37334f9b3eeSRoland Mainzdone
37434f9b3eeSRoland Mainzftt=0
37534f9b3eeSRoland Mainzset --pipefail
37634f9b3eeSRoland Mainzfor ((i = 0; i < ${#pipeline[@]}; i++ ))
37734f9b3eeSRoland Mainzdo	eval ${pipeline[i].command}
37834f9b3eeSRoland Mainz	status=$?
37934f9b3eeSRoland Mainz	expected=${pipeline[i].pipefail}
38034f9b3eeSRoland Mainz	if	[[ $status != $expected ]]
38134f9b3eeSRoland Mainz	then	err_exit "--pipefail '${pipeline[i].command}' exit status $status -- expected $expected"
38234f9b3eeSRoland Mainz		(( i == 0 )) && ftt=1
38334f9b3eeSRoland Mainz	fi
38434f9b3eeSRoland Mainzdone
38534f9b3eeSRoland Mainzif	(( ! ftt ))
38634f9b3eeSRoland Mainzthen	exp=10
38734f9b3eeSRoland Mainz	got=$(for((n=1;n<exp;n++))do $SHELL --pipefail -c '(sleep 0.1;false)|true|true' && break; done; print $n)
38834f9b3eeSRoland Mainz	[[ $got == $exp ]] || err_exit "--pipefail -c '(sleep 0.1;false)|true|true' fails with exit status 0 (after $got/$exp iterations)"
38934f9b3eeSRoland Mainzfi
39034f9b3eeSRoland Mainz
39134f9b3eeSRoland Mainzecho=$(whence -p echo)
39234f9b3eeSRoland Mainzfor ((i=0; i < 20; i++))
39334f9b3eeSRoland Mainzdo	if	! x=$(true | $echo 123)
39434f9b3eeSRoland Mainz	then	err_exit 'command substitution with wrong exit status with pipefai'
39534f9b3eeSRoland Mainz		break
39634f9b3eeSRoland Mainz	fi
39734f9b3eeSRoland Mainzdone
3987c2fbfb3SApril Chin(
3997c2fbfb3SApril Chin	set -o pipefail
4007c2fbfb3SApril Chin	false | true
4017c2fbfb3SApril Chin	(( $? )) || err_exit 'pipe not failing in subshell with pipefail'
4027c2fbfb3SApril Chin) | wc >/dev/null
4037c2fbfb3SApril Chin$SHELL -c 'set -o pipefail; false | $(whence -p true);' && err_exit 'pipefail not returning failure with sh -c'
40434f9b3eeSRoland Mainzexp='1212 or 1221'
40534f9b3eeSRoland Mainzgot=$(
40634f9b3eeSRoland Mainz	set --pipefail
4077c2fbfb3SApril Chin	pipe() { date | cat > /dev/null ;}
4087c2fbfb3SApril Chin	print $'1\n2' |
4097c2fbfb3SApril Chin	while	read i
41034f9b3eeSRoland Mainz	do 	if	pipe $tmp
41134f9b3eeSRoland Mainz		then	{ print -n $i; sleep 2; print -n $i; } &
4127c2fbfb3SApril Chin		fi
4137c2fbfb3SApril Chin	done
41434f9b3eeSRoland Mainz	wait
41534f9b3eeSRoland Mainz)
41634f9b3eeSRoland Mainz[[ $got == @((12|21)(12|21)) ]] || err_exit "& job delayed by --pipefail, expected '$exp', got '$got'"
4177c2fbfb3SApril Chin$SHELL -c '[[ $- == *c* ]]' || err_exit 'option c not in $-'
41834f9b3eeSRoland Mainz> $tmp/.profile
41934f9b3eeSRoland Mainzfor i in i l r s D E a b e f h k n t u v x B C G H
42034f9b3eeSRoland Mainzdo	HOME=$tmp ENV= $SHELL -$i >/dev/null 2>&1 <<- ++EOF++ || err_exit "option $i not in \$-"
4217c2fbfb3SApril Chin	[[ \$- == *$i* ]] || exit 1
4227c2fbfb3SApril Chin	++EOF++
4237c2fbfb3SApril Chindone
4247c2fbfb3SApril Chinletters=ilrabefhknuvxBCGE
4257c2fbfb3SApril Chininteger j=0
4267c2fbfb3SApril Chinfor i in interactive login restricted allexport notify errexit \
4277c2fbfb3SApril Chin	noglob trackall keyword noexec nounset verbose xtrace braceexpand \
4287c2fbfb3SApril Chin	noclobber globstar rc
42934f9b3eeSRoland Mainzdo	HOME=$tmp ENV= $SHELL -o $i >/dev/null 2>&1 <<- ++EOF++ || err_exit "option $i not equivalent to ${letters:j:1}"
4307c2fbfb3SApril Chin	[[ \$- == *${letters:j:1}* ]] || exit 1
4317c2fbfb3SApril Chin	++EOF++
4327c2fbfb3SApril Chin	((j++))
4337c2fbfb3SApril Chindone
43434f9b3eeSRoland Mainz
43534f9b3eeSRoland Mainzexport ENV=
43634f9b3eeSRoland Mainzhistfile=$tmp/history
43734f9b3eeSRoland Mainzexp=$(HISTFILE=$histfile $SHELL -c $'function foo\n{\ncat\n}\ntype foo')
43834f9b3eeSRoland Mainzfor var in HISTSIZE HISTFILE
43934f9b3eeSRoland Mainzdo	got=$( ( HISTFILE=$histfile $SHELL -ic $'unset '$var$'\nfunction foo\n{\ncat\n}\ntype foo\nexit' ) 2>&1 )
44034f9b3eeSRoland Mainz	got=${got##*': '}
44134f9b3eeSRoland Mainz	[[ $got == "$exp" ]] || err_exit "function definition inside (...) with $var unset fails -- got '$got', expected '$exp'"
44234f9b3eeSRoland Mainz	got=$( { HISTFILE=$histfile $SHELL -ic $'unset '$var$'\nfunction foo\n{\ncat\n}\ntype foo\nexit' ;} 2>&1 )
44334f9b3eeSRoland Mainz	got=${got##*': '}
44434f9b3eeSRoland Mainz	[[ $got == "$exp" ]] || err_exit "function definition inside {...;} with $var unset fails -- got '$got', expected '$exp'"
44534f9b3eeSRoland Mainzdone
44634f9b3eeSRoland Mainz( unset HISTFILE; $SHELL -ic "HISTFILE=$histfile" 2>/dev/null ) || err_exit "setting HISTFILE when not in environment fails"
44734f9b3eeSRoland Mainz
44834f9b3eeSRoland Mainz# the next tests loop on all combinations of
44934f9b3eeSRoland Mainz#	{ SUB PAR CMD ADD }
45034f9b3eeSRoland Mainz
45134f9b3eeSRoland MainzSUB=(
45234f9b3eeSRoland Mainz	( BEG='$( '	END=' )'	)
45334f9b3eeSRoland Mainz	( BEG='${ '	END='; }'	)
45434f9b3eeSRoland Mainz)
45534f9b3eeSRoland MainzPAR=(
45634f9b3eeSRoland Mainz	( BEG='( '	END=' )'	)
45734f9b3eeSRoland Mainz	( BEG='{ '	END='; }'	)
45834f9b3eeSRoland Mainz)
45934f9b3eeSRoland MainzCMD=(	command-kill	script-kill	)
46034f9b3eeSRoland MainzADD=(	''		'; :'		)
46134f9b3eeSRoland Mainz
46234f9b3eeSRoland Mainzcd $tmp
46334f9b3eeSRoland Mainzprint $'#!'$SHELL$'\nkill -KILL $$' > command-kill
46434f9b3eeSRoland Mainzprint $'kill -KILL $$' > script-kill
46534f9b3eeSRoland Mainzchmod +x command-kill script-kill
46634f9b3eeSRoland Mainzexport PATH=.:$PATH
46734f9b3eeSRoland Mainzexp='Killed'
46834f9b3eeSRoland Mainzfor ((S=0; S<${#SUB[@]}; S++))
46934f9b3eeSRoland Mainzdo	for ((P=0; P<${#PAR[@]}; P++))
47034f9b3eeSRoland Mainz	do	for ((C=0; C<${#CMD[@]}; C++))
47134f9b3eeSRoland Mainz		do	for ((A=0; A<${#ADD[@]}; A++))
47234f9b3eeSRoland Mainz			do	cmd="${SUB[S].BEG}${PAR[P].BEG}${CMD[C]}${PAR[P].END} 2>&1${ADD[A]}${SUB[S].END}"
47334f9b3eeSRoland Mainz				eval got="$cmd"
47434f9b3eeSRoland Mainz				got=${got##*': '}
47534f9b3eeSRoland Mainz				got=${got%%'('*}
47634f9b3eeSRoland Mainz				[[ $got == "$exp" ]] || err_exit "$cmd failed -- got '$got', expected '$exp'"
47734f9b3eeSRoland Mainz			done
47834f9b3eeSRoland Mainz		done
47934f9b3eeSRoland Mainz	done
48034f9b3eeSRoland Mainzdone
48134f9b3eeSRoland Mainz
48234f9b3eeSRoland Mainz$SHELL 2> /dev/null -c '{; true ;}' || err_exit 'leading ; causes syntax error in brace group'
48334f9b3eeSRoland Mainz$SHELL 2> /dev/null -c '(; true ;)' || err_exit 'leading ; causes syntax error in parenthesis group'
48434f9b3eeSRoland Mainz
48534f9b3eeSRoland Mainzprint 'for ((i = 0; i < ${1:-10000}; i++ )); do printf "%.*c\n" 15 x; done' > pipefail
48634f9b3eeSRoland Mainzchmod +x pipefail
48734f9b3eeSRoland Mainz$SHELL --pipefail -c './pipefail 10000 | sed 1q' >/dev/null 2>&1 &
48834f9b3eeSRoland Mainztst=$!
48934f9b3eeSRoland Mainz{ sleep 4; kill $tst; } 2>/dev/null &
49034f9b3eeSRoland Mainzspy=$!
49134f9b3eeSRoland Mainzwait $tst 2>/dev/null
49234f9b3eeSRoland Mainzstatus=$?
49334f9b3eeSRoland Mainzif	[[ $status == 0 || $(kill -l $status) == PIPE ]]
49434f9b3eeSRoland Mainzthen    kill $spy 2>/dev/null
49534f9b3eeSRoland Mainzelse    err_exit "pipefail pipeline bypasses SIGPIPE and hangs"
49634f9b3eeSRoland Mainzfi
49734f9b3eeSRoland Mainzwait
49834f9b3eeSRoland Mainz
499da2e3ebdSchinexit $((Errors))
500