[147226] trunk/base/src/pextlib1.0/system.c
raimue at macports.org
raimue at macports.org
Thu Mar 31 09:59:52 PDT 2016
Revision: 147226
https://trac.macports.org/changeset/147226
Author: raimue at 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));
}
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/macports-changes/attachments/20160331/a700c094/attachment.html>
More information about the macports-changes
mailing list