Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/tcl8.5.2/tests/exec.test @ 68

Last change on this file since 68 was 25, checked in by landauf, 16 years ago

added tcl to libs

File size: 25.5 KB
Line 
1# Commands covered:  exec
2#
3# This file contains a collection of tests for one or more of the Tcl
4# built-in commands.  Sourcing this file into Tcl runs the tests and
5# generates output for errors.  No output means no errors were found.
6#
7# Copyright (c) 1991-1994 The Regents of the University of California.
8# Copyright (c) 1994-1997 Sun Microsystems, Inc.
9# Copyright (c) 1998-1999 by Scriptics Corporation.
10#
11# See the file "license.terms" for information on usage and redistribution
12# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13#
14# RCS: @(#) $Id: exec.test,v 1.29 2008/03/11 22:23:33 das Exp $
15
16package require tcltest 2
17namespace import -force ::tcltest::*
18
19# All tests require the "exec" command.
20# Skip them if exec is not defined.
21testConstraint exec [llength [info commands exec]]
22unset -nocomplain path
23set path(echo) [makeFile {
24    puts -nonewline [lindex $argv 0]
25    foreach str [lrange $argv 1 end] {
26        puts -nonewline " $str"
27    }
28    puts {}
29    exit
30} echo]
31
32set path(echo2) [makeFile {
33    puts stdout [join $argv]
34    puts stderr [lindex $argv 1]
35    exit
36} echo2]
37
38set path(cat) [makeFile {
39    if {$argv == {}} {
40        set argv -
41    }
42    foreach name $argv {
43        if {$name == "-"} {
44            set f stdin
45        } elseif {[catch {open $name r} f] != 0} {
46            puts stderr $f
47            continue
48        }
49        while {[eof $f] == 0} {
50            puts -nonewline [read $f]
51        }
52        if {$f != "stdin"} {
53            close $f
54        }
55    }
56    exit
57} cat]
58
59set path(wc) [makeFile {
60    set data [read stdin]
61    set lines [regsub -all "\n" $data {} dummy]
62    set words [regsub -all "\[^ \t\n]+" $data {} dummy]
63    set chars [string length $data]
64    puts [format "%8.d%8.d%8.d" $lines $words $chars]
65    exit
66} wc]
67
68set path(sh) [makeFile {
69    if {[lindex $argv 0] != "-c"} {
70        error "sh: unexpected arguments $argv"
71    }
72    set cmd [lindex $argv 1]
73    lappend cmd ";"
74
75    set newcmd {}
76   
77    foreach arg $cmd {
78        if {$arg == ";"} {
79            eval exec >@stdout 2>@stderr [list [info nameofexecutable]] $newcmd
80            set newcmd {}
81            continue
82        }
83        if {$arg == "1>&2"} {
84            set arg >@stderr
85        }
86        lappend newcmd $arg
87    }
88    exit
89} sh]
90set path(sh2) [makeFile {
91    if {[lindex $argv 0] != "-c"} {
92        error "sh: unexpected arguments $argv"
93    }
94    set cmd [lindex $argv 1]
95    lappend cmd ";"
96
97    set newcmd {}
98   
99    foreach arg $cmd {
100        if {$arg == ";"} {
101            eval exec -ignorestderr >@stdout [list [info nameofexecutable]] $newcmd
102            set newcmd {}
103            continue
104        }
105        lappend newcmd $arg
106    }
107    exit
108} sh2]
109
110set path(sleep) [makeFile {
111    after [expr $argv*1000]
112    exit
113} sleep]
114
115set path(exit) [makeFile {
116    exit $argv
117} exit]
118
119# Basic operations.
120
121test exec-1.1 {basic exec operation} {exec} {
122    exec [interpreter] $path(echo) a b c
123} "a b c"
124test exec-1.2 {pipelining} {exec stdio} {
125    exec [interpreter] $path(echo) a b c d | [interpreter] $path(cat) | [interpreter] $path(cat)
126} "a b c d"
127test exec-1.3 {pipelining} {exec stdio} {
128    set a [exec [interpreter] $path(echo) a b c d | [interpreter] $path(cat) | [interpreter] $path(wc)]
129    list [scan $a "%d %d %d" b c d] $b $c
130} {3 1 4}
131set arg {12345678901234567890123456789012345678901234567890}
132set arg "$arg$arg$arg$arg$arg$arg"
133test exec-1.4 {long command lines} {exec} {
134    exec [interpreter] $path(echo) $arg
135} $arg
136set arg {}
137
138# I/O redirection: input from Tcl command.
139
140test exec-2.1 {redirecting input from immediate source} {exec stdio} {
141    exec [interpreter] $path(cat) << "Sample text"
142} {Sample text}
143test exec-2.2 {redirecting input from immediate source} {exec stdio} {
144    exec << "Sample text" [interpreter] $path(cat) | [interpreter] $path(cat)
145} {Sample text}
146test exec-2.3 {redirecting input from immediate source} {exec stdio} {
147    exec [interpreter] $path(cat) << "Sample text" | [interpreter] $path(cat)
148} {Sample text}
149test exec-2.4 {redirecting input from immediate source} {exec stdio} {
150    exec [interpreter] $path(cat) | [interpreter] $path(cat) << "Sample text"
151} {Sample text}
152test exec-2.5 {redirecting input from immediate source} {exec} {
153    exec [interpreter] $path(cat) "<<Joined to arrows"
154} {Joined to arrows}
155test exec-2.6 {redirecting input from immediate source, with UTF} {exec} {
156    # If this fails, it may give back:
157    # "\uC3\uA9\uC3\uA0\uC3\uBC\uC3\uB1"
158    # If it does, this means that the UTF -> external conversion did not
159    # occur before writing out the temp file.
160    exec [interpreter] $path(cat) << "\uE9\uE0\uFC\uF1"
161} "\uE9\uE0\uFC\uF1"
162
163# I/O redirection: output to file.
164
165set path(gorp.file) [makeFile {} gorp.file]
166file delete $path(gorp.file)
167
168test exec-3.1 {redirecting output to file} {exec} {
169    exec [interpreter] $path(echo) "Some simple words" > $path(gorp.file)
170    exec [interpreter] $path(cat) $path(gorp.file)
171} "Some simple words"
172test exec-3.2 {redirecting output to file} {exec stdio} {
173    exec [interpreter] $path(echo) "More simple words" | >$path(gorp.file) [interpreter] $path(cat) | [interpreter] $path(cat)
174    exec [interpreter] $path(cat) $path(gorp.file)
175} "More simple words"
176test exec-3.3 {redirecting output to file} {exec stdio} {
177    exec > $path(gorp.file) [interpreter] $path(echo) "Different simple words" | [interpreter] $path(cat) | [interpreter] $path(cat)
178    exec [interpreter] $path(cat) $path(gorp.file)
179} "Different simple words"
180test exec-3.4 {redirecting output to file} {exec} {
181    exec [interpreter] $path(echo) "Some simple words" >$path(gorp.file)
182    exec [interpreter] $path(cat) $path(gorp.file)
183} "Some simple words"
184test exec-3.5 {redirecting output to file} {exec} {
185    exec [interpreter] $path(echo) "First line" >$path(gorp.file)
186    exec [interpreter] $path(echo) "Second line" >> $path(gorp.file)
187    exec [interpreter] $path(cat) $path(gorp.file)
188} "First line\nSecond line"
189test exec-3.6 {redirecting output to file} {exec} {
190    exec [interpreter] $path(echo) "First line" >$path(gorp.file)
191    exec [interpreter] $path(echo) "Second line" >>$path(gorp.file)
192    exec [interpreter] $path(cat) $path(gorp.file)
193} "First line\nSecond line"
194test exec-3.7 {redirecting output to file} {exec} {
195    set f [open $path(gorp.file) w]
196    puts $f "Line 1"
197    flush $f
198    exec [interpreter] $path(echo) "More text" >@ $f
199    exec [interpreter] $path(echo) >@$f "Even more"
200    puts $f "Line 3"
201    close $f
202    exec [interpreter] $path(cat) $path(gorp.file)
203} "Line 1\nMore text\nEven more\nLine 3"
204
205# I/O redirection: output and stderr to file.
206
207file delete $path(gorp.file)
208
209test exec-4.1 {redirecting output and stderr to file} {exec} {
210    exec [interpreter] "$path(echo)" "test output" >& $path(gorp.file)
211    exec [interpreter] "$path(cat)" "$path(gorp.file)"
212} "test output"
213test exec-4.2 {redirecting output and stderr to file} {exec} {
214    list [exec [interpreter] "$path(sh)" -c "\"$path(echo)\" foo bar 1>&2" >&$path(gorp.file)] \
215            [exec [interpreter] "$path(cat)" "$path(gorp.file)"]
216} {{} {foo bar}}
217test exec-4.3 {redirecting output and stderr to file} {exec} {
218    exec [interpreter] $path(echo) "first line" > $path(gorp.file)
219    list [exec [interpreter] "$path(sh)" -c "\"$path(echo)\" foo bar 1>&2" >>&$path(gorp.file)] \
220            [exec [interpreter] "$path(cat)" "$path(gorp.file)"]
221} "{} {first line\nfoo bar}"
222test exec-4.4 {redirecting output and stderr to file} {exec} {
223    set f [open "$path(gorp.file)" w]
224    puts $f "Line 1"
225    flush $f
226    exec [interpreter] "$path(echo)" "More text" >&@ $f
227    exec [interpreter] "$path(echo)" >&@$f "Even more"
228    puts $f "Line 3"
229    close $f
230    exec [interpreter] "$path(cat)" "$path(gorp.file)"
231} "Line 1\nMore text\nEven more\nLine 3"
232test exec-4.5 {redirecting output and stderr to file} {exec} {
233    set f [open "$path(gorp.file)" w]
234    puts $f "Line 1"
235    flush $f
236    exec >&@ $f [interpreter] "$path(sh)" -c "\"$path(echo)\" foo bar 1>&2"
237    exec >&@$f [interpreter] "$path(sh)" -c "\"$path(echo)\" xyzzy 1>&2"
238    puts $f "Line 3"
239    close $f
240    exec [interpreter] "$path(cat)" "$path(gorp.file)"
241} "Line 1\nfoo bar\nxyzzy\nLine 3"
242
243# I/O redirection: input from file.
244
245if {[testConstraint exec]} {
246    exec [interpreter] $path(echo) "Just a few thoughts" > $path(gorp.file)
247}
248test exec-5.1 {redirecting input from file} {exec} {
249    exec [interpreter] $path(cat) < $path(gorp.file)
250} {Just a few thoughts}
251test exec-5.2 {redirecting input from file} {exec stdio} {
252    exec [interpreter] $path(cat) | [interpreter] $path(cat) < $path(gorp.file)
253} {Just a few thoughts}
254test exec-5.3 {redirecting input from file} {exec stdio} {
255    exec [interpreter] $path(cat) < $path(gorp.file) | [interpreter] $path(cat)
256} {Just a few thoughts}
257test exec-5.4 {redirecting input from file} {exec stdio} {
258    exec < $path(gorp.file) [interpreter] $path(cat) | [interpreter] $path(cat)
259} {Just a few thoughts}
260test exec-5.5 {redirecting input from file} {exec} {
261    exec [interpreter] $path(cat) <$path(gorp.file)
262} {Just a few thoughts}
263test exec-5.6 {redirecting input from file} {exec} {
264    set f [open $path(gorp.file) r]
265    set result [exec [interpreter] $path(cat) <@ $f]
266    close $f
267    set result
268} {Just a few thoughts}
269test exec-5.7 {redirecting input from file} {exec} {
270    set f [open $path(gorp.file) r]
271    set result [exec <@$f [interpreter] $path(cat)]
272    close $f
273    set result
274} {Just a few thoughts}
275
276# I/O redirection: standard error through a pipeline.
277
278test exec-6.1 {redirecting stderr through a pipeline} {exec stdio} {
279    exec [interpreter] "$path(sh)" -c "\"$path(echo)\" foo bar" |& [interpreter] "$path(cat)"
280} "foo bar"
281test exec-6.2 {redirecting stderr through a pipeline} {exec stdio} {
282    exec [interpreter] "$path(sh)" -c "\"$path(echo)\" foo bar 1>&2" |& [interpreter] "$path(cat)"
283} "foo bar"
284test exec-6.3 {redirecting stderr through a pipeline} {exec stdio} {
285    exec [interpreter] "$path(sh)" -c "\"$path(echo)\" foo bar 1>&2" \
286        |& [interpreter] "$path(sh)" -c "\"$path(echo)\" second msg 1>&2 ; \"$path(cat)\"" |& [interpreter] "$path(cat)"
287} "second msg\nfoo bar"
288
289# I/O redirection: combinations.
290
291set path(gorp.file2) [makeFile {} gorp.file2]
292file delete $path(gorp.file2)
293
294test exec-7.1 {multiple I/O redirections} {exec} {
295    exec << "command input" > $path(gorp.file2) [interpreter] $path(cat) < $path(gorp.file)
296    exec [interpreter] $path(cat) $path(gorp.file2)
297} {Just a few thoughts}
298test exec-7.2 {multiple I/O redirections} {exec} {
299    exec < $path(gorp.file) << "command input" [interpreter] $path(cat)
300} {command input}
301
302# Long input to command and output from command.
303
304set a "0123456789 xxxxxxxxx abcdefghi ABCDEFGHIJK\n"
305set a [concat $a $a $a $a]
306set a [concat $a $a $a $a]
307set a [concat $a $a $a $a]
308set a [concat $a $a $a $a]
309test exec-8.1 {long input and output} {exec} {
310    exec [interpreter] $path(cat) << $a
311} $a
312
313# More than 20 arguments to exec.
314
315test exec-8.2 {long input and output} {exec} {
316    exec [interpreter] $path(echo) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
317} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23}
318
319# Commands that return errors.
320
321test exec-9.1 {commands returning errors} {exec} {
322    set x [catch {exec gorp456} msg]
323    list $x [string tolower $msg] [string tolower $errorCode]
324} {1 {couldn't execute "gorp456": no such file or directory} {posix enoent {no such file or directory}}}
325test exec-9.2 {commands returning errors} {exec} {
326    string tolower [list [catch {exec [interpreter] echo foo | foo123} msg] $msg $errorCode]
327} {1 {couldn't execute "foo123": no such file or directory} {posix enoent {no such file or directory}}}
328test exec-9.3 {commands returning errors} {exec stdio} {
329    list [catch {exec [interpreter] $path(sleep) 1 | [interpreter] $path(exit) 43 | [interpreter] $path(sleep) 1} msg] $msg
330} {1 {child process exited abnormally}}
331test exec-9.4 {commands returning errors} {exec stdio} {
332    list [catch {exec [interpreter] $path(exit) 43 | [interpreter] $path(echo) "foo bar"} msg] $msg
333} {1 {foo bar
334child process exited abnormally}}
335test exec-9.5 {commands returning errors} {exec stdio} {
336    list [catch {exec gorp456 | [interpreter] echo a b c} msg] [string tolower $msg]
337} {1 {couldn't execute "gorp456": no such file or directory}}
338test exec-9.6 {commands returning errors} {exec} {
339    list [catch {exec [interpreter] "$path(sh)" -c "\"$path(echo)\" error msg 1>&2"} msg] $msg
340} {1 {error msg}}
341test exec-9.7 {commands returning errors} {exec stdio} {
342    list [catch {exec [interpreter] "$path(sh)" -c "\"$path(echo)\" error msg 1>&2 ; \"$path(sleep)\" 1" \
343                    | [interpreter] "$path(sh)" -c "\"$path(echo)\" error msg 1>&2 ; \"$path(sleep)\" 1"} msg] $msg
344} {1 {error msg
345error msg}}
346
347set path(err) [makeFile {} err]
348
349test exec-9.8 {commands returning errors} {exec} {
350    set f [open $path(err) w]
351    puts $f {
352        puts stdout out
353        puts stderr err
354    }
355    close $f
356    list [catch {exec [interpreter] $path(err)} msg] $msg
357} {1 {out
358err}}
359
360# Errors in executing the Tcl command, as opposed to errors in the
361# processes that are invoked.
362
363test exec-10.1 {errors in exec invocation} {exec} {
364    list [catch {exec} msg] $msg
365} {1 {wrong # args: should be "exec ?switches? arg ?arg ...?"}}
366test exec-10.2 {errors in exec invocation} {exec} {
367    list [catch {exec | cat} msg] $msg
368} {1 {illegal use of | or |& in command}}
369test exec-10.3 {errors in exec invocation} {exec} {
370    list [catch {exec cat |} msg] $msg
371} {1 {illegal use of | or |& in command}}
372test exec-10.4 {errors in exec invocation} {exec} {
373    list [catch {exec cat | | cat} msg] $msg
374} {1 {illegal use of | or |& in command}}
375test exec-10.5 {errors in exec invocation} {exec} {
376    list [catch {exec cat | |& cat} msg] $msg
377} {1 {illegal use of | or |& in command}}
378test exec-10.6 {errors in exec invocation} {exec} {
379    list [catch {exec cat |&} msg] $msg
380} {1 {illegal use of | or |& in command}}
381test exec-10.7 {errors in exec invocation} {exec} {
382    list [catch {exec cat <} msg] $msg
383} {1 {can't specify "<" as last word in command}}
384test exec-10.8 {errors in exec invocation} {exec} {
385    list [catch {exec cat >} msg] $msg
386} {1 {can't specify ">" as last word in command}}
387test exec-10.9 {errors in exec invocation} {exec} {
388    list [catch {exec cat <<} msg] $msg
389} {1 {can't specify "<<" as last word in command}}
390test exec-10.10 {errors in exec invocation} {exec} {
391    list [catch {exec cat >>} msg] $msg
392} {1 {can't specify ">>" as last word in command}}
393test exec-10.11 {errors in exec invocation} {exec} {
394    list [catch {exec cat >&} msg] $msg
395} {1 {can't specify ">&" as last word in command}}
396test exec-10.12 {errors in exec invocation} {exec} {
397    list [catch {exec cat >>&} msg] $msg
398} {1 {can't specify ">>&" as last word in command}}
399test exec-10.13 {errors in exec invocation} {exec} {
400    list [catch {exec cat >@} msg] $msg
401} {1 {can't specify ">@" as last word in command}}
402test exec-10.14 {errors in exec invocation} {exec} {
403    list [catch {exec cat <@} msg] $msg
404} {1 {can't specify "<@" as last word in command}}
405test exec-10.15 {errors in exec invocation} {exec} {
406    list [catch {exec cat < a/b/c} msg] [string tolower $msg]
407} {1 {couldn't read file "a/b/c": no such file or directory}}
408test exec-10.16 {errors in exec invocation} {exec} {
409    list [catch {exec cat << foo > a/b/c} msg] [string tolower $msg]
410} {1 {couldn't write file "a/b/c": no such file or directory}}
411test exec-10.17 {errors in exec invocation} {exec} {
412    list [catch {exec cat << foo > a/b/c} msg] [string tolower $msg]
413} {1 {couldn't write file "a/b/c": no such file or directory}}
414set f [open $path(gorp.file) w]
415test exec-10.18 {errors in exec invocation} {exec} {
416    list [catch {exec cat <@ $f} msg] $msg
417} "1 {channel \"$f\" wasn't opened for reading}"
418close $f
419set f [open $path(gorp.file) r]
420test exec-10.19 {errors in exec invocation} {exec} {
421    list [catch {exec cat >@ $f} msg] $msg
422} "1 {channel \"$f\" wasn't opened for writing}"
423close $f
424test exec-10.20 {errors in exec invocation} {exec} {
425    list [catch {exec ~non_existent_user/foo/bar} msg] $msg
426} {1 {user "non_existent_user" doesn't exist}}
427test exec-10.21 {errors in exec invocation} {exec} {
428    list [catch {exec [interpreter] true | ~xyzzy_bad_user/x | false} msg] $msg
429} {1 {user "xyzzy_bad_user" doesn't exist}}
430test exec-10.22 {errors in exec invocation} \
431-constraints exec \
432-returnCodes 1 \
433-body {exec echo test > ~non_existent_user/foo/bar} \
434-result {user "non_existent_user" doesn't exist}
435# Commands in background.
436
437test exec-11.1 {commands in background} {exec} {
438    set x [lindex [time {exec [interpreter] $path(sleep) 2 &}] 0]
439    expr $x<1000000
440} 1
441test exec-11.2 {commands in background} {exec} {
442    list [catch {exec [interpreter] $path(echo) a &b} msg] $msg
443} {0 {a &b}}
444test exec-11.3 {commands in background} {exec} {
445    llength [exec [interpreter] $path(sleep) 1 &]
446} 1
447test exec-11.4 {commands in background} {exec stdio} {
448    llength [exec [interpreter] $path(sleep) 1 | [interpreter] $path(sleep) 1 | [interpreter] $path(sleep) 1 &]
449} 3
450test exec-11.5 {commands in background} {exec} {
451    set f [open $path(gorp.file) w]
452    puts $f [list catch [list exec [info nameofexecutable] $path(echo) foo &]]
453    close $f
454    string compare "foo" [exec [interpreter] $path(gorp.file)]
455} 0
456
457# Make sure that background commands are properly reaped when
458# they eventually die.
459
460if {[testConstraint exec]} {
461    exec [interpreter] $path(sleep) 3
462}
463test exec-12.1 {reaping background processes} \
464        {exec unix nonPortable} {
465    for {set i 0} {$i < 20} {incr i} {
466        exec echo foo > /dev/null &
467    }
468    exec sleep 1
469    catch {exec ps | fgrep "echo foo" | fgrep -v fgrep | wc} msg
470    lindex $msg 0
471} 0
472test exec-12.2 {reaping background processes} \
473        {exec unix nonPortable} {
474    exec sleep 2 | sleep 2 | sleep 2 &
475    catch {exec ps | fgrep -i "sleep" | fgrep -i -v fgrep | wc} msg
476    set x [lindex $msg 0]
477    exec sleep 3
478    catch {exec ps | fgrep -i "sleep" | fgrep -i -v fgrep | wc} msg
479    list $x [lindex $msg 0]
480} {3 0}
481test exec-12.3 {reaping background processes} \
482        {exec unix nonPortable} {
483    exec sleep 1000 &
484    exec sleep 1000 &
485    set x [exec ps | fgrep "sleep" | fgrep -v fgrep]
486    set pids {}
487    foreach i [split $x \n] {
488        lappend pids [lindex $i 0]
489    }
490    foreach i $pids {
491        catch {exec kill -STOP $i}
492    }
493    catch {exec ps | fgrep "sleep" | fgrep -v fgrep | wc} msg
494    set x [lindex $msg 0]
495
496    foreach i $pids {
497        catch {exec kill -KILL $i}
498    }
499    catch {exec ps | fgrep "sleep" | fgrep -v fgrep | wc} msg
500    list $x [lindex $msg 0]
501} {2 0}
502
503# Make sure "errorCode" is set correctly.
504
505test exec-13.1 {setting errorCode variable} {exec} {
506    list [catch {exec [interpreter] $path(cat) < a/b/c} msg] [string tolower $errorCode]
507} {1 {posix enoent {no such file or directory}}}
508test exec-13.2 {setting errorCode variable} {exec} {
509    list [catch {exec [interpreter] $path(cat) > a/b/c} msg] [string tolower $errorCode]
510} {1 {posix enoent {no such file or directory}}}
511test exec-13.3 {setting errorCode variable} {exec} {
512    set x [catch {exec _weird_cmd_} msg]
513    list $x [string tolower $msg] [lindex $errorCode 0] \
514            [string tolower [lrange $errorCode 2 end]]
515} {1 {couldn't execute "_weird_cmd_": no such file or directory} POSIX {{no such file or directory}}}
516
517test exec-13.4 {extended exit result codes} {
518    -constraints {win}
519    -setup {
520        set tmp [makeFile {exit 0x00000101} tmpfile.exec-13.4]
521    }
522    -body {
523        list [catch {exec [interpreter] $tmp} err]\
524            [lreplace $::errorCode 1 1 {}]
525    }
526    -cleanup {
527        removeFile $tmp
528    }
529    -result {1 {CHILDSTATUS {} 257}}
530}
531
532test exec-13.5 {extended exit result codes: max value} {
533    -constraints {win}
534    -setup {
535        set tmp [makeFile {exit 0x3fffffff} tmpfile.exec-13.5]
536    }
537    -body {
538        list [catch {exec [interpreter] $tmp} err]\
539            [lreplace $::errorCode 1 1 {}]
540    }
541    -cleanup {
542        removeFile $tmp
543    }
544    -result {1 {CHILDSTATUS {} 1073741823}}
545}
546
547test exec-13.6 {extended exit result codes: signalled} {   
548    -constraints {win}
549    -setup {
550        set tmp [makeFile {exit 0xC0000016} tmpfile.exec-13.6]
551    }
552    -body {
553        list [catch {exec [interpreter] $tmp} err]\
554            [lreplace $::errorCode 1 1 {}]
555    }
556    -cleanup {
557        removeFile $tmp
558    }
559    -result {1 {CHILDKILLED {} SIGABRT SIGABRT}}
560}
561
562# Switches before the first argument
563
564test exec-14.1 {-keepnewline switch} {exec} {
565    exec -keepnewline [interpreter] $path(echo) foo
566} "foo\n"
567test exec-14.2 {-keepnewline switch} {exec} {
568    list [catch {exec -keepnewline} msg] $msg
569} {1 {wrong # args: should be "exec ?switches? arg ?arg ...?"}}
570test exec-14.3 {unknown switch} {exec} {
571    list [catch {exec -gorp} msg] $msg
572} {1 {bad switch "-gorp": must be -ignorestderr, -keepnewline, or --}}
573test exec-14.4 {-- switch} {exec} {
574    list [catch {exec -- -gorp} msg] [string tolower $msg]
575} {1 {couldn't execute "-gorp": no such file or directory}}
576test exec-14.5 {-ignorestderr switch} {exec} {
577    # Alas, the use of -ignorestderr is buried here :-(
578    exec [interpreter] $path(sh2) -c [list $path(echo2) foo bar] 2>@1
579} "foo bar\nbar"
580
581# Redirecting standard error separately from standard output
582
583test exec-15.1 {standard error redirection} {exec} {
584    exec [interpreter] "$path(echo)" "First line" > "$path(gorp.file)"
585    list [exec [interpreter] "$path(sh)" -c "\"$path(echo)\" foo bar 1>&2" 2> "$path(gorp.file)"] \
586            [exec [interpreter] "$path(cat)" "$path(gorp.file)"]
587} {{} {foo bar}}
588test exec-15.2 {standard error redirection} {exec stdio} {
589    list [exec [interpreter] "$path(sh)" -c "\"$path(echo)\" foo bar 1>&2" \
590                | [interpreter] "$path(echo)" biz baz >$path(gorp.file) 2> "$path(gorp.file2)"] \
591            [exec [interpreter] "$path(cat)" "$path(gorp.file)"] \
592            [exec [interpreter] "$path(cat)" "$path(gorp.file2)"]
593} {{} {biz baz} {foo bar}}
594test exec-15.3 {standard error redirection} {exec stdio} {
595    list [exec [interpreter] "$path(sh)" -c "\"$path(echo)\" foo bar 1>&2" \
596                | [interpreter] "$path(echo)" biz baz 2>$path(gorp.file) > "$path(gorp.file2)"] \
597            [exec [interpreter] "$path(cat)" "$path(gorp.file)"] \
598            [exec [interpreter] "$path(cat)" "$path(gorp.file2)"]
599} {{} {foo bar} {biz baz}}
600test exec-15.4 {standard error redirection} {exec} {
601    set f [open "$path(gorp.file)" w]
602    puts $f "Line 1"
603    flush $f
604    exec [interpreter] "$path(sh)" -c "\"$path(echo)\" foo bar 1>&2" 2>@ $f
605    puts $f "Line 3"
606    close $f
607    exec [interpreter] "$path(cat)" "$path(gorp.file)"
608} {Line 1
609foo bar
610Line 3}
611test exec-15.5 {standard error redirection} {exec} {
612    exec [interpreter] "$path(echo)" "First line" > "$path(gorp.file)"
613    exec [interpreter] "$path(sh)" -c "\"$path(echo)\" foo bar 1>&2" 2>> "$path(gorp.file)"
614    exec [interpreter] "$path(cat)" "$path(gorp.file)"
615} {First line
616foo bar}
617test exec-15.6 {standard error redirection} {exec stdio} {
618    exec [interpreter] "$path(sh)" -c "\"$path(echo)\" foo bar 1>&2" > "$path(gorp.file2)" 2> "$path(gorp.file)" \
619            >& "$path(gorp.file)" 2> "$path(gorp.file2)" | [interpreter] "$path(echo)" biz baz
620    list [exec [interpreter] "$path(cat)" "$path(gorp.file)"] [exec [interpreter] "$path(cat)" "$path(gorp.file2)"]
621} {{biz baz} {foo bar}}
622test exec-15.7 {standard error redirection 2>@1} {exec stdio} {
623    # This redirects stderr output into normal result output from exec
624    exec [interpreter] "$path(sh)" -c "\"$path(echo)\" foo bar 1>&2" 2>@1
625} {foo bar}
626
627test exec-16.1 {flush output before exec} {exec} {
628    set f [open $path(gorp.file) w]
629    puts $f "First line"
630    exec [interpreter] $path(echo) "Second line" >@ $f
631    puts $f "Third line"
632    close $f
633    exec [interpreter] $path(cat) $path(gorp.file)
634} {First line
635Second line
636Third line}
637test exec-16.2 {flush output before exec} {exec} {
638    set f [open $path(gorp.file) w]
639    puts $f "First line"
640    exec [interpreter] << {puts stderr {Second line}} >&@ $f > $path(gorp.file2)
641    puts $f "Third line"
642    close $f
643    exec [interpreter] $path(cat) $path(gorp.file)
644} {First line
645Second line
646Third line}
647
648set path(script) [makeFile {} script]
649
650test exec-17.1 { inheriting standard I/O } {exec} {
651    set f [open $path(script) w]
652    puts -nonewline $f {close stdout
653        set f [}
654    puts $f [list open $path(gorp.file) w]]
655    puts $f [list catch \
656            [list exec [info nameofexecutable] $path(echo) foobar &]]
657    puts $f [list exec [info nameofexecutable] $path(sleep) 2]
658    puts $f {close $f}
659    close $f
660    catch {exec [interpreter] $path(script)} result
661    set f [open $path(gorp.file) r]
662    lappend result [read $f]
663    close $f
664    set result
665} {{foobar
666}}
667
668test exec-18.1 { exec cat deals with weird file names} {exec tempNotWin} {
669    # This is cross-platform, but the cat isn't predictably correct on
670    # Windows.
671    set f "foo\[\{blah"
672    set path(fooblah) [makeFile {} $f]
673    set fout [open $path(fooblah) w]
674    puts $fout "contents"
675    close $fout
676    set res [list [catch {exec cat $path(fooblah)} msg] $msg]
677    removeFile $f
678    set res
679} {0 contents}
680
681# Note that this test cannot be adapted to work on Windows; that platform has
682# no kernel support for an analog of O_APPEND.
683test exec-19.1 {exec >> uses O_APPEND} {
684    -constraints {exec unix}
685    -setup {
686        set tmpfile [makeFile {0} tmpfile.exec-19.1]
687    }
688    -body {
689        # Note that we have to allow for the current contents of the
690        # temporary file, which is why the result is 14 and not 12
691        exec /bin/sh -c \
692            {for a in 1 2 3; do sleep 1; echo $a; done} >>$tmpfile &
693        exec /bin/sh -c \
694            {for a in a b c; do sleep 1; echo $a; done} >>$tmpfile &
695        # The above two shell invokations take about 3 seconds to
696        # finish, so allow 5s (in case the machine is busy)
697        after 5000
698        # Check that no bytes have got lost through mixups with
699        # overlapping appends, which is only guaranteed to work when
700        # we set O_APPEND on the file descriptor in the [exec >>...]
701        file size $tmpfile
702    }
703    -cleanup {
704        removeFile $tmpfile
705    }
706    -result 14
707}
708
709# cleanup
710
711foreach file {script gorp.file gorp.file2 echo echo2 cat wc sh sh2 sleep exit err} {
712    removeFile $file
713}
714unset -nocomplain path
715
716::tcltest::cleanupTests
717return
Note: See TracBrowser for help on using the repository browser.