Skip to content

Commit

Permalink
Improved code a little to better handle process status supervision
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolas-van committed Dec 15, 2016
1 parent 09325e1 commit a2cf439
Showing 1 changed file with 50 additions and 35 deletions.
85 changes: 50 additions & 35 deletions multirun.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
typedef struct {
pid_t pid;
const char* command;
int up;
int error;
} subprocess;

void print_help();
Expand All @@ -39,8 +41,6 @@ int verbose = 0;
char* const* commands;
int nbr_processes = 0;
subprocess* subprocesses = NULL;
int error = 0;
int counter = 0;
int closing = 0;

int main(int argc, char* const* argv) {
Expand Down Expand Up @@ -87,6 +87,8 @@ void launch_processes() {
subprocess new_sub;
new_sub.pid = pid;
new_sub.command = commands[i];
new_sub.up = 1;
new_sub.error = 0;
subprocesses[i] = new_sub;
}
}
Expand All @@ -97,47 +99,60 @@ void launch_processes() {
if (sigaction(SIGTERM, &ssig, NULL))
exit(-1);

while (counter < nbr_processes) {
while (1) {
pid_t pid = wait(&wstatus);
if (pid == -1) {
continue;
}
if (WIFEXITED(wstatus) || WIFSIGNALED(wstatus)) {
subprocess* process = NULL;
for (int i = 0; i < nbr_processes; i++) {
if (subprocesses[i].pid == pid) {
process = &subprocesses[i];
break;
}
subprocess* process = NULL;
for (int i = 0; i < nbr_processes; i++) {
if (subprocesses[i].pid == pid) {
process = &subprocesses[i];
break;
}
counter += 1;
if ((WIFEXITED(wstatus) && WEXITSTATUS(wstatus) != 0)
|| (WIFSIGNALED(wstatus) && WTERMSIG(wstatus) != SIGINT && WTERMSIG(wstatus) != SIGTERM)) {
error = 1;
if (verbose) {
printf("multirun: command %s with pid %d exited abnormally\n",
process != NULL ? process->command : "unknown", pid);
}
if (process != NULL) {
// check if process is down
if (WIFEXITED(wstatus) || WIFSIGNALED(wstatus)) {
process->up = 0;
if ((WIFEXITED(wstatus) && WEXITSTATUS(wstatus) != 0)
|| (WIFSIGNALED(wstatus) && WTERMSIG(wstatus) != SIGINT && WTERMSIG(wstatus) != SIGTERM)) {
process->error = 1;
if (verbose) {
printf("multirun: command %s with pid %d exited abnormally\n", process->command, pid);
}
} else {
if (verbose) {
printf("multirun: command %s with pid %d exited normally\n", process->command, pid);
}
}
} else {
if (verbose) {
printf("multirun: command %s with pid %d exited normally\n",
process != NULL ? process->command : "unknown", pid);
if (! closing) {
closing = 1;
// activate Goebbels mode
if (verbose) {
printf("multirun: sending SIGTERM to all subprocesses\n");
}
kill_all(SIGTERM);
}
}
if (! closing) {
closing = 1;
if (verbose) {
printf("multirun: sending SIGTERM to all subprocesses\n");
}
kill_all(SIGTERM);
}
} else {
if (verbose) {
printf("multirun: received unhandled signal from subprocess\n");
}
// check if all processes are stopped
int running = 0;
for (int i = 0; i < nbr_processes; i++) {
if (subprocesses[i].up) {
running = 1;
break;
}
}
if (! running)
break;
}
// check if there are errors
int error = 0;
for (int i = 0; i < nbr_processes; i++) {
if (subprocesses[i].error) {
error = 1;
break;
}
}
if (error == 1) {
if (error) {
fprintf(stderr, "multirun: one or more of the provided commands ended abnormally\n");
exit(-1);
} else {
Expand Down

0 comments on commit a2cf439

Please sign in to comment.