aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Bennett <steveb@workware.net.au>2022-12-16 11:40:01 +1000
committerSteve Bennett <steveb@workware.net.au>2023-02-13 10:44:09 +1000
commit97c305635eb1552ad373c7e0a835b6069fd79312 (patch)
treec817313465526ae3c20b12edcd40b37139d854cc
parent3d159dad2b93ab3033224edf2d29f7602a955e3e (diff)
downloadjimtcl-97c305635eb1552ad373c7e0a835b6069fd79312.zip
jimtcl-97c305635eb1552ad373c7e0a835b6069fd79312.tar.gz
jimtcl-97c305635eb1552ad373c7e0a835b6069fd79312.tar.bz2
vwait: add support for vwait -signal
To break vwait if a handled signal is received. In this case, the handled signal(s) can be returned by signal check ?-clear? Signed-off-by: Steve Bennett <steveb@workware.net.au>
-rw-r--r--jim-eventloop.c23
-rw-r--r--jim-signal.c5
-rw-r--r--jim.h1
-rw-r--r--tests/event.test12
4 files changed, 32 insertions, 9 deletions
diff --git a/jim-eventloop.c b/jim-eventloop.c
index 64e3008..782d5dd 100644
--- a/jim-eventloop.c
+++ b/jim-eventloop.c
@@ -592,13 +592,18 @@ static int JimELVwaitCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
Jim_EventLoop *eventLoop = Jim_CmdPrivData(interp);
Jim_Obj *oldValue;
int rc;
+ int signal = 0;
- if (argc != 2) {
- Jim_WrongNumArgs(interp, 1, argv, "name");
+ if (argc == 3 && Jim_CompareStringImmediate(interp, argv[1], "-signal")) {
+ signal++;
+ }
+
+ if (argc - signal != 2) {
+ Jim_WrongNumArgs(interp, 1, argv, "?-signal? name");
return JIM_ERR;
}
- oldValue = Jim_GetGlobalVariable(interp, argv[1], JIM_NONE);
+ oldValue = Jim_GetGlobalVariable(interp, argv[1 + signal], JIM_NONE);
if (oldValue) {
Jim_IncrRefCount(oldValue);
}
@@ -612,6 +617,18 @@ static int JimELVwaitCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
eventLoop->suppress_bgerror = 0;
while ((rc = Jim_ProcessEvents(interp, JIM_ALL_EVENTS)) >= 0) {
+ if (signal && interp->sigmask) {
+ /* vwait -signal and handled signals were received, so transfer them
+ * to ignored signals so that 'signal check -clear' will return them.
+ * It's possible that if signals aren't supported we shouldn't even
+ * allow the -signal option.
+ */
+#ifdef jim_ext_signal
+ Jim_SignalSetIgnored(interp->sigmask);
+#endif
+ interp->sigmask = 0;
+ break;
+ }
Jim_Obj *currValue;
currValue = Jim_GetGlobalVariable(interp, argv[1], JIM_NONE);
/* Stop the loop if the vwait-ed variable changed value,
diff --git a/jim-signal.c b/jim-signal.c
index b65cf7e..e25a276 100644
--- a/jim-signal.c
+++ b/jim-signal.c
@@ -46,6 +46,11 @@ static void signal_ignorer(int sig)
sigsignored |= sig_to_bit(sig);
}
+void Jim_SignalSetIgnored(jim_wide mask)
+{
+ sigsignored |= mask;
+}
+
static void signal_init_names(void)
{
#define SET_SIG_NAME(SIG) siginfo[SIG].name = #SIG
diff --git a/jim.h b/jim.h
index 763c456..2f8ca99 100644
--- a/jim.h
+++ b/jim.h
@@ -957,6 +957,7 @@ JIM_EXPORT int Jim_IsBigEndian(void);
* in a catch -signal {} clause.
*/
#define Jim_CheckSignal(i) ((i)->signal_level && (i)->sigmask)
+JIM_EXPORT void Jim_SignalSetIgnored(jim_wide mask);
/* 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 cfadde8..278f4e3 100644
--- a/tests/event.test
+++ b/tests/event.test
@@ -104,12 +104,12 @@ test event-10.1 {Tcl_Exit procedure} exec {
[lindex $errorCode 2]
} {1 CHILDSTATUS 3}
-test event-11.1 {Tcl_VwaitCmd procedure} {
- list [catch {vwait} msg] $msg
-} {1 {wrong # args: should be "vwait name"}}
-test event-11.2 {Tcl_VwaitCmd procedure} {
- list [catch {vwait a b} msg] $msg
-} {1 {wrong # args: should be "vwait name"}}
+test event-11.1 {Tcl_VwaitCmd procedure} -body {
+ vwait
+} -returnCodes error -match glob -result {wrong # args: should be "vwait* name"}
+test event-11.2 {Tcl_VwaitCmd procedure} -body {
+ vwait a b
+} -returnCodes error -match glob -result {wrong # args: should be "vwait* name"}
test event-11.3 {Tcl_VwaitCmd procedure} jim {
catch {unset x}
set x 1