175 lines
5.2 KiB
Plaintext
175 lines
5.2 KiB
Plaintext
# These tests are design especially for the vfork() implementation
|
|
# of exec where sh -c must be used and thus we must take extra care
|
|
# in quoting arguments to exec.
|
|
|
|
source [file dirname [info script]]/testing.tcl
|
|
|
|
needs cmd exec
|
|
testCmdConstraints signal wait alarm after
|
|
|
|
# Jim needs [pipe] to implement [open |command]
|
|
if {[testConstraint tcl]} {
|
|
testConstraint pipe 1
|
|
} else {
|
|
testCmdConstraints pipe
|
|
}
|
|
|
|
# Some Windows platforms (e.g. AppVeyor) produce ENOSPC rather than killing
|
|
# the child with SIGPIPE). So turn off this test for that platform
|
|
if {[info exists env(MSYSTEM)] && $env(MSYSTEM) eq "MINGW32"} {
|
|
testConstraint nomingw32 0
|
|
} else {
|
|
testConstraint nomingw32 1
|
|
}
|
|
|
|
set d \"
|
|
set s '
|
|
set b \\
|
|
|
|
array set saveenv [array get env]
|
|
|
|
test exec2-1.1 "Quoting - Result" {
|
|
exec echo ${d}double quoted${d} ${s}single quoted${s} ${b}backslash quoted${b}
|
|
} "\"double\ quoted\"\ 'single quoted'\ \\backslash\ quoted\\"
|
|
|
|
test exec2-1.2 "Quoting - Word Grouping" {
|
|
string trim [exec echo ${d}double quoted${d} ${s}single quoted${s} ${b}backslash quoted${b} | wc -w]
|
|
} {6}
|
|
|
|
test exec2-2.1 "Add to exec environment" {
|
|
set env(TESTENV) "the value"
|
|
exec printenv | sed -n -e /^TESTENV=/p
|
|
} {TESTENV=the value}
|
|
|
|
test exec2-2.2 "Remove from exec environment" {
|
|
set env(TESTENV2) "new value"
|
|
unset env(TESTENV)
|
|
exec printenv | sed -n -e /^TESTENV=/p
|
|
} {}
|
|
|
|
|
|
test exec2-2.3 "Remove all exec environment" {
|
|
array unset env *
|
|
exec printenv | sed -n -e /^TESTENV2=/p
|
|
} {}
|
|
|
|
test exec2-2.4 "Remove all env var" {
|
|
unset -nocomplain env
|
|
exec printenv | sed -n -e /^TESTENV2=/p
|
|
} {}
|
|
|
|
array set env [array get saveenv]
|
|
|
|
test exec2-3.1 "close pipeline return value" pipe {
|
|
set f [open |false]
|
|
set rc [catch {close $f} msg opts]
|
|
lassign [dict get $opts -errorcode] status pid exitcode
|
|
list $rc $msg $status $exitcode
|
|
} {1 {child process exited abnormally} CHILDSTATUS 1}
|
|
|
|
test exec2-3.2 "close pipeline return value" -constraints {jim pipe nomingw32} -body {
|
|
# Create a pipe and immediately close the read end
|
|
lassign [pipe] r w
|
|
close $r
|
|
# Write more than 64KB which is maximum size of the pipe buffers
|
|
# on all systems we have seen
|
|
set bigstring [string repeat a 100000]
|
|
set f [open [list |cat << $bigstring >$@w]]
|
|
set rc [catch {close $f} msg opts]
|
|
lassign [dict get $opts -errorcode] status pid exitcode
|
|
list $rc $msg $status $exitcode
|
|
} -match glob -result {1 {child killed*} CHILDKILLED SIGPIPE}
|
|
|
|
test exec2-3.3 "close pipeline with SIGPIPE blocked" -constraints {pipe signal nomingw32} -body {
|
|
# Create a pipe and immediately close the read end
|
|
lassign [pipe] r w
|
|
close $r
|
|
signal block SIGPIPE
|
|
# Write more than 64KB which is maximum size of the pipe buffers
|
|
# on all systems we have seen
|
|
set bigstring [string repeat a 100000]
|
|
set f [open [list |cat << $bigstring >$@w 2>/dev/null]]
|
|
set rc [catch {close $f} msg opts]
|
|
lassign [dict get $opts -errorcode] status pid exitcode
|
|
list $rc $msg $status $exitcode
|
|
} -match glob -result {1 {child process exited*} CHILDSTATUS 1} -cleanup {
|
|
signal default SIGPIPE
|
|
}
|
|
|
|
test exec2-3.4 "wait for background task" -constraints wait -body {
|
|
set pid [exec sleep 0.1 &]
|
|
lassign [wait $pid] status newpid exitcode
|
|
if {$pid != $newpid} {
|
|
error "Got wrong pid from wait"
|
|
} else {
|
|
list $status $exitcode
|
|
}
|
|
} -result {CHILDSTATUS 0}
|
|
|
|
test exec2-4.1 {redirect from invalid filehandle} -body {
|
|
exec cat <@bogus
|
|
} -returnCodes error -match glob -result {*"bogus"}
|
|
|
|
test exec2-4.2 {env is invalid dict} -constraints jim -body {
|
|
set saveenv $env
|
|
lappend env bogus
|
|
catch {exec pwd}
|
|
} -result {0} -cleanup {
|
|
set env $saveenv
|
|
}
|
|
|
|
test exec2-4.3 {signalled process during foreground exec} -constraints {jim alarm} -body {
|
|
# We need to exec a pipeline and then have one process
|
|
# be killed by a signal
|
|
exec [info nameofexecutable] -e {alarm 0.1; sleep 0.5}
|
|
} -returnCodes error -result {child killed by signal SIGALRM}
|
|
|
|
test exec2-4.4 {exec - consecutive |} -body {
|
|
exec echo | | test
|
|
} -returnCodes error -result {illegal use of | or |& in command}
|
|
|
|
test exec2-4.5 {exec - consecutive | with &} -body {
|
|
exec echo | | test &
|
|
} -returnCodes error -result {illegal use of | or |& in command}
|
|
|
|
test exec2-4.6 {exec - illegal channel} -body {
|
|
exec echo hello >@nonexistent
|
|
} -returnCodes error -match glob -result {*"nonexistent"}
|
|
|
|
test exec2-5.1 {wait with invalid pid} wait {
|
|
wait 9999999
|
|
} {NONE -1 -1}
|
|
|
|
test exec2-5.2 {wait with invalid pid} -constraints wait -body {
|
|
wait blah
|
|
} -returnCodes error -result {expected integer but got "blah"}
|
|
|
|
test exec2-5.3 {wait - bad args} -constraints wait -body {
|
|
wait too many args
|
|
} -returnCodes error -result {wrong # args: should be "wait ?-nohang? ?pid?"}
|
|
|
|
test exec2-5.4 {wait -nohang} -constraints wait -body {
|
|
set pid [exec sleep 0.2 &]
|
|
# first wait will do nothing as the process is not finished
|
|
wait -nohang $pid
|
|
wait $pid
|
|
} -match glob -result {CHILDSTATUS * 0}
|
|
|
|
test exec2-5.5 {wait for all children} -constraints {after jim} -body {
|
|
# We want to have children finish at different times
|
|
# so that we test the handling of the wait table
|
|
foreach i {0.1 0.2 0.6 0.5 0.4 0.3} {
|
|
exec sleep $i &
|
|
}
|
|
# reap zombies, there should not be any
|
|
wait
|
|
after 300
|
|
# reap zombies, 2-3 should be finished now
|
|
wait
|
|
after 400
|
|
# reap zombies, all processes should be finished now
|
|
wait
|
|
} -result {}
|
|
|
|
testreport
|