Reputation: 11
Using TCL, I am trying to use the "try" command in TCL as a background process and return the error codes. However, using the ampersand (&) always returns the error code as 0 indicating a successful run.
try {
exec cmd /c test.exe &
set returnvalue 0
} on ok {output} {
puts "Command successful"
} trap {CHILDSTATUS} {output options} {
set result [lindex [dict get $options -errorcode] end]
if {$result == 3} {
puts "Argument undefined"
} elseif {$result == 4} {
puts "Login Failed"
} elseif {$result == 1} {
puts "Process Cancelled by user"
}
}
How can I instruct the interpreter to execute test.exe in the background and yet return the appropriate error codes? My intention is to run test.exe and another program in parallel, and yet read the error codes from test.exe run and post-process based on the error codes.
Any expert advices?
Upvotes: 1
Views: 682
Reputation: 4813
To run processes in the background and get their exit code, you have to switch to using open "|cmd /c ... &"
and fileevents. Then catch the close
command (in blocking mode) for the end result:
# Helper proc to run commands in the background
proc bgexec {args} {
set fd [open "|$args &"]
fconfigure $fd -blocking 0
fileevent $fd readable [list bgevent $fd [join $args]]
}
# Helper proc to handle file events
proc bgevent {fd cmd} {
# Discard any output
read $fd
if {[eof $fd]} {
fconfigure $fd -blocking 1
try {
close $fd
} on ok {output} {
puts "$cmd: Command successful"
} trap {CHILDSTATUS} {output options} {
set result [lindex [dict get $options -errorcode] end]
if {$result == 3} {
puts "$cmd: Argument undefined"
} elseif {$result == 4} {
puts "$cmd: Login Failed"
} elseif {$result == 1} {
puts "$cmd: Process Cancelled by user"
}
}
}
}
bgexec cmd /c test.exe
bgexec cmd /c test.exe arg1
vwait forever
Upvotes: 2