Changeset 141415 for trunk/base


Ignore:
Timestamp:
Oct 18, 2015, 12:07:16 AM (4 years ago)
Author:
cal@…
Message:

base: pextlib/system: Report signal termination

Add code to correctly report termination by signal back to the Tcl user. See
https://www.tcl.tk/man/tcl7.6/TclCmd/tclvars.n.html#M7 for a description of the
format in case of signaled subprocesses. See vendor/tcl8.5.15/generic/tclPipe.c
for C code that generates these messages. Use Tcl_SignalId and Tcl_SignalMsg to
generate the required data for the message to be returned to the user.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/base/src/pextlib1.0/system.c

    r141414 r141415  
    307307    status = TCL_ERROR;
    308308
    309     if (wait(&ret) == pid && WIFEXITED(ret) && !read_failed) {
     309    if (wait(&ret) == pid && (WIFEXITED(ret) || WIFSIGNALED(ret)) && !read_failed) {
    310310        /* Normal exit, and reading from the pipe didn't fail. */
    311         if (WEXITSTATUS(ret) == 0) {
     311        if (WIFEXITED(ret) && WEXITSTATUS(ret) == 0) {
    312312            status = TCL_OK;
    313313        } else {
     
    316316            /* print error */
    317317            ui_info(interp, "Command failed: %s", cmdstring);
    318             ui_info(interp, "Exit code: %d", WEXITSTATUS(ret));
    319 
    320             /* set errorCode [list CHILDSTATUS <pid> <code>] */
     318            if (WIFEXITED(ret)) {
     319                ui_info(interp, "Exit code: %d", WEXITSTATUS(ret));
     320            } else if(WIFSIGNALED(ret)) {
     321                ui_info(interp, "Killed by signal: %d", WTERMSIG(ret));
     322            }
     323
    321324            errorCode = Tcl_NewListObj(0, NULL);
    322             Tcl_ListObjAppendElement(interp, errorCode, Tcl_NewStringObj("CHILDSTATUS", -1));
    323             Tcl_ListObjAppendElement(interp, errorCode, Tcl_NewIntObj(pid));
    324             Tcl_ListObjAppendElement(interp, errorCode, Tcl_NewIntObj(WEXITSTATUS(ret)));
    325             Tcl_SetObjErrorCode(interp, errorCode);
     325            if (WIFEXITED(ret)) {
     326                /* set errorCode [list CHILDSTATUS <pid> <code>] */
     327                Tcl_ListObjAppendElement(interp, errorCode, Tcl_NewStringObj("CHILDSTATUS", -1));
     328                Tcl_ListObjAppendElement(interp, errorCode, Tcl_NewIntObj(pid));
     329                Tcl_ListObjAppendElement(interp, errorCode, Tcl_NewIntObj(WEXITSTATUS(ret)));
     330                Tcl_SetObjErrorCode(interp, errorCode);
     331            } else if (WIFSIGNALED(ret)) {
     332                /* set errorCode [list CHILDKILLED <pid> <SIGNAME> <signal descripton>] */
     333                Tcl_ListObjAppendElement(interp, errorCode, Tcl_NewStringObj("CHILDKILLED", -1));
     334                Tcl_ListObjAppendElement(interp, errorCode, Tcl_NewIntObj(pid));
     335                Tcl_ListObjAppendElement(interp, errorCode, Tcl_NewStringObj(Tcl_SignalId(WTERMSIG(ret)), -1));
     336                Tcl_ListObjAppendElement(interp, errorCode, Tcl_NewStringObj(Tcl_SignalMsg(WTERMSIG(ret)), -1));
     337                Tcl_SetObjErrorCode(interp, errorCode);
     338            }
    326339
    327340            Tcl_SetObjResult(interp, Tcl_NewStringObj("command execution failed", -1));
Note: See TracChangeset for help on using the changeset viewer.