blob: b96555c7e7fae28c8d9b8d250c0ccc1b1819dd25 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
|
# 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 pipe signal wait alarm
# 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" {
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 {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 -result {invalid command name "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 -result {invalid command name "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} -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
|