[147226] trunk/base/src/pextlib1.0/system.c
Revision: 147226 https://trac.macports.org/changeset/147226 Author: raimue@macports.org Date: 2016-03-31 09:59:52 -0700 (Thu, 31 Mar 2016) Log Message: ----------- pextlib/system: custom handler for SIGINT/SIGQUIT Record the fact that a signal was delivered and throw the appropriate error code, This will still block until the child process terminates itself. Modified Paths: -------------- trunk/base/src/pextlib1.0/system.c Modified: trunk/base/src/pextlib1.0/system.c =================================================================== --- trunk/base/src/pextlib1.0/system.c 2016-03-31 16:34:44 UTC (rev 147225) +++ trunk/base/src/pextlib1.0/system.c 2016-03-31 16:59:52 UTC (rev 147226) @@ -109,6 +109,11 @@ return 1; } +static volatile int interrupted_by = 0; +static void handle_sigint(int s) { + interrupted_by = s; +} + /* usage: system ?-notty? ?-nodup? ?-nice value? ?-W path? command */ int SystemCmd(ClientData clientData UNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { @@ -189,7 +194,7 @@ } /* - * Ignore SIGINT and SIGQUIT, just like system(3) + * Custom handlers for SIGINT and SIGQUIT to detect aborts * * system(3) also blocks SIGCHLD during the execution of the program. * However, that would make our wait(2) call more complicated. As we are @@ -198,8 +203,10 @@ */ struct sigaction sa, old_sa_int, old_sa_quit; memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_IGN; + sa.sa_handler = handle_sigint; sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESTART; + interrupted_by = 0; sigaction(SIGINT, &sa, &old_sa_int); sigaction(SIGQUIT, &sa, &old_sa_quit); @@ -344,12 +351,21 @@ } errorCode = Tcl_NewListObj(0, NULL); - if (WIFEXITED(ret)) { + if (interrupted_by != 0) { + /* set errorCode [list POSIX SIG <SIGNAME> <signal descripton>] */ + Tcl_ListObjAppendElement(interp, errorCode, Tcl_NewStringObj("POSIX", -1)); + Tcl_ListObjAppendElement(interp, errorCode, Tcl_NewStringObj("SIG", -1)); + Tcl_ListObjAppendElement(interp, errorCode, Tcl_NewStringObj(Tcl_SignalId(interrupted_by), -1)); + Tcl_ListObjAppendElement(interp, errorCode, Tcl_NewStringObj(Tcl_SignalMsg(interrupted_by), -1)); + Tcl_SetObjErrorCode(interp, errorCode); + Tcl_SetObjResult(interp, Tcl_NewStringObj("interrupted by signal", -1)); + } else if (WIFEXITED(ret)) { /* set errorCode [list CHILDSTATUS <pid> <code>] */ Tcl_ListObjAppendElement(interp, errorCode, Tcl_NewStringObj("CHILDSTATUS", -1)); Tcl_ListObjAppendElement(interp, errorCode, Tcl_NewIntObj(pid)); Tcl_ListObjAppendElement(interp, errorCode, Tcl_NewIntObj(WEXITSTATUS(ret))); Tcl_SetObjErrorCode(interp, errorCode); + Tcl_SetObjResult(interp, Tcl_NewStringObj("command execution failed", -1)); } else if (WIFSIGNALED(ret)) { /* set errorCode [list CHILDKILLED <pid> <SIGNAME> <signal descripton>] */ Tcl_ListObjAppendElement(interp, errorCode, Tcl_NewStringObj("CHILDKILLED", -1)); @@ -357,9 +373,8 @@ Tcl_ListObjAppendElement(interp, errorCode, Tcl_NewStringObj(Tcl_SignalId(WTERMSIG(ret)), -1)); Tcl_ListObjAppendElement(interp, errorCode, Tcl_NewStringObj(Tcl_SignalMsg(WTERMSIG(ret)), -1)); Tcl_SetObjErrorCode(interp, errorCode); + Tcl_SetObjResult(interp, Tcl_NewStringObj("command execution failed", -1)); } - - Tcl_SetObjResult(interp, Tcl_NewStringObj("command execution failed", -1)); } }
participants (1)
-
raimue@macports.org