diff options
author | Baruch Sterin <baruchs@gmail.com> | 2011-02-27 18:33:56 -0800 |
---|---|---|
committer | Baruch Sterin <baruchs@gmail.com> | 2011-02-27 18:33:56 -0800 |
commit | 34d59b0b91f09b35b7c3b4e74411f11b8b3994cc (patch) | |
tree | a721b34849df3243b145ba62b504ed41ab618dbc /src/misc | |
parent | 02081dba6779fbd247d1e62d5dc6db2097acc8e7 (diff) | |
download | abc-34d59b0b91f09b35b7c3b4e74411f11b8b3994cc.tar.gz abc-34d59b0b91f09b35b7c3b4e74411f11b8b3994cc.tar.bz2 abc-34d59b0b91f09b35b7c3b4e74411f11b8b3994cc.zip |
fixes to pyabc kill mechanism
Diffstat (limited to 'src/misc')
-rw-r--r-- | src/misc/util/utilSignal.c | 474 | ||||
-rw-r--r-- | src/misc/util/utilSignal.h | 9 |
2 files changed, 15 insertions, 468 deletions
diff --git a/src/misc/util/utilSignal.c b/src/misc/util/utilSignal.c index 3549dbec..eeff504a 100644 --- a/src/misc/util/utilSignal.c +++ b/src/misc/util/utilSignal.c @@ -4,9 +4,9 @@ SystemName [ABC: Logic synthesis and verification system.] - PackageName [Signal handling utilities.] + PackageName [] - Synopsis [Signal handling utilities.] + Synopsis [] Author [Baruch Sterin] @@ -18,19 +18,15 @@ ***********************************************************************/ -#include <main.h> #include <stdlib.h> -#include <signal.h> #include "abc_global.h" -#include "hashGen.h" #include "utilSignal.h" -#ifndef _MSC_VER - +#ifdef _MSC_VER +#define remove _remove +#else #include <unistd.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/wait.h> +#endif ABC_NAMESPACE_IMPL_START @@ -38,478 +34,36 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -static Hash_Gen_t* watched_pid_hash = NULL; -static Hash_Gen_t* watched_tmp_files_hash = NULL; - -static sigset_t old_procmask; - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -/**Function************************************************************* - - Synopsis [] - - Description [Kills all watched child processes and remove all watched termporary files.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -void Util_SignalCleanup() -{ - int i; - Hash_Gen_Entry_t* pEntry; - - // kill all watched child processes - Hash_GenForEachEntry(watched_pid_hash, pEntry, i) - { - pid_t pid = (pid_t)(ABC_PTRINT_T)pEntry->key; - pid_t ppid = (pid_t)(ABC_PTRINT_T)pEntry->data; - - if (getpid() == ppid) - { - kill(pid, SIGINT); - } - } - - // remove watched temporary files - Hash_GenForEachEntry(watched_tmp_files_hash, pEntry, i) - { - const char* fname = (const char*)pEntry->key; - pid_t ppid = (pid_t)(ABC_PTRINT_T)pEntry->data; - - if( getpid() == ppid ) - { - remove(fname); - } - } -} - -/**Function************************************************************* - - Synopsis [] - - Description [Sets up data structures needed for cleanup in signal handler.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -void Util_SignalStartHandler() -{ - watched_pid_hash = Hash_GenAlloc(100, Hash_DefaultHashFuncInt, Hash_DefaultCmpFuncInt, 0); - watched_tmp_files_hash = Hash_GenAlloc(100, Hash_DefaultHashFuncStr, (Hash_GenCompFunction_t)strcmp, 1); -} - -/**Function************************************************************* - - Synopsis [] - - Description [Frees data structures used for clean up in signal handler.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -void Util_SignalResetHandler() -{ - sigset_t procmask, old_procmask; - - sigemptyset(&procmask); - sigaddset(&procmask, SIGINT); - - sigprocmask(SIG_BLOCK, &procmask, &old_procmask); - - Hash_GenFree(watched_pid_hash); - watched_pid_hash = Hash_GenAlloc(100, Hash_DefaultHashFuncInt, Hash_DefaultCmpFuncInt, 0); - - Hash_GenFree(watched_tmp_files_hash); - watched_tmp_files_hash = Hash_GenAlloc(100, Hash_DefaultHashFuncStr, (Hash_GenCompFunction_t)strcmp, 1); - - sigprocmask(SIG_SETMASK, &old_procmask, NULL); -} - -void Util_SignalStopHandler() -{ - Hash_GenFree(watched_pid_hash); - watched_pid_hash = NULL; - - Hash_GenFree(watched_tmp_files_hash); - watched_tmp_files_hash = NULL; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [Blocks SIGINT. For use when updating watched processes and temporary files to prevent race conditions with the signal handler.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -static int nblocks = 0; - -void Util_SignalBlockSignals() -{ - sigset_t procmask; - - assert(nblocks==0); - nblocks ++ ; - - sigemptyset(&procmask); - sigaddset(&procmask, SIGINT); - - sigprocmask(SIG_BLOCK, &procmask, &old_procmask); -} - -/**Function************************************************************* - - Synopsis [] - - Description [Unblocks SIGINT after a call to Util_SignalBlockSignals.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -void Util_SignalUnblockSignals() -{ - assert( nblocks==1); - nblocks--; - - sigprocmask(SIG_SETMASK, &old_procmask, NULL); -} - - -static void watch_tmp_file(const char* fname) -{ - if( watched_tmp_files_hash != NULL ) - { - Hash_GenWriteEntry(watched_tmp_files_hash, Extra_UtilStrsav(fname), (void*)getpid() ); - } -} - -static void unwatch_tmp_file(const char* fname) -{ - if ( watched_tmp_files_hash ) - { - assert( Hash_GenExists(watched_tmp_files_hash, (void*)fname) ); - Hash_GenRemove(watched_tmp_files_hash, (void*)fname); - assert( !Hash_GenExists(watched_tmp_files_hash, (void*)fname) ); - } -} - -/**Function************************************************************* - - Synopsis [] - - Description [Adds a process id to the list of processes that should be killed in a signal handler.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -void Util_SignalAddChildPid(int pid) -{ - if ( watched_pid_hash ) - { - Hash_GenWriteEntry(watched_pid_hash, (void*)pid, (void*)getpid()); - } -} - -/**Function************************************************************* - - Synopsis [] - - Description [Removes a process id from the list of processes that should be killed in a signal handler.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -void Util_SignalRemoveChildPid(int pid) -{ - if ( watched_pid_hash ) - { - Hash_GenRemove(watched_pid_hash, (void*)pid); - } -} - -// a dummy signal hanlder to make sure that SIGCHLD and SIGINT will cause sigsuspend() to return -static void null_sig_handler(int signum) -{ -} - - -// enusre that sigsuspend() returns when signal signum occurs -- sigsuspend() does not return if a signal is ignored -static void replace_sighandler(int signum, struct sigaction* old_sa, int replace_dfl) -{ - sigaction(signum, NULL, old_sa); - - if( old_sa->sa_handler == SIG_IGN || old_sa->sa_handler==SIG_DFL && replace_dfl) - { - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - - sa.sa_handler = null_sig_handler; - - sigaction(signum, &sa, old_sa); - } -} - -// -static int do_waitpid(pid_t pid, sigset_t* old_procmask) -{ - int status; - - struct sigaction sigint_sa; - struct sigaction sigchld_sa; - sigset_t waitmask; - - // ensure SIGINT and SIGCHLD are not blocked during sigsuspend() - memcpy(&waitmask, old_procmask, sizeof(sigset_t)); - - sigdelset(&waitmask, SIGINT); - sigdelset(&waitmask, SIGCHLD); - - // ensure sigsuspend() returns if SIGINT or SIGCHLD occur, and save the current settings for SIGCHLD and SIGINT - - replace_sighandler(SIGINT, &sigint_sa, 0); - replace_sighandler(SIGCHLD, &sigchld_sa, 1); - - for(;;) - { - int rc; - - // wait for a signal -- returns if SIGINT or SIGCHLD (or any other signal that is unblocked and not ignored) occur - sigsuspend(&waitmask); - - // check if pid has terminated - rc = waitpid(pid, &status, WNOHANG); - - // stop if terminated or some other error occurs - if( rc > 0 || rc == -1 && errno!=EINTR ) - { - break; - } - } - - // process is dead, should no longer be watched - Util_SignalRemoveChildPid(pid); - - // restore original behavior of SIGINT and SIGCHLD - sigaction(SIGINT, &sigint_sa, NULL); - sigaction(SIGCHLD, &sigchld_sa, NULL); - - return status; -} - -static int do_system(const char* cmd, sigset_t* old_procmask) -{ - int pid; - - pid = fork(); - - if (pid == -1) - { - // fork failed - return -1; - } - else if( pid == 0) - { - // child process - sigprocmask(SIG_SETMASK, old_procmask, NULL); - execl("/bin/sh", "sh", "-c", cmd, NULL); - _exit(127); - } - - Util_SignalAddChildPid(pid); - - return do_waitpid(pid, old_procmask); -} - -/**Function************************************************************* - - Synopsis [] - - Description [Replaces system() with a function that allows SIGINT to interrupt.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -int Util_SignalSystem(const char* cmd) -{ - int status; - - sigset_t procmask; - sigset_t old_procmask; - - // if signal handler is not installed, run the original system() - if ( ! watched_pid_hash && ! watched_tmp_files_hash ) - return system(cmd); - - // block SIGINT and SIGCHLD - sigemptyset(&procmask); - - sigaddset(&procmask, SIGINT); - sigaddset(&procmask, SIGCHLD); - - sigprocmask(SIG_BLOCK, &procmask, &old_procmask); - - // call the actual function - status = do_system(cmd, &old_procmask); - - // restore signal block mask - sigprocmask(SIG_SETMASK, &old_procmask, NULL); - return status; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - -#else /* #ifndef _MSC_VER */ - -#include "abc_global.h" - -ABC_NAMESPACE_IMPL_START - -void Util_SignalCleanup() -{ -} - -void Util_SignalStartHandler() -{ -} - -void Util_SignalResetHandler() -{ -} - -void Util_SignalStopHandler() -{ -} - -void Util_SignalBlockSignals() -{ -} - -void Util_SignalUnblockSignals() -{ -} - -void watch_tmp_file(const char* fname) -{ -} - -void unwatch_tmp_file(const char* fname) -{ -} - -void Util_SignalAddChildPid(int pid) -{ -} - -void Util_SignalRemoveChildPid(int pid) -{ -} +#ifndef ABC_PYTHON_EMBED int Util_SignalSystem(const char* cmd) { return system(cmd); } -#endif /* #ifdef _MSC_VER */ - int tmpFile(const char* prefix, const char* suffix, char** out_name); -/**Function************************************************************* - - Synopsis [] - - Description [Create a temporary file and add it to the list of files to be cleaned up in the signal handler.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - int Util_SignalTmpFile(const char* prefix, const char* suffix, char** out_name) { - int fd; - - Util_SignalBlockSignals(); - - fd = tmpFile(prefix, suffix, out_name); - - if ( fd != -1 ) - { - watch_tmp_file( *out_name ); - } - - Util_SignalUnblockSignals(); - - return fd; + return tmpFile(prefix, suffix, out_name); } -/**Function************************************************************* - - Synopsis [] - - Description [Remove a temporary file (and remove it from the watched files list.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - void Util_SignalTmpFileRemove(const char* fname, int fLeave) { - Util_SignalBlockSignals(); - - unwatch_tmp_file(fname); - if (! fLeave) { remove(fname); } - - Util_SignalUnblockSignals(); } +#endif /* ABC_PYTHON_EMBED */ + ABC_NAMESPACE_IMPL_END + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// diff --git a/src/misc/util/utilSignal.h b/src/misc/util/utilSignal.h index 30c0ba1d..0ac87290 100644 --- a/src/misc/util/utilSignal.h +++ b/src/misc/util/utilSignal.h @@ -44,14 +44,7 @@ ABC_NAMESPACE_HEADER_START //////////////////////////////////////////////////////////////////////// /*=== utilSignal.c ==========================================================*/ -extern void Util_SignalCleanup(); -extern void Util_SignalStartHandler(); -extern void Util_SignalResetHandler(); -extern void Util_SignalStopHandler(); -extern void Util_SignalBlockSignals(); -extern void Util_SignalUnblockSignals(); -extern void Util_SignalAddChildPid(int pid); -extern void Util_SignalRemoveChildPid(int pid); + extern int Util_SignalTmpFile(const char* prefix, const char* suffix, char** out_name); extern void Util_SignalTmpFileRemove(const char* fname, int fLeave); extern int Util_SignalSystem(const char* cmd); |