Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/ksh93/tests/io.sh
1810 views
1
########################################################################
2
# #
3
# This software is part of the ast package #
4
# Copyright (c) 1982-2012 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 <[email protected]> #
18
# #
19
########################################################################
20
function err_exit
21
{
22
print -u2 -n "\t"
23
print -u2 -r ${Command}[$1]: "${@:2}"
24
let Errors+=1
25
}
26
alias err_exit='err_exit $LINENO'
27
28
Command=${0##*/}
29
integer Errors=0
30
31
tmp=$(mktemp -dt) || { err_exit mktemp -dt failed; exit 1; }
32
trap "cd /; rm -rf $tmp" EXIT
33
34
unset HISTFILE
35
36
function fun
37
{
38
while command exec 3>&1
39
do break
40
done 2> /dev/null
41
print -u3 good
42
}
43
print 'read -r a; print -r -u$1 -- "$a"' > $tmp/mycat
44
chmod 755 $tmp/mycat
45
for ((i=3; i < 10; i++))
46
do
47
eval "a=\$(print foo | $tmp/mycat" $i $i'>&1 > /dev/null |cat)' 2> /dev/null
48
[[ $a == foo ]] || err_exit "bad file descriptor $i in comsub script"
49
done
50
exec 3> /dev/null
51
[[ $(fun) == good ]] || err_exit 'file 3 closed before subshell completes'
52
exec 3>&-
53
cd $tmp || { err_exit "cd $tmp failed"; exit ; }
54
print foo > file1
55
print bar >> file1
56
if [[ $(<file1) != $'foo\nbar' ]]
57
then err_exit 'append (>>) not working'
58
fi
59
set -o noclobber
60
exec 3<> file1
61
read -u3 line
62
exp=foo
63
if [[ $line != $exp ]]
64
then err_exit "read on <> fd failed -- expected '$exp', got '$line'"
65
fi
66
if ( 4> file1 ) 2> /dev/null
67
then err_exit 'noclobber not causing exclusive open'
68
fi
69
set +o noclobber
70
71
FDFS=(
72
( dir=/proc/self/fd semantics='open' )
73
( dir=/proc/$$/fd semantics='open' )
74
( dir=/dev/fd semantics='open|dup' )
75
( dir=/dev/fd semantics='dup' )
76
)
77
for ((fdfs=0; fdfs<${#FDFS[@]}-1; fdfs++))
78
do [[ -e ${FDFS[fdfs].dir} ]] && { command : > ${FDFS[fdfs].dir}/1; } 2>/dev/null >&2 && break
79
done
80
81
exec 3<> file1
82
if command exec 4< ${FDFS[fdfs].dir}/3
83
then read -u3 got
84
read -u4 got
85
exp='foo|bar'
86
case $got in
87
foo) semantics='open' ;;
88
bar) semantics='dup' ;;
89
*) semantics='failed' ;;
90
esac
91
[[ $semantics == @(${FDFS[fdfs].semantics}) ]] || err_exit "'4< ${FDFS[fdfs].dir}/3' $semantics semantics instead of ${FDFS[fdfs].semantics} -- expected '$exp', got '$got'"
92
fi
93
94
# 2004-11-25 ancient /dev/fd/N redirection bug fix
95
got=$(
96
{
97
print -n 1
98
print -n 2 > ${FDFS[fdfs].dir}/2
99
print -n 3
100
print -n 4 > ${FDFS[fdfs].dir}/2
101
} 2>&1
102
)
103
exp='1234|4'
104
case $got in
105
1234) semantics='dup' ;;
106
4) semantics='open' ;;
107
*) semantics='failed' ;;
108
esac
109
[[ $semantics == @(${FDFS[fdfs].semantics}) ]] || err_exit "${FDFS[fdfs].dir}/N $semantics semantics instead of ${FDFS[fdfs].semantics} -- expected '$exp', got '$got'"
110
111
cat > close0 <<\!
112
exec 0<&-
113
echo $(./close1)
114
!
115
print "echo abc" > close1
116
chmod +x close0 close1
117
x=$(./close0)
118
if [[ $x != "abc" ]]
119
then err_exit "picked up file descriptor zero for opening script file"
120
fi
121
cat > close0 <<\!
122
for ((i=0; i < 1100; i++))
123
do exec 4< /dev/null
124
read -u4
125
done
126
exit 0
127
!
128
./close0 2> /dev/null || err_exit "multiple exec 4< /dev/null can fail"
129
$SHELL -c '
130
trap "rm -f in out" EXIT
131
for ((i = 0; i < 1000; i++))
132
do print -r -- "This is a test"
133
done > in
134
> out
135
exec 1<> out
136
builtin cat
137
print -r -- "$(<in)"
138
cmp -s in out' 2> /dev/null
139
[[ $? == 0 ]] || err_exit 'builtin cat truncates files'
140
cat >| script <<-\!
141
print hello
142
( exec 3<&- 4<&-)
143
exec 3<&- 4<&-
144
print world
145
!
146
chmod +x script
147
[[ $( $SHELL ./script) == $'hello\nworld' ]] || err_exit 'closing 3 & 4 causes script to fail'
148
cd ~- || err_exit "cd back failed"
149
( exec > '' ) 2> /dev/null && err_exit '> "" does not fail'
150
unset x
151
( exec > ${x} ) 2> /dev/null && err_exit '> $x, where x null does not fail'
152
exec <<!
153
foo
154
bar
155
!
156
( exec 0< /dev/null)
157
read line
158
if [[ $line != foo ]]
159
then err_exit 'file descriptor not restored after exec in subshell'
160
fi
161
exec 3>&- 4>&-
162
[[ $( {
163
read -r line; print -r -- "$line"
164
(
165
read -r line; print -r -- "$line"
166
) & wait
167
while read -r line
168
do print -r -- "$line"
169
done
170
} << !
171
line 1
172
line 2
173
line 3
174
!) == $'line 1\nline 2\nline 3' ]] || err_exit 'read error with subshells'
175
# 2004-05-11 bug fix
176
cat > $tmp/1 <<- ++EOF++
177
script=$tmp/2
178
trap "rm -f \$script" EXIT
179
exec 9> \$script
180
for ((i=3; i<9; i++))
181
do eval "while read -u\$i; do : ; done \$i</dev/null"
182
print -u9 "exec \$i< /dev/null"
183
done
184
for ((i=0; i < 60; i++))
185
do print -u9 -f "%.80c\n" ' '
186
done
187
print -u9 'print ok'
188
exec 9<&-
189
chmod +x \$script
190
\$script
191
++EOF++
192
chmod +x $tmp/1
193
[[ $($SHELL $tmp/1) == ok ]] || err_exit "parent i/o causes child script to fail"
194
# 2004-12-20 redirection loss bug fix
195
cat > $tmp/1 <<- \++EOF++
196
function a
197
{
198
trap 'print ok' EXIT
199
: > /dev/null
200
}
201
a
202
++EOF++
203
chmod +x $tmp/1
204
[[ $($tmp/1) == ok ]] || err_exit "trap on EXIT loses last command redirection"
205
print > /dev/null {n}> $tmp/1
206
[[ ! -s $tmp/1 ]] && newio=1
207
if [[ $newio && $(print hello | while read -u$n; do print $REPLY; done {n}<&0) != hello ]]
208
then err_exit "{n}<&0 not working with for loop"
209
fi
210
[[ $({ read -r; read -u3 3<&0; print -- "$REPLY" ;} <<!
211
hello
212
world
213
!) == world ]] || err_exit 'I/O not synchronized with <&'
214
x="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNSPQRSTUVWXYZ1234567890"
215
for ((i=0; i < 62; i++))
216
do printf "%.39c\n" ${x:i:1}
217
done > $tmp/seek
218
if command exec 3<> $tmp/seek
219
then (( $(3<#) == 0 )) || err_exit "not at position 0"
220
(( $(3<# ((EOF))) == 40*62 )) || err_exit "not at end-of-file"
221
command exec 3<# ((40*8)) || err_exit "absolute seek fails"
222
read -u3
223
[[ $REPLY == +(i) ]] || err_exit "expected iiii..., got $REPLY"
224
[[ $(3<#) == $(3<# ((CUR)) ) ]] || err_exit '$(3<#)!=$(3<#((CUR)))'
225
command exec 3<# ((CUR+80))
226
read -u3
227
[[ $REPLY == {39}(l) ]] || err_exit "expected lll..., got $REPLY"
228
command exec 3<# ((EOF-80))
229
read -u3
230
[[ $REPLY == +(9) ]] || err_exit "expected 999..., got $REPLY"
231
command exec 3># ((80))
232
print -u3 -f "%.39c\n" @
233
command exec 3># ((80))
234
read -u3
235
[[ $REPLY == +(@) ]] || err_exit "expected @@@..., got $REPLY"
236
read -u3
237
[[ $REPLY == +(d) ]] || err_exit "expected ddd..., got $REPLY"
238
command exec 3># ((EOF))
239
print -u3 -f "%.39c\n" ^
240
(( $(3<# ((CUR-0))) == 40*63 )) || err_exit "not at extended end-of-file"
241
command exec 3<# ((40*62))
242
read -u3
243
[[ $REPLY == +(^) ]] || err_exit "expected ddd..., got $REPLY"
244
command exec 3<# ((0))
245
command exec 3<# *jjjj*
246
read -u3
247
[[ $REPLY == {39}(j) ]] || err_exit "<# pattern failed"
248
[[ $(command exec 3<## *llll*) == {39}(k) ]] || err_exit "<## pattern not saving standard output"
249
read -u3
250
[[ $REPLY == {39}(l) ]] || err_exit "<## pattern failed to position"
251
command exec 3<# *abc*
252
read -u3 && err_exit "not found pattern not positioning at eof"
253
cat $tmp/seek | read -r <# *WWW*
254
[[ $REPLY == *WWWWW* ]] || err_exit '<# not working for pipes'
255
{ < $tmp/seek <# ((2358336120)) ;} 2> /dev/null || err_exit 'long seek not working'
256
else err_exit "$tmp/seek: cannot open for reading"
257
fi
258
command exec 3<&- || 'cannot close 3'
259
for ((i=0; i < 62; i++))
260
do printf "%.39c\n" ${x:i:1}
261
done > $tmp/seek
262
if command exec {n}<> $tmp/seek
263
then { command exec {n}<#((EOF)) ;} 2> /dev/null || err_exit '{n}<# not working'
264
if $SHELL -c '{n}</dev/null' 2> /dev/null
265
then (( $({n}<#) == 40*62)) || err_exit '$({n}<#) not working'
266
else err_exit 'not able to parse {n}</dev/null'
267
fi
268
fi
269
$SHELL -ic '
270
{
271
print -u2 || exit 2
272
print -u3 || exit 3
273
print -u4 || exit 4
274
print -u5 || exit 5
275
print -u6 || exit 6
276
print -u7 || exit 7
277
print -u8 || exit 8
278
print -u9 || exit 9
279
} 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
280
exitval=$?
281
(( exitval )) && err_exit "print to unit $exitval failed"
282
$SHELL -c "{ > $tmp/1 ; date;} >&- 2> /dev/null" > $tmp/2
283
[[ -s $tmp/1 || -s $tmp/2 ]] && err_exit 'commands with standard output closed produce output'
284
$SHELL -c "$SHELL -c ': 3>&1' 1>&- 2>/dev/null" && err_exit 'closed standard output not passed to subshell'
285
[[ $(cat <<- \EOF | $SHELL
286
do_it_all()
287
{
288
dd 2>/dev/null # not a ksh93 buildin
289
return $?
290
}
291
do_it_all ; exit $?
292
hello world
293
EOF) == 'hello world' ]] || err_exit 'invalid readahead on stdin'
294
$SHELL -c 'exec 3>; /dev/null' 2> /dev/null && err_exit '>; with exec should be an error'
295
$SHELL -c ': 3>; /dev/null' 2> /dev/null || err_exit '>; not working with at all'
296
print hello > $tmp/1
297
if ! $SHELL -c "false >; $tmp/1" 2> /dev/null
298
then let 1;[[ $(<$tmp/1) == hello ]] || err_exit '>; not preserving file on failure'
299
fi
300
if ! $SHELL -c "sed -e 's/hello/hello world/' $tmp/1" >; $tmp/1 2> /dev/null
301
then [[ $(<$tmp/1) == 'hello world' ]] || err_exit '>; not updating file on success'
302
fi
303
304
$SHELL -c 'exec 3<>; /dev/null' 2> /dev/null && err_exit '<>; with exec should be an error'
305
$SHELL -c ': 3<>; /dev/null' 2> /dev/null || err_exit '<>; not working with at all'
306
print $'hello\nworld' > $tmp/1
307
if ! $SHELL -c "false <>; $tmp/1" 2> /dev/null
308
then [[ $(<$tmp/1) == $'hello\nworld' ]] || err_exit '<>; not preserving file on failure'
309
fi
310
if ! $SHELL -c "head -1 $tmp/1" <>; $tmp/1 2> /dev/null
311
then [[ $(<$tmp/1) == hello ]] || err_exit '<>; not truncating file on success of head'
312
fi
313
print $'hello\nworld' > $tmp/1
314
if ! $SHELL -c head < $tmp/1 <#((6)) <>; $tmp/1 2> /dev/null
315
then [[ $(<$tmp/1) == world ]] || err_exit '<>; not truncating file on success of behead'
316
fi
317
318
unset y
319
read -n1 y <<!
320
abc
321
!
322
if [[ $y != a ]]
323
then err_exit 'read -n1 not working'
324
fi
325
unset a
326
{ read -N3 a; read -N1 b;} <<!
327
abcdefg
328
!
329
[[ $a == abc ]] || err_exit 'read -N3 here-document not working'
330
[[ $b == d ]] || err_exit 'read -N1 here-document not working'
331
read -n3 a <<!
332
abcdefg
333
!
334
[[ $a == abc ]] || err_exit 'read -n3 here-document not working'
335
(print -n a; sleep 1; print -n bcde) | { read -N3 a; read -N1 b;}
336
[[ $a == abc ]] || err_exit 'read -N3 from pipe not working'
337
[[ $b == d ]] || err_exit 'read -N1 from pipe not working'
338
(print -n a; sleep 1; print -n bcde) |read -n3 a
339
[[ $a == a ]] || err_exit 'read -n3 from pipe not working'
340
if mkfifo $tmp/fifo 2> /dev/null
341
then (print -n a; sleep 2; print -n bcde) > $tmp/fifo &
342
{
343
read -u5 -n3 -t3 a || err_exit 'read -n3 from fifo timed out'
344
read -u5 -n1 -t3 b || err_exit 'read -n1 from fifo timed out'
345
} 5< $tmp/fifo
346
exp=a
347
got=$a
348
[[ $got == "$exp" ]] || err_exit "read -n3 from fifo failed -- expected '$exp', got '$got'"
349
exp=b
350
got=$b
351
[[ $got == "$exp" ]] || err_exit "read -n1 from fifo failed -- expected '$exp', got '$got'"
352
rm -f $tmp/fifo
353
wait
354
mkfifo $tmp/fifo 2> /dev/null
355
(print -n a; sleep 2; print -n bcde) > $tmp/fifo &
356
{
357
read -u5 -N3 -t3 a || err_exit 'read -N3 from fifo timed out'
358
read -u5 -N1 -t3 b || err_exit 'read -N1 from fifo timed out'
359
} 5< $tmp/fifo
360
exp=abc
361
got=$a
362
[[ $got == "$exp" ]] || err_exit "read -N3 from fifo failed -- expected '$exp', got '$got'"
363
exp=d
364
got=$b
365
[[ $got == "$exp" ]] || err_exit "read -N1 from fifo failed -- expected '$exp', got '$got'"
366
wait
367
fi
368
(
369
print -n 'prompt1: '
370
sleep .1
371
print line2
372
sleep .1
373
print -n 'prompt2: '
374
sleep .1
375
) | {
376
read -t2 -n 1000 line1
377
read -t2 -n 1000 line2
378
read -t2 -n 1000 line3
379
read -t2 -n 1000 line4
380
}
381
[[ $? == 0 ]] && err_exit 'should have timed out'
382
[[ $line1 == 'prompt1: ' ]] || err_exit "line1 should be 'prompt1: '"
383
[[ $line2 == line2 ]] || err_exit "line2 should be line2"
384
[[ $line3 == 'prompt2: ' ]] || err_exit "line3 should be 'prompt2: '"
385
[[ ! $line4 ]] || err_exit "line4 should be empty"
386
387
if $SHELL -c "export LC_ALL=C.UTF-8; c=$'\342\202\254'; [[ \${#c} == 1 ]]" 2>/dev/null
388
then lc_utf8=C.UTF-8
389
else lc_utf8=''
390
fi
391
392
typeset -a e o=(-n2 -N2)
393
integer i
394
set -- \
395
'a' 'bcd' 'a bcd' 'ab cd' \
396
'ab' 'cd' 'ab cd' 'ab cd' \
397
'abc' 'd' 'ab cd' 'ab cd' \
398
'abcd' '' 'ab cd' 'ab cd'
399
while (( $# >= 3 ))
400
do a=$1
401
b=$2
402
e[0]=$3
403
e[1]=$4
404
shift 4
405
for ((i = 0; i < 2; i++))
406
do for lc_all in C $lc_utf8
407
do g=$(LC_ALL=$lc_all $SHELL -c "{ print -n '$a'; sleep 0.2; print -n '$b'; sleep 0.2; } | { read ${o[i]} a; print -n \$a; read a; print -n \ \$a; }")
408
[[ $g == "${e[i]}" ]] || err_exit "LC_ALL=$lc_all read ${o[i]} from pipe '$a $b' failed -- expected '${e[i]}', got '$g'"
409
done
410
done
411
done
412
413
if [[ $lc_utf8 ]]
414
then export LC_ALL=$lc_utf8
415
typeset -a c=( '' 'A' $'\303\274' $'\342\202\254' )
416
integer i w
417
typeset o
418
if (( ${#c[2]} == 1 && ${#c[3]} == 1 ))
419
then for i in 1 2 3
420
do for o in n N
421
do for w in 1 2 3
422
do print -nr "${c[w]}" | read -${o}${i} g
423
if [[ $o == N ]] && (( i > 1 ))
424
then e=''
425
else e=${c[w]}
426
fi
427
[[ $g == "$e" ]] || err_exit "read -${o}${i} failed for '${c[w]}' -- expected '$e', got '$g'"
428
done
429
done
430
done
431
fi
432
fi
433
434
exec 3<&2
435
file=$tmp/file
436
redirect 5>$file 2>&5
437
print -u5 -f 'This is a test\n'
438
print -u2 OK
439
exec 2<&3
440
exp=$'This is a test\nOK'
441
got=$(< $file)
442
[[ $got == $exp ]] || err_exit "output garbled when stderr is duped -- expected $(printf %q "$exp"), got $(printf %q "$got")"
443
print 'hello world' > $file
444
1<>; $file 1># ((5))
445
(( $(wc -c < $file) == 5 )) || err_exit "$file was not truncate to 5 bytes"
446
447
$SHELL -c "PS4=':2:'
448
exec 1> $tmp/21.out 2> $tmp/22.out
449
set -x
450
printf ':1:A:'
451
print \$(:)
452
print :1:Z:" 1> $tmp/11.out 2> $tmp/12.out
453
[[ -s $tmp/11.out ]] && err_exit "standard output leaked past redirection"
454
[[ -s $tmp/12.out ]] && err_exit "standard error leaked past redirection"
455
exp=$':1:A:\n:1:Z:'
456
got=$(<$tmp/21.out)
457
[[ $exp == "$got" ]] || err_exit "standard output garbled -- expected $(printf %q "$exp"), got $(printf %q "$got")"
458
exp=$':2:printf :1:A:\n:2::\n:2:print\n:2:print :1:Z:'
459
got=$(<$tmp/22.out)
460
[[ $exp == "$got" ]] || err_exit "standard error garbled -- expected $(printf %q "$exp"), got $(printf %q "$got")"
461
462
tmp=$tmp $SHELL 2> /dev/null -c 'exec 3<&1 ; exec 1<&- ; exec > $tmp/outfile;print foobar' || err_exit 'exec 1<&- causes failure'
463
[[ $(<$tmp/outfile) == foobar ]] || err_exit 'outfile does not contain foobar'
464
465
print hello there world > $tmp/foobar
466
sed -e 's/there //' $tmp/foobar >; $tmp/foobar
467
[[ $(<$tmp/foobar) == 'hello world' ]] || err_exit '>; redirection not working on simple command'
468
print hello there world > $tmp/foobar
469
{ sed -e 's/there //' $tmp/foobar;print done;} >; $tmp/foobar
470
[[ $(<$tmp/foobar) == $'hello world\ndone' ]] || err_exit '>; redirection not working for compound command'
471
print hello there world > $tmp/foobar
472
$SHELL -c "sed -e 's/there //' $tmp/foobar >; $tmp/foobar"
473
[[ $(<$tmp/foobar) == 'hello world' ]] || err_exit '>; redirection not working with -c on a simple command'
474
475
rm -f "$tmp/junk"
476
for (( i=1; i < 50; i++ ))
477
do out=$(/bin/ls "$tmp/junk" 2>/dev/null)
478
if (( $? == 0 ))
479
then err_exit 'wrong error code with redirection'
480
break
481
fi
482
done
483
484
rm -f $tmp/file1 $tmp/file2
485
print foo > $tmp/file3
486
ln -s $tmp/file3 $tmp/file2
487
ln -s $tmp/file2 $tmp/file1
488
print bar >; $tmp/file1
489
[[ $(<$tmp/file3) == bar ]] || err_exit '>; not following symlinks'
490
491
for i in 1
492
do :
493
done {n}< /dev/null
494
[[ -r /dev/fd/$n ]] && err_exit "file descriptor n=$n left open after {n}<"
495
496
n=$( exec {n}< /dev/null; print -r -- $n)
497
[[ -r /dev/fd/$n ]] && err_exit "file descriptor n=$n left open after subshell"
498
499
exit $((Errors<125?Errors:125))
500
501