OILS / spec / builtin-process.test.sh View on Github | oils.pub

591 lines, 258 significant
1## compare_shells: dash bash mksh zsh
2## oils_failures_allowed: 1
3## oils_cpp_failures_allowed: 2
4# case #24 with ulimit -f 1 is different under C++ for some reason - could be due to the python2
5# intepreter and SIGXFSZ
6
7#### exec builtin
8exec echo hi
9## stdout: hi
10
11#### exec builtin with redirects
12exec 1>&2
13echo 'to stderr'
14## stdout-json: ""
15## stderr: to stderr
16
17#### exec builtin with here doc
18# This has in a separate file because both code and data can be read from
19# stdin.
20$SH $REPO_ROOT/spec/bin/builtins-exec-here-doc-helper.sh
21## STDOUT:
22x=one
23y=two
24DONE
25## END
26
27#### exec builtin accepts --
28exec -- echo hi
29## STDOUT:
30hi
31## END
32## BUG dash status: 127
33## BUG dash stdout-json: ""
34
35#### exec -- 2>&1
36exec -- 3>&1
37echo stdout 1>&3
38## STDOUT:
39stdout
40## END
41## BUG dash status: 127
42## BUG dash stdout-json: ""
43## BUG mksh status: -11
44## BUG mksh stdout-json: ""
45
46#### Exit out of function
47f() { exit 3; }
48f
49exit 4
50## status: 3
51
52#### Exit builtin with invalid arg
53exit invalid
54# Rationale: runtime errors are 1
55## status: 1
56## OK dash/bash status: 2
57## BUG zsh status: 0
58
59#### Exit builtin with too many args
60# This is a parse error in OSH.
61exit 7 8 9
62echo status=$?
63## status: 2
64## stdout-json: ""
65## BUG bash/zsh status: 0
66## BUG bash/zsh stdout: status=1
67## BUG dash status: 7
68## BUG dash stdout-json: ""
69## OK mksh status: 1
70## OK mksh stdout-json: ""
71
72#### time with brace group argument
73
74err=time-$(basename $SH).txt
75{
76 time {
77 sleep 0.01
78 sleep 0.02
79 }
80} 2> $err
81
82grep --only-matching user $err
83echo result=$?
84
85# Regression: check fractional seconds
86gawk '
87BEGIN { ok = 0 }
88match( $0, /\.([0-9]+)/, m) {
89 if (m[1] > 0) { # check fractional seconds
90 ok = 1
91 }
92}
93END { if (ok) { print "non-zero" } }
94' $err
95
96## status: 0
97## STDOUT:
98user
99result=0
100non-zero
101## END
102
103# time doesn't accept a block?
104## BUG zsh STDOUT:
105result=1
106## END
107
108# dash doesn't have time keyword
109## N-I dash status: 2
110## N-I dash stdout-json: ""
111
112
113
114#### ulimit with no flags is like -f
115
116ulimit > no-flags.txt
117echo status=$?
118
119ulimit -f > f.txt
120echo status=$?
121
122diff -u no-flags.txt f.txt
123echo diff=$?
124
125# Print everything
126# ulimit -a
127
128## STDOUT:
129status=0
130status=0
131diff=0
132## END
133
134
135#### ulimit too many args
136
137ulimit 1 2
138if test $? -ne 0; then
139 echo pass
140else
141 echo fail
142fi
143
144#ulimit -f
145
146## STDOUT:
147pass
148## END
149
150## BUG bash/zsh STDOUT:
151fail
152## END
153
154
155#### ulimit negative flag
156
157ulimit -f
158
159# interpreted as a flag
160ulimit -f -42
161if test $? -ne 0; then
162 echo pass
163else
164 echo fail
165fi
166
167## STDOUT:
168unlimited
169pass
170## END
171
172#### ulimit negative arg
173
174ulimit -f
175
176# an arg
177ulimit -f -- -42
178if test $? -ne 0; then
179 echo pass
180else
181 echo fail
182fi
183
184## STDOUT:
185unlimited
186pass
187## END
188
189## BUG mksh STDOUT:
190unlimited
191fail
192## END
193
194
195#### ulimit -a doesn't take arg
196case $SH in bash) exit ;; esac
197
198ulimit -a 42
199if test $? -ne 0; then
200 echo 'failure that was expected'
201fi
202
203## STDOUT:
204failure that was expected
205## END
206## BUG bash STDOUT:
207## END
208
209
210#### ulimit doesn't accept multiple flags - reduce confusion between shells
211
212# - bash, zsh, busybox ash accept multiple "commands", which requires custom
213# flag parsing, like
214
215# ulimit -f 999 -n
216# ulimit -f 999 -n 888
217#
218# - dash and mksh accept a single ARG
219#
220# we want to make it clear we're like the latter
221
222# can't print all and -f
223ulimit -f -a >/dev/null
224echo status=$?
225
226ulimit -f -n >/dev/null
227echo status=$?
228
229ulimit -f -n 999 >/dev/null
230echo status=$?
231
232## STDOUT:
233status=2
234status=2
235status=2
236## END
237
238## BUG dash/bash/mksh STDOUT:
239status=0
240status=0
241status=0
242## END
243
244# zsh is better - it checks that -a and -f are exclusive
245
246## BUG zsh STDOUT:
247status=1
248status=0
249status=0
250## END
251
252
253#### YSH readability: ulimit --all the same as ulimit -a
254
255case $SH in bash|dash|mksh|zsh) exit ;; esac
256
257ulimit -a > short.txt
258ulimit --all > long.txt
259
260wc -l short.txt long.txt
261
262diff -u short.txt long.txt
263echo status=$?
264
265## STDOUT:
266 8 short.txt
267 8 long.txt
268 16 total
269status=0
270## END
271
272## N-I bash/dash/mksh/zsh STDOUT:
273## END
274
275#### ulimit accepts 'unlimited'
276
277for arg in zz unlimited; do
278 echo " arg $arg"
279 ulimit -f
280 echo status=$?
281 ulimit -f $arg
282 if test $? -ne 0; then
283 echo 'FAILED'
284 fi
285 echo
286done
287## STDOUT:
288 arg zz
289unlimited
290status=0
291FAILED
292
293 arg unlimited
294unlimited
295status=0
296
297## END
298
299
300#### ulimit of 2**32, 2**31 (int overflow)
301
302echo -n 'one '; ulimit -f
303
304
305ulimit -f $(( 1 << 32 ))
306
307echo -n 'two '; ulimit -f
308
309
310# mksh fails because it overflows signed int, turning into negative number
311ulimit -f $(( 1 << 31 ))
312
313echo -n 'three '; ulimit -f
314
315## STDOUT:
316one unlimited
317two 4294967296
318three 2147483648
319## END
320## BUG mksh STDOUT:
321one unlimited
322two 1
323three 1
324## END
325
326
327#### ulimit that is 64 bits
328
329# no 64-bit integers
330case $SH in mksh) exit ;; esac
331
332echo -n 'before '; ulimit -f
333
334# 1 << 63 overflows signed int
335
336# 512 is 1 << 9, so make it 62-9 = 53 bits
337
338lim=$(( 1 << 53 ))
339#echo $lim
340
341# bash says this is out of range
342ulimit -f $lim
343
344echo -n 'after '; ulimit -f
345
346## STDOUT:
347before unlimited
348after 9007199254740992
349## END
350
351## BUG mksh STDOUT:
352## END
353
354
355#### arg that would overflow 64 bits is detected
356
357# no 64-bit integers
358case $SH in mksh) exit ;; esac
359
360echo -n 'before '; ulimit -f
361
362# 1 << 63 overflows signed int
363
364lim=$(( (1 << 62) + 1 ))
365#echo lim=$lim
366
367# bash detects that this is out of range
368# so does osh-cpp, but not osh-cpython
369
370ulimit -f $lim
371echo -n 'after '; ulimit -f
372
373## STDOUT:
374before unlimited
375after unlimited
376## END
377
378## BUG dash/zsh STDOUT:
379before unlimited
380after 1
381## END
382
383## BUG mksh STDOUT:
384## END
385
386
387#### ulimit -f 1 prevents files larger 512 bytes
388trap - XFSZ # don't handle this
389
390rm -f err.txt
391touch err.txt
392
393bytes() {
394 local n=$1
395 local st=0
396 for i in $(seq $n); do
397 echo -n x
398 st=$?
399 if test $st -ne 0; then
400 echo "ERROR: echo failed with status $st" >> err.txt
401 fi
402 done
403}
404
405ulimit -f 1
406
407bytes 512 > ok.txt
408echo 512 status=$?
409
410bytes 513 > too-big.txt
411echo 513 status=$?
412echo
413
414wc --bytes ok.txt too-big.txt
415echo
416
417cat err.txt
418
419## status: -25
420## STDOUT:
421512 status=0
422## END
423
424## OK disabledosh status: 0
425## OK disabledosh STDOUT:
426512 status=0
427513 status=0
428
429 512 ok.txt
430 512 too-big.txt
4311024 total
432
433ERROR: echo failed with status 1
434## END
435
436## BUG bash status: 0
437## BUG bash STDOUT:
438512 status=0
439513 status=0
440
441 512 ok.txt
442 513 too-big.txt
4431025 total
444
445## END
446
447#### write big file with ulimit
448
449# I think this will test write() errors, rather than the final flush() error
450# (which is currently skipped by C++
451
452{ echo 'ulimit -f 1'
453 # More than 8 KiB may cause a flush()
454 python2 -c 'print("echo " + "X"*9000 + " >out.txt")'
455 echo 'echo inner=$?'
456} > big.sh
457
458$SH big.sh
459echo outer=$?
460
461## STDOUT:
462outer=153
463## END
464
465# not sure why this is different
466## OK osh STDOUT:
467inner=1
468outer=0
469## END
470
471
472#### ulimit -S for soft limit (default), -H for hard limit
473case $SH in dash|zsh) exit ;; esac
474
475# Note: ulimit -n -S 1111 is OK in osh/dash/mksh, but not bash/zsh
476# Mus be ulimit -S -n 1111
477
478show_state() {
479 local msg=$1
480 echo "$msg"
481 echo -n ' '; ulimit -S -t
482 echo -n ' '; ulimit -H -t
483 echo
484}
485
486show_state 'init'
487
488ulimit -S -t 123456
489show_state '-S'
490
491ulimit -H -t 123457
492show_state '-H'
493
494ulimit -t 123455
495show_state 'no flag'
496
497echo 'GET'
498
499ulimit -S -t 123454
500echo -n ' '; ulimit -t
501echo -n ' '; ulimit -S -t
502echo -n ' '; ulimit -H -t
503
504## STDOUT:
505init
506 unlimited
507 unlimited
508
509-S
510 123456
511 unlimited
512
513-H
514 123456
515 123457
516
517no flag
518 123455
519 123455
520
521GET
522 123454
523 123454
524 123455
525## END
526
527## BUG dash/zsh STDOUT:
528## END
529
530#### Changing resource limit is denied
531
532# Not sure why these don't work
533case $SH in dash|mksh) exit ;; esac
534
535
536flag=-t
537
538ulimit -S -H $flag 100
539echo both=$?
540
541ulimit -S $flag 90
542echo soft=$?
543
544ulimit -S $flag 95
545echo soft=$?
546
547ulimit -S $flag 105
548if test $? -ne 0; then
549 echo soft OK
550else
551 echo soft fail
552fi
553
554ulimit -H $flag 200
555if test $? -ne 0; then
556 echo hard OK
557else
558 echo hard fail
559fi
560
561## STDOUT:
562both=0
563soft=0
564soft=0
565soft OK
566hard OK
567## END
568
569## BUG dash/mksh STDOUT:
570## END
571
572#### ulimit -n limits file descriptors
573
574# OSH bug
575# https://oilshell.zulipchat.com/#narrow/channel/502349-osh/topic/alpine.20build.20failures.20-.20make.20-.20ulimit.20-n.2064/with/519691301
576
577$SH -c 'ulimit -n 64; echo hi >out'
578echo status=$?
579
580$SH -c 'ulimit -n 0; echo hi >out'
581echo status=$?
582
583## STDOUT:
584status=0
585status=1
586## END
587
588## OK dash STDOUT:
589status=0
590status=2
591## END