Index: .fossil-settings/ignore-glob ================================================================== --- .fossil-settings/ignore-glob +++ .fossil-settings/ignore-glob @@ -1,5 +1,6 @@ tuapi.so libtuapi.a tuapi.o tuapi.tcl.h pkgIndex.tcl +compile_commands.json Index: build-dyn.sh ================================================================== --- build-dyn.sh +++ build-dyn.sh @@ -1,6 +1,19 @@ -# /bin/bash +#! /usr/bin/env bash + +bashArrayToJSON() ( + args=("$@") + + jq -M -r -n -c --args '$ARGS.positional' --args -- "${args[@]}" +) + +bashStringToJSON() ( + string="$1" + + eval "tmpArray=($string)" + bashArrayToJSON "${tmpArray[@]}" +) # Perform common build options . ./build-common.sh # Compile using the same options as Tcl @@ -9,8 +22,34 @@ fi . "${TCLCONFIGSH}" echo "${TCL_CC} -ggdb3 -fPIC -DPIC -Wall -DUSE_TCL_STUBS=1 ${TCL_DEFS} ${TCL_INCLUDE_SPEC} -shared -rdynamic -o tuapi.so tuapi.c ${TCL_STUB_LIB_SPEC}" -eval ${TCL_CC} -ggdb3 -fPIC -DPIC -Wall -DUSE_TCL_STUBS=1 ${TCL_DEFS} ${TCL_INCLUDE_SPEC} -shared -rdynamic -o tuapi.so tuapi.c ${TCL_STUB_LIB_SPEC} + +cat << _EOF_ > compile_commands.json.new +[ + { + "directory": "$(pwd)", + "file": "tuapi.c", + "arguments": [ + "$(echo "${TCL_CC}" | sed 's@ @", "@g')", + "-ggdb3", + "-fPIC", + "-DPIC", + "-Wall", + "-DUSE_TCL_STUBS=1", + $(bashStringToJSON "${TCL_DEFS}" | sed 's@^\[@@;s@\]$@@'), + $(bashStringToJSON "${TCL_INCLUDE_SPEC}" | sed 's@^\[@@;s@\]$@@'), + "-shared", + "-rdynamic", + "-o", + "tuapi.so", + "tuapi.c" + ] + } +] +_EOF_ + +eval ${TCL_CC} -ggdb3 -fPIC -DPIC -Wall -DUSE_TCL_STUBS=1 ${TCL_DEFS} ${TCL_INCLUDE_SPEC} -shared -rdynamic -o tuapi.so tuapi.c ${TCL_STUB_LIB_SPEC} || exit 1 +mv compile_commands.json.new compile_commands.json echo 'package ifneeded tuapi '"${tuapi_version}"' [list load [file join $dir tuapi.so]]' > pkgIndex.tcl Index: tuapi.c ================================================================== --- tuapi.c +++ tuapi.c @@ -3072,10 +3072,11 @@ FD_ZERO(&read_fdset); FD_SET(fd, &read_fdset); select_ret = select(fd + 1, &read_fdset, NULL, NULL, &select_timeout); + if (select_ret == 0) { /* On timeout, terminate starting process */ child_pgid = getpgid(child); if (child_pgid != -1) { kill(-child_pgid, SIGKILL); @@ -3090,15 +3091,19 @@ snprintf(logmsg, sizeof(logmsg), "Method \"start\" timed out after %i seconds ]\n", (int) timeout_val); write(log_fd, logmsg, strlen(logmsg)); close(log_fd); + waitpid(child, NULL, WNOHANG); + return(TCL_ERROR); } if (select_ret > 0) { read_ret = read(fd, &child_pgid, sizeof(child_pgid)); + } else { + read_ret = -1; } /* 4.parent.d. Close read end of pipe */ close(fd); @@ -3113,10 +3118,12 @@ snprintf(logmsg, sizeof(logmsg), "Method \"start\" failed: communication with started service broken ]\n"); write(log_fd, logmsg, strlen(logmsg)); close(log_fd); + waitpid(child, NULL, WNOHANG); + return(TCL_ERROR); } /* 4.parent.f. If the PGID given is actually an error, return error */ if (child_pgid == -1) { @@ -3129,10 +3136,12 @@ snprintf(logmsg, sizeof(logmsg), "Method \"start\" failed ]\n"); write(log_fd, logmsg, strlen(logmsg)); close(log_fd); + waitpid(child, NULL, WNOHANG); + return(TCL_ERROR); } /* 4.parent.g. Return PGID to Tcl */ Tcl_SetObjResult(interp, Tcl_NewWideIntObj((Tcl_WideInt) child_pgid)); @@ -3143,10 +3152,12 @@ snprintf(logmsg, sizeof(logmsg), "Method \"start\" completed, process group = %lu ]\n", (unsigned long) child_pgid); write(log_fd, logmsg, strlen(logmsg)); close(log_fd); + + waitpid(child, NULL, 0); return(TCL_OK); } /* 4.child.a. Close read end of pipe -- we only write to it */ @@ -3276,11 +3287,11 @@ int Tuapi_Init(Tcl_Interp *interp) { #ifdef USE_TCL_STUBS const char *tclInitStubs_ret; /* Initialize Stubs */ - tclInitStubs_ret = Tcl_InitStubs(interp, "8.4", 0); + tclInitStubs_ret = Tcl_InitStubs(interp, TCL_PATCH_LEVEL, 0); if (!tclInitStubs_ret) { return(TCL_ERROR); } #endif