#include #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif #ifdef INT64 void mrccend_(long*); void dmrccend_(long*); long ERROR_SIGTERM = -1; long ERROR_SIGSEGV = -2; #else void mrccend_(int*); void dmrccend_(int*); int ERROR_SIGTERM = -1; int ERROR_SIGSEGV = -2; #endif void parent_sigterm_(int, siginfo_t *, void *); void child_sigterm_(int, siginfo_t *, void *); void child_sigsegv_(int, siginfo_t *, void *); void sendSignalToChildren(int); static struct sigaction old_act; void signalinit_() { // initialise dmrcc's responses to signals struct sigaction act_term; memset(&act_term, '\0', sizeof(act_term)); act_term.sa_sigaction = &parent_sigterm_; act_term.sa_flags = SA_SIGINFO; sigaction(SIGTERM, &act_term, NULL); } void parent_sigterm_(int signum, siginfo_t *siginfo, void *context) { // initialise response to signal SIGTERM pid_t pid_parent; char pidchar[10]; char command[40]; pid_parent = getpid(); sprintf(pidchar, "%d", pid_parent); printf("\n Program dmrcc recieved SIGTERM\n"); fflush(stdout); sendSignalToChildren(SIGTERM); sleep(5); sendSignalToChildren(SIGKILL); printf("\n Program dmrcc terminating\n"); fflush(stdout); dmrccend_(&ERROR_SIGTERM); } void sendSignalToChildren(int sig) { int ownPid = getpid(); int pid, numPids = 0; int *pids; FILE *pidfile = fopen("pids", "r"); if (pidfile == NULL) { printf("Error: Could not open pids file\n"); return; } // number of running processes other than the current process while (fscanf(pidfile, "%d", &pid) != EOF) { if (pid != ownPid) { numPids++; } } rewind(pidfile); // read other process' PIDs pids = (int *)malloc(numPids * sizeof(int)); int i = -1; while (fscanf(pidfile, "%d", &pid) != EOF) { if (pid != ownPid) { pids[++i] = pid; } } // send signal sig to processes printf("\n Sending signal %2d to child processes\n", sig); fflush(stdout); for (i = 0; i < numPids; i++) { kill((pid_t)pids[i], sig); } fclose(pidfile); free(pids); } void signalinitchild_() { // initialise child's responses to signals struct sigaction act_term; memset (&act_term, '\0', sizeof(act_term)); act_term.sa_sigaction = &child_sigterm_; act_term.sa_flags = SA_SIGINFO; sigaction(SIGTERM, &act_term, NULL); struct sigaction act_segv; memset (&act_segv, '\0', sizeof(act_segv)); act_segv.sa_sigaction = &child_sigsegv_; act_segv.sa_flags = SA_SIGINFO; sigaction(SIGSEGV, &act_segv, &old_act); } void child_sigterm_(int signum, siginfo_t *siginfo, void *context) { // initialise child's response to signal SIGTERM mrccend_(&ERROR_SIGTERM); } void child_sigsegv_(int signum, siginfo_t *siginfo, void *context) { // initialise child's response to signal SIGSEGV mrccend_(&ERROR_SIGSEGV); if(old_act.sa_flags & SA_SIGINFO) { (*old_act.sa_sigaction)(signum, siginfo, context); } else { (*old_act.sa_handler)(signum); } } #ifdef __cplusplus } #endif