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

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