mirror of
https://code.it4i.cz/sccs/easyconfigs-it4i.git
synced 2025-04-16 19:50:50 +01:00
133 lines
3.1 KiB
C
Executable File
133 lines
3.1 KiB
C
Executable File
#include <signal.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
|
|
|
|
#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
|