xref: /titanic_41/usr/src/lib/libshell/common/tests/io.sh (revision fd06a699040f011e80ab8ac5213bb0a47858e69b)
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
28Command=${0##*/}
29integer Errors=0
30# cut here
31function fun
32{
33	while  command exec 3>&1
34	do	break
35	done 2>   /dev/null
36	print -u3 good
37}
38print 'read -r a;print -r -u$1 -- "$a"' >  /tmp/mycat$$
39chmod 755 /tmp/mycat$$
40for ((i=3; i < 10; i++))
41do
42	eval "a=\$(print foo | /tmp/mycat$$" $i $i'>&1 > /dev/null |cat)' 2> /dev/null
43	[[ $a == foo ]] || err_exit "bad file descriptor $i in comsub script"
44done
45rm -f /tmp/mycat$$
46exec 3> /dev/null
47[[ $(fun) == good ]] || err_exit 'file 3 closed before subshell completes'
48exec 3>&-
49mkdir /tmp/ksh$$ || err_exit "mkdir /tmp/ksh$$ failed"
50trap 'rm -rf /tmp/ksh$$' EXIT
51cd /tmp/ksh$$ || err_exit "cd /tmp/ksh$$ failed"
52print foo > file1
53print bar >> file1
54if	[[ $(<file1) != $'foo\nbar' ]]
55then	err_exit 'append (>>) not working'
56fi
57set -o noclobber
58exec 3<> file1
59read -u3 line
60if	[[ $line != foo ]]
61then	err_exit '<> not working right with read'
62fi
63if	( 4> file1 ) 2> /dev/null
64then	err_exit 'noclobber not causing exclusive open'
65fi
66set +o noclobber
67if	command exec 4< /dev/fd/3
68then	read -u4 line
69	if	[[ $line != bar ]]
70	then	'4< /dev/fd/3 not working correctly'
71	fi
72fi
73cat > close0 <<\!
74exec 0<&-
75echo $(./close1)
76!
77print "echo abc" > close1
78chmod +x close0 close1
79x=$(./close0)
80if	[[ $x != "abc" ]]
81then	err_exit "picked up file descriptor zero for opening script file"
82fi
83cat > close0 <<\!
84	for ((i=0; i < 1100; i++))
85	do	exec 4< /dev/null
86		read -u4
87	done
88	exit 0
89!
90./close0 2> /dev/null || err_exit "multiple exec 4< /dev/null can fail"
91$SHELL -c '
92	trap "rm -f in$$ out$$" EXIT
93	for ((i = 0; i < 1000; i++))
94	do	print -r -- "This is a test"
95	done > in$$
96	> out$$
97	exec 1<> out$$
98	builtin cat
99	print -r -- "$(cat in$$)"
100	cmp -s in$$ out$$'  2> /dev/null
101[[ $? == 0 ]] || err_exit 'builtin cat truncates files'
102cat >| script <<-\!
103print hello
104( exec 3<&- 4<&-)
105exec 3<&- 4<&-
106print world
107!
108chmod +x script
109[[ $( $SHELL ./script) == $'hello\nworld' ]] || err_exit 'closing 3 & 4 causes script to fail'
110cd ~- || err_exit "cd back failed"
111( exec  > '' ) 2> /dev/null  && err_exit '> "" does not fail'
112unset x
113( exec > ${x} ) 2> /dev/null && err_exit '> $x, where x null does not fail'
114exec <<!
115foo
116bar
117!
118( exec 0< /dev/null)
119read line
120if	[[ $line != foo ]]
121then	err_exit 'file descriptor not restored after exec in subshell'
122fi
123exec 3>&- 4>&-; cd /; rm -r /tmp/ksh$$ || err_exit "rm -r /tmp/ksh$$ failed"
124[[ $( {
125	read -r line;print -r -- "$line"
126	(
127	        read -r line;print -r -- "$line"
128	) & wait
129	while	read -r line
130        do	print -r -- "$line"
131	done
132 } << !
133line 1
134line 2
135line 3
136!) == $'line 1\nline 2\nline 3' ]] || err_exit 'read error with subshells'
137# 2004-05-11 bug fix
138cat > /tmp/io$$.1 <<- \++EOF++
139	script=/tmp/io$$.2
140	trap 'rm -f $script' EXIT
141	exec 9> $script
142	for ((i=3; i<9; i++))
143	do	eval "while read -u$i; do : ;done $i</dev/null"
144		print -u9 "exec $i< /dev/null"
145	done
146	for ((i=0; i < 60; i++))
147	do	print -u9 -f "%.80c\n"  ' '
148	done
149	print -u9 'print ok'
150	exec 9<&-
151	chmod +x $script
152	$script
153++EOF++
154chmod +x /tmp/io$$.1
155[[ $($SHELL  /tmp/io$$.1) == ok ]]  || err_exit "parent i/o causes child script to fail"
156rm -rf /tmp/io$$.[12]
157# 2004-11-25 ancient /dev/fd/NN redirection bug fix
158x=$(
159	{
160		print -n 1
161		print -n 2 > /dev/fd/2
162		print -n 3
163		print -n 4 > /dev/fd/2
164	}  2>&1
165)
166[[ $x == "1234" ]] || err_exit "/dev/fd/NN redirection fails to dup"
167# 2004-12-20 redirction loss bug fix
168cat > /tmp/io$$.1 <<- \++EOF++
169	function a
170	{
171		trap 'print ok' EXIT
172		: > /dev/null
173	}
174	a
175++EOF++
176chmod +x /tmp/io$$.1
177[[ $(/tmp/io$$.1) == ok ]] || err_exit "trap on EXIT loses last command redirection"
178print > /dev/null {n}> /tmp/io$$.1
179[[ ! -s /tmp/io$$.1 ]] && newio=1
180rm -rf /tmp/io$$.1
181if	[[ $newio && $(print hello | while read -u$n; do print $REPLY; done {n}<&0) != hello ]]
182then	err_exit "{n}<&0 not working with for loop"
183fi
184[[ $({ read -r;read -u3 3<&0; print -- "$REPLY" ;} <<!
185hello
186world
187!) == world ]] || err_exit 'I/O not synchronized with <&'
188trap 'rm -f /tmp/seek$$; exit $((Errors+1))' EXIT
189x="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNSPQRSTUVWXYZ1234567890"
190for ((i=0; i < 62; i++))
191do	printf "%.39c\n"  ${x:i:1}
192done >  /tmp/seek$$
193if	command exec 3<> /tmp/seek$$
194then	(( $(3<#) == 0 )) || err_exit "not at position 0"
195	(( $(3<# ((EOF))) == 40*62 )) || err_exit "not at end-of-file"
196	command exec 3<# ((40*8)) || err_exit "absolute seek fails"
197	read -u3
198	[[ $REPLY == +(i) ]] || err_exit "expecting iiii..."
199	[[ $(3<#) == $(3<# ((CUR)) ) ]] || err_exit '$(3<#)!=$(3<#((CUR)))'
200	command exec 3<# ((CUR+80))
201	read -u3
202	[[ $REPLY == {39}(l) ]] || err_exit "expecting lll..."
203	command exec 3<# ((EOF-80))
204	read -u3
205	[[ $REPLY == +(9) ]] || err_exit "expecting 999...; got $REPLY"
206	command exec 3># ((80))
207	print -u3 -f "%.39c\n"  @
208	command exec 3># ((80))
209	read -u3
210	[[ $REPLY == +(@) ]] || err_exit "expecting @@@..."
211	read -u3
212	[[ $REPLY == +(d) ]] || err_exit "expecting ddd..."
213	command exec 3># ((EOF))
214	print -u3 -f "%.39c\n"  ^
215	(( $(3<# ((CUR-0))) == 40*63 )) || err_exit "not at extended end-of-file"
216	command exec 3<# ((40*62))
217	read -u3
218	[[ $REPLY == +(^) ]] || err_exit "expecting ddd..."
219	command exec 3<# ((0))
220	command exec 3<# *jjjj*
221	read -u3
222	[[  $REPLY == {39}(j) ]] || err_exit "<# pattern failed"
223	[[ $(command exec 3<## *llll*) = {39}(k) ]] || err_exit "<## pattern not saving standard output"
224	read -u3
225	[[  $REPLY == {39}(l) ]] || err_exit "<## pattern failed to position"
226	command exec 3<# *abc*
227	read -u3 && err_exit "not found pattern not positioning at eof"
228	cat /tmp/seek$$ | read -r <# *WWW*
229	[[ $REPLY == *WWWWW* ]] || err_exit '<# not working for pipes'
230else	err_exit "/tmp/seek$$: cannot open for reading"
231fi
232trap "" EXIT
233rm -f  /tmp/seek$$
234$SHELL -ic '
235{
236    print -u2  || exit 2
237    print -u3  || exit 3
238    print -u4  || exit 4
239    print -u5  || exit 5
240    print -u6  || exit 6
241    print -u7  || exit 7
242    print -u8  || exit 8
243    print -u9  || exit 9
244}  3> /dev/null 4> /dev/null 5> /dev/null 6> /dev/null 7> /dev/null 8> /dev/null 9> /dev/null' > /dev/null 2>&1
245exitval=$?
246(( exitval ))  && err_exit  "print to unit $exitval failed"
247trap 'rm -rf /tmp/io.sh$$*' EXIT
248$SHELL -c "{ > /tmp/io.sh$$.1 ; date;} >&- 2> /dev/null" > /tmp/io.sh$$.2
249[[ -s /tmp/io.sh$$.1 || -s /tmp/io.sh$$.2 ]] && err_exit 'commands with standard output closed produce output'
250$SHELL -c "$SHELL -c ': 3>&1' 1>&- 2>/dev/null" && err_exit 'closed standard output not passed to subshell'
251exit $((Errors))
252