aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Bennett <steveb@workware.net.au>2013-07-22 10:29:42 +1000
committerSteve Bennett <steveb@workware.net.au>2013-07-22 10:46:20 +1000
commitc8df8ad4f5fed5a9c85498987e9b416e69fb3b44 (patch)
treeb68919687ad14c7496c009b42c3da28586ff4954
parent5ca6b7ff651246cec3a09a94fda36dc5872fa759 (diff)
downloadjimtcl-c8df8ad4f5fed5a9c85498987e9b416e69fb3b44.zip
jimtcl-c8df8ad4f5fed5a9c85498987e9b416e69fb3b44.tar.gz
jimtcl-c8df8ad4f5fed5a9c85498987e9b416e69fb3b44.tar.bz2
Ensure that signals can break vwait
The following should break when a handled signal is caught. catch -signal { vwait forever } Signed-off-by: Steve Bennett <steveb@workware.net.au>
-rw-r--r--jim-eventloop.c9
-rw-r--r--jim.c15
-rw-r--r--jim.h1
-rw-r--r--tests/event.test11
-rw-r--r--tests/exec.test1
5 files changed, 31 insertions, 6 deletions
diff --git a/jim-eventloop.c b/jim-eventloop.c
index ef62284..ac45eb5 100644
--- a/jim-eventloop.c
+++ b/jim-eventloop.c
@@ -567,16 +567,19 @@ static int JimELVwaitCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
Jim_Obj *currValue;
currValue = Jim_GetGlobalVariable(interp, argv[1], JIM_NONE);
/* Stop the loop if the vwait-ed variable changed value,
- * or if was unset and now is set (or the contrary). */
+ * or if was unset and now is set (or the contrary)
+ * or if a signal was caught
+ */
if ((oldValue && !currValue) ||
(!oldValue && currValue) ||
- (oldValue && currValue && !Jim_StringEqObj(oldValue, currValue)))
+ (oldValue && currValue && !Jim_StringEqObj(oldValue, currValue)) ||
+ Jim_CheckSignal(interp)) {
break;
+ }
}
if (oldValue)
Jim_DecrRefCount(interp, oldValue);
-
if (rc == -2) {
return JIM_ERR;
}
diff --git a/jim.c b/jim.c
index b2d5853..d8c71da 100644
--- a/jim.c
+++ b/jim.c
@@ -10516,8 +10516,8 @@ int Jim_EvalObj(Jim_Interp *interp, Jim_Obj *scriptObjPtr)
if (retcode == JIM_OK && argc) {
/* Invoke the command */
retcode = JimInvokeCommand(interp, argc, argv);
- if (interp->signal_level && interp->sigmask) {
- /* Check for a signal after each command */
+ /* Check for a signal after each command */
+ if (Jim_CheckSignal(interp)) {
retcode = JIM_SIGNAL;
}
}
@@ -13679,6 +13679,15 @@ static int Jim_ExitCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg
return JIM_EXIT;
}
+/**
+ * Returns 1 if a signal has been received while
+ * in a catch -signal {} clause.
+ */
+int Jim_CheckSignal(Jim_Interp *interp)
+{
+ return interp->signal_level && interp->sigmask;
+}
+
/* [catch] */
static int Jim_CatchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
@@ -13750,7 +13759,7 @@ static int Jim_CatchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar
}
interp->signal_level += sig;
- if (interp->signal_level && interp->sigmask) {
+ if (Jim_CheckSignal(interp)) {
/* If a signal is set, don't even try to execute the body */
exitCode = JIM_SIGNAL;
}
diff --git a/jim.h b/jim.h
index 84ca506..49e1909 100644
--- a/jim.h
+++ b/jim.h
@@ -907,6 +907,7 @@ JIM_EXPORT void Jim_HistoryShow(void);
/* Misc */
JIM_EXPORT int Jim_InitStaticExtensions(Jim_Interp *interp);
JIM_EXPORT int Jim_StringToWide(const char *str, jim_wide *widePtr, int base);
+JIM_EXPORT int Jim_CheckSignal(Jim_Interp *interp);
/* jim-load.c */
JIM_EXPORT int Jim_LoadLibrary(Jim_Interp *interp, const char *pathName);
diff --git a/tests/event.test b/tests/event.test
index e55d07b..b460227 100644
--- a/tests/event.test
+++ b/tests/event.test
@@ -14,6 +14,7 @@ source [file dirname [info script]]/testing.tcl
needs cmd after eventloop
testConstraint socket [expr {[info commands socket] ne ""}]
testConstraint exec [expr {[info commands exec] ne ""}]
+testConstraint signal [expr {[info commands signal] ne ""}]
test event-5.1 {Tcl_BackgroundError, HandleBgErrors procedures} jim {
catch {rename bgerror {}}
@@ -189,4 +190,14 @@ foreach i [after info] {
after cancel $i
}
+test event-13.1 "vwait/signal" signal {
+ signal handle ALRM
+ list [catch -signal {
+ alarm 0.1
+ # This is just to prevent the vwait from exiting immediately
+ stdin readable { puts "stdin is readable" }
+ vwait forever
+ } msg] $msg
+} {5 SIGALRM}
+
testreport
diff --git a/tests/exec.test b/tests/exec.test
index 5a027f4..82da421 100644
--- a/tests/exec.test
+++ b/tests/exec.test
@@ -16,6 +16,7 @@
source [file dirname [info script]]/testing.tcl
needs cmd exec
+needs cmd after eventloop
# Sleep which supports fractions of a second
if {[info commands sleep] eq {}} {