diff options
author | Rob Savoye <rob@welcomehome.org> | 2015-07-30 13:25:20 -0600 |
---|---|---|
committer | Rob Savoye <rob@welcomehome.org> | 2015-07-30 13:25:20 -0600 |
commit | 31aa24d3683d7150cae7b7c61b4d21af06eabd44 (patch) | |
tree | 6fd53f42cc60aa9d67be83b293554ac87d54bc2f | |
parent | c465c486c4f1a9602aba153307f544a352159233 (diff) | |
parent | e7d7a3e0b0cda9194c192e979f4ecc8dcfb010b3 (diff) |
Merge branch 'master' into linaro
Conflicts:
ChangeLog
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | lib/remote.exp | 86 |
2 files changed, 70 insertions, 26 deletions
@@ -1,6 +1,7 @@ -2015-04-17 Rob Savoye <rob.savoye@linaro.org> +2015-07-30 Pedro Alves <palves@redhat.com> - * lib/libgloss.exp (find_g++): Look for xg++ before g++. + * lib/remote.exp (close_wait_program): New procedure. + (local_exec, standard_close): Use it. 2015-05-23 Ben Elliston <bje@gnu.org> @@ -45,7 +46,10 @@ 2015-05-12 Steve Ellcey <sellcey@imgtec.com> * baseboards/generic-sim.exp: Check $DEJAGNU_SIM_OPTION. ->>>>>>> master + +2015-04-17 Rob Savoye <rob.savoye@linaro.org> + + * lib/libgloss.exp (find_g++): Look for xg++ before g++. 2015-03-30 Ben Elliston <bje@gnu.org> diff --git a/lib/remote.exp b/lib/remote.exp index 4dea1b9..c334416 100644 --- a/lib/remote.exp +++ b/lib/remote.exp @@ -58,6 +58,61 @@ proc remote_raw_open { args } { return [eval call_remote raw open $args] } +# Close a spawn ID, and wait for the process to die. If PID is not +# -1, then if the process doesn't exit gracefully promptly, we kill +# it. +# +proc close_wait_program { program_id pid {wres_varname ""} } { + if {$wres_varname != "" } { + upvar 1 $wres_varname wres + } + + set exec_pid -1 + + if { $pid > 0 } { + # Tcl has no kill primitive, so we have to execute an external + # command in order to kill the process. + verbose "doing kill, pid is $pid" + # Prepend "-" to generate the "process group ID" needed by + # kill. + set pgid "-$pid" + # Send SIGINT to give the program a better chance to interrupt + # whatever it might be doing and react to stdin closing. + # E.g., in case of GDB, this should get it back to the prompt. + exec sh -c "exec > /dev/null 2>&1 && (kill -2 $pgid || kill -2 $pid)" + + # If the program doesn't exit gracefully when stdin closes, + # we'll need to kill it. But only do this after 'wait'ing a + # bit, to avoid killing the wrong process in case of a + # PID-reuse race. The extra sleep at the end is there to give + # time to kill $exec_pid without having _that_ be subject to a + # PID reuse race. + set secs 5 + set sh_cmd "exec > /dev/null 2>&1" + append sh_cmd " && sleep $secs && (kill -15 $pgid || kill -15 $pid)" + append sh_cmd " && sleep $secs && (kill -9 $pgid || kill -9 $pid)" + append sh_cmd " && sleep $secs" + set exec_pid [exec sh -c "$sh_cmd" &] + } + verbose "pid is $pid" + + # This closes the program's stdin. This should cause well behaved + # interactive programs to exit. This will hang if the kill + # doesn't work. Nothin' to do, and it's not OK. + catch "close -i $program_id" + + # Reap it. + set res [catch "wait -i $program_id" wres] + if {$exec_pid != -1} { + # We reaped the process, so cancel the pending force-kills, as + # otherwise if the PID is reused for some other unrelated + # process, we'd kill the wrong process. + exec sh -c "exec > /dev/null 2>&1 && kill -9 $exec_pid" + } + + return $res +} + # Run the specified COMMANDLINE on the local machine, redirecting input # to file INP (if non-empty), redirecting output to file OUTP (if non-empty), # and waiting TIMEOUT seconds for the command to complete before killing @@ -176,18 +231,10 @@ proc local_exec { commandline inp outp timeout } { # Uuuuuuugh. Now I'm getting really sick. # If we didn't get an EOF, we have to kill the poor defenseless program. - # However, Tcl has no kill primitive, so we have to execute an external - # command in order to execute the execution. (English. Gotta love it.) - if { ! $got_eof } { - verbose "killing $pid $pgid" - # This is very, very nasty. SH, instead of EXPECT, is used to - # run this in the background since, on older CYGWINs, a - # strange file I/O error occures. - exec sh -c "exec > /dev/null 2>&1 && (kill -2 $pgid || kill -2 $pid) && sleep 5 && (kill -15 $pgid || kill $pid) && sleep 5 && (kill -9 $pgid || kill -9 $pid) &" - } - # This will hang if the kill doesn't work. Nothin' to do, and it's not ok. - catch "close -i $spawn_id" - set r2 [catch "wait -i $spawn_id" wres] + if { $got_eof } { + set pid -1 + } + set r2 [close_wait_program $spawn_id $pid wres] if { $id > 0 } { set r2 [catch "close $id" res] } else { @@ -314,20 +361,13 @@ proc standard_close { host } { } } } - if { $pid > 0 } { - verbose "doing kill, pid is $pid" - # This is very, very nasty. SH, instead of EXPECT, is used - # to run this in the background since, on older CYGWINs, a - # strange file I/O error occures. - set pgid "-[join $pid { -}]" - exec sh -c "exec > /dev/null 2>&1 && (kill -2 $pgid || kill -2 $pid) && sleep 5 && (kill $pgid || kill $pid) && sleep 5 && (kill -9 $pgid || kill -9 $pid) &" - } - verbose "pid is $pid" - catch "close -i $shell_id" + + close_wait_program $shell_id $pid + if {[info exists oid]} { catch "close $oid" } - catch "wait -i $shell_id" + unset board_info(${host},fileid) verbose "Shell closed." } |