diff options
author | Steve Bennett <steveb@workware.net.au> | 2022-12-16 11:40:01 +1000 |
---|---|---|
committer | Steve Bennett <steveb@workware.net.au> | 2023-02-13 10:44:09 +1000 |
commit | 97c305635eb1552ad373c7e0a835b6069fd79312 (patch) | |
tree | c817313465526ae3c20b12edcd40b37139d854cc | |
parent | 3d159dad2b93ab3033224edf2d29f7602a955e3e (diff) | |
download | jimtcl-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.c | 23 | ||||
-rw-r--r-- | jim-signal.c | 5 | ||||
-rw-r--r-- | jim.h | 1 | ||||
-rw-r--r-- | tests/event.test | 12 |
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 @@ -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 |