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

622 lines, 275 significant
1## compare_shells: dash bash mksh zsh
2## oils_failures_allowed: 2
3## oils_cpp_failures_allowed: 3
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#### get umask
114umask | grep '[0-9]\+' # check for digits
115## status: 0
116
117#### set umask in octal
118rm -f $TMP/umask-one $TMP/umask-two
119umask 0002
120echo one > $TMP/umask-one
121umask 0022
122echo two > $TMP/umask-two
123stat -c '%a' $TMP/umask-one $TMP/umask-two
124## status: 0
125## STDOUT:
126664
127644
128## END
129## stderr-json: ""
130
131#### set umask symbolically
132umask 0002 # begin in a known state for the test
133rm -f $TMP/umask-one $TMP/umask-two
134echo one > $TMP/umask-one
135umask g-w,o-w
136echo two > $TMP/umask-two
137stat -c '%a' $TMP/umask-one $TMP/umask-two
138## status: 0
139## STDOUT:
140664
141644
142## END
143## stderr-json: ""
144
145#### ulimit with no flags is like -f
146
147ulimit > no-flags.txt
148echo status=$?
149
150ulimit -f > f.txt
151echo status=$?
152
153diff -u no-flags.txt f.txt
154echo diff=$?
155
156# Print everything
157# ulimit -a
158
159## STDOUT:
160status=0
161status=0
162diff=0
163## END
164
165
166#### ulimit too many args
167
168ulimit 1 2
169if test $? -ne 0; then
170 echo pass
171else
172 echo fail
173fi
174
175#ulimit -f
176
177## STDOUT:
178pass
179## END
180
181## BUG bash/zsh STDOUT:
182fail
183## END
184
185
186#### ulimit negative flag
187
188ulimit -f
189
190# interpreted as a flag
191ulimit -f -42
192if test $? -ne 0; then
193 echo pass
194else
195 echo fail
196fi
197
198## STDOUT:
199unlimited
200pass
201## END
202
203#### ulimit negative arg
204
205ulimit -f
206
207# an arg
208ulimit -f -- -42
209if test $? -ne 0; then
210 echo pass
211else
212 echo fail
213fi
214
215## STDOUT:
216unlimited
217pass
218## END
219
220## BUG mksh STDOUT:
221unlimited
222fail
223## END
224
225
226#### ulimit -a doesn't take arg
227case $SH in bash) exit ;; esac
228
229ulimit -a 42
230if test $? -ne 0; then
231 echo 'failure that was expected'
232fi
233
234## STDOUT:
235failure that was expected
236## END
237## BUG bash STDOUT:
238## END
239
240
241#### ulimit doesn't accept multiple flags - reduce confusion between shells
242
243# - bash, zsh, busybox ash accept multiple "commands", which requires custom
244# flag parsing, like
245
246# ulimit -f 999 -n
247# ulimit -f 999 -n 888
248#
249# - dash and mksh accept a single ARG
250#
251# we want to make it clear we're like the latter
252
253# can't print all and -f
254ulimit -f -a >/dev/null
255echo status=$?
256
257ulimit -f -n >/dev/null
258echo status=$?
259
260ulimit -f -n 999 >/dev/null
261echo status=$?
262
263## STDOUT:
264status=2
265status=2
266status=2
267## END
268
269## BUG dash/bash/mksh STDOUT:
270status=0
271status=0
272status=0
273## END
274
275# zsh is better - it checks that -a and -f are exclusive
276
277## BUG zsh STDOUT:
278status=1
279status=0
280status=0
281## END
282
283
284#### YSH readability: ulimit --all the same as ulimit -a
285
286case $SH in bash|dash|mksh|zsh) exit ;; esac
287
288ulimit -a > short.txt
289ulimit --all > long.txt
290
291wc -l short.txt long.txt
292
293diff -u short.txt long.txt
294echo status=$?
295
296## STDOUT:
297 8 short.txt
298 8 long.txt
299 16 total
300status=0
301## END
302
303## N-I bash/dash/mksh/zsh STDOUT:
304## END
305
306#### ulimit accepts 'unlimited'
307
308for arg in zz unlimited; do
309 echo " arg $arg"
310 ulimit -f
311 echo status=$?
312 ulimit -f $arg
313 if test $? -ne 0; then
314 echo 'FAILED'
315 fi
316 echo
317done
318## STDOUT:
319 arg zz
320unlimited
321status=0
322FAILED
323
324 arg unlimited
325unlimited
326status=0
327
328## END
329
330
331#### ulimit of 2**32, 2**31 (int overflow)
332
333echo -n 'one '; ulimit -f
334
335
336ulimit -f $(( 1 << 32 ))
337
338echo -n 'two '; ulimit -f
339
340
341# mksh fails because it overflows signed int, turning into negative number
342ulimit -f $(( 1 << 31 ))
343
344echo -n 'three '; ulimit -f
345
346## STDOUT:
347one unlimited
348two 4294967296
349three 2147483648
350## END
351## BUG mksh STDOUT:
352one unlimited
353two 1
354three 1
355## END
356
357
358#### ulimit that is 64 bits
359
360# no 64-bit integers
361case $SH in mksh) exit ;; esac
362
363echo -n 'before '; ulimit -f
364
365# 1 << 63 overflows signed int
366
367# 512 is 1 << 9, so make it 62-9 = 53 bits
368
369lim=$(( 1 << 53 ))
370#echo $lim
371
372# bash says this is out of range
373ulimit -f $lim
374
375echo -n 'after '; ulimit -f
376
377## STDOUT:
378before unlimited
379after 9007199254740992
380## END
381
382## BUG mksh STDOUT:
383## END
384
385
386#### arg that would overflow 64 bits is detected
387
388# no 64-bit integers
389case $SH in mksh) exit ;; esac
390
391echo -n 'before '; ulimit -f
392
393# 1 << 63 overflows signed int
394
395lim=$(( (1 << 62) + 1 ))
396#echo lim=$lim
397
398# bash detects that this is out of range
399# so does osh-cpp, but not osh-cpython
400
401ulimit -f $lim
402echo -n 'after '; ulimit -f
403
404## STDOUT:
405before unlimited
406after unlimited
407## END
408
409## BUG dash/zsh STDOUT:
410before unlimited
411after 1
412## END
413
414## BUG mksh STDOUT:
415## END
416
417
418#### ulimit -f 1 prevents files larger 512 bytes
419trap - XFSZ # don't handle this
420
421rm -f err.txt
422touch err.txt
423
424bytes() {
425 local n=$1
426 local st=0
427 for i in $(seq $n); do
428 echo -n x
429 st=$?
430 if test $st -ne 0; then
431 echo "ERROR: echo failed with status $st" >> err.txt
432 fi
433 done
434}
435
436ulimit -f 1
437
438bytes 512 > ok.txt
439echo 512 status=$?
440
441bytes 513 > too-big.txt
442echo 513 status=$?
443echo
444
445wc --bytes ok.txt too-big.txt
446echo
447
448cat err.txt
449
450## status: -25
451## STDOUT:
452512 status=0
453## END
454
455## OK disabledosh status: 0
456## OK disabledosh STDOUT:
457512 status=0
458513 status=0
459
460 512 ok.txt
461 512 too-big.txt
4621024 total
463
464ERROR: echo failed with status 1
465## END
466
467## BUG bash status: 0
468## BUG bash STDOUT:
469512 status=0
470513 status=0
471
472 512 ok.txt
473 513 too-big.txt
4741025 total
475
476## END
477
478#### write big file with ulimit
479
480# I think this will test write() errors, rather than the final flush() error
481# (which is currently skipped by C++
482
483{ echo 'ulimit -f 1'
484 # More than 8 KiB may cause a flush()
485 python2 -c 'print("echo " + "X"*9000 + " >out.txt")'
486 echo 'echo inner=$?'
487} > big.sh
488
489$SH big.sh
490echo outer=$?
491
492## STDOUT:
493outer=153
494## END
495
496# not sure why this is different
497## OK osh STDOUT:
498inner=1
499outer=0
500## END
501
502
503#### ulimit -S for soft limit (default), -H for hard limit
504case $SH in dash|zsh) exit ;; esac
505
506# Note: ulimit -n -S 1111 is OK in osh/dash/mksh, but not bash/zsh
507# Mus be ulimit -S -n 1111
508
509show_state() {
510 local msg=$1
511 echo "$msg"
512 echo -n ' '; ulimit -S -t
513 echo -n ' '; ulimit -H -t
514 echo
515}
516
517show_state 'init'
518
519ulimit -S -t 123456
520show_state '-S'
521
522ulimit -H -t 123457
523show_state '-H'
524
525ulimit -t 123455
526show_state 'no flag'
527
528echo 'GET'
529
530ulimit -S -t 123454
531echo -n ' '; ulimit -t
532echo -n ' '; ulimit -S -t
533echo -n ' '; ulimit -H -t
534
535## STDOUT:
536init
537 unlimited
538 unlimited
539
540-S
541 123456
542 unlimited
543
544-H
545 123456
546 123457
547
548no flag
549 123455
550 123455
551
552GET
553 123454
554 123454
555 123455
556## END
557
558## BUG dash/zsh STDOUT:
559## END
560
561#### Changing resource limit is denied
562
563# Not sure why these don't work
564case $SH in dash|mksh) exit ;; esac
565
566
567flag=-t
568
569ulimit -S -H $flag 100
570echo both=$?
571
572ulimit -S $flag 90
573echo soft=$?
574
575ulimit -S $flag 95
576echo soft=$?
577
578ulimit -S $flag 105
579if test $? -ne 0; then
580 echo soft OK
581else
582 echo soft fail
583fi
584
585ulimit -H $flag 200
586if test $? -ne 0; then
587 echo hard OK
588else
589 echo hard fail
590fi
591
592## STDOUT:
593both=0
594soft=0
595soft=0
596soft OK
597hard OK
598## END
599
600## BUG dash/mksh STDOUT:
601## END
602
603#### ulimit -n limits file descriptors
604
605# OSH bug
606# https://oilshell.zulipchat.com/#narrow/channel/502349-osh/topic/alpine.20build.20failures.20-.20make.20-.20ulimit.20-n.2064/with/519691301
607
608$SH -c 'ulimit -n 64; echo hi >out'
609echo status=$?
610
611$SH -c 'ulimit -n 0; echo hi >out'
612echo status=$?
613
614## STDOUT:
615status=0
616status=1
617## END
618
619## OK dash STDOUT:
620status=0
621status=2
622## END