aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Savoye <rob@welcomehome.org>2015-07-30 13:25:20 -0600
committerRob Savoye <rob@welcomehome.org>2015-07-30 13:25:20 -0600
commit31aa24d3683d7150cae7b7c61b4d21af06eabd44 (patch)
tree6fd53f42cc60aa9d67be83b293554ac87d54bc2f
parentc465c486c4f1a9602aba153307f544a352159233 (diff)
parente7d7a3e0b0cda9194c192e979f4ecc8dcfb010b3 (diff)
Merge branch 'master' into linaro
Conflicts: ChangeLog
-rw-r--r--ChangeLog10
-rw-r--r--lib/remote.exp86
2 files changed, 70 insertions, 26 deletions
diff --git a/ChangeLog b/ChangeLog
index 9145142..62b5eff 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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."
}