Skip to content

Commit a2cf439

Browse files
committed
Improved code a little to better handle process status supervision
1 parent 09325e1 commit a2cf439

File tree

1 file changed

+50
-35
lines changed

1 file changed

+50
-35
lines changed

multirun.c

Lines changed: 50 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2727
typedef struct {
2828
pid_t pid;
2929
const char* command;
30+
int up;
31+
int error;
3032
} subprocess;
3133

3234
void print_help();
@@ -39,8 +41,6 @@ int verbose = 0;
3941
char* const* commands;
4042
int nbr_processes = 0;
4143
subprocess* subprocesses = NULL;
42-
int error = 0;
43-
int counter = 0;
4444
int closing = 0;
4545

4646
int main(int argc, char* const* argv) {
@@ -87,6 +87,8 @@ void launch_processes() {
8787
subprocess new_sub;
8888
new_sub.pid = pid;
8989
new_sub.command = commands[i];
90+
new_sub.up = 1;
91+
new_sub.error = 0;
9092
subprocesses[i] = new_sub;
9193
}
9294
}
@@ -97,47 +99,60 @@ void launch_processes() {
9799
if (sigaction(SIGTERM, &ssig, NULL))
98100
exit(-1);
99101

100-
while (counter < nbr_processes) {
102+
while (1) {
101103
pid_t pid = wait(&wstatus);
102-
if (pid == -1) {
103-
continue;
104-
}
105-
if (WIFEXITED(wstatus) || WIFSIGNALED(wstatus)) {
106-
subprocess* process = NULL;
107-
for (int i = 0; i < nbr_processes; i++) {
108-
if (subprocesses[i].pid == pid) {
109-
process = &subprocesses[i];
110-
break;
111-
}
104+
subprocess* process = NULL;
105+
for (int i = 0; i < nbr_processes; i++) {
106+
if (subprocesses[i].pid == pid) {
107+
process = &subprocesses[i];
108+
break;
112109
}
113-
counter += 1;
114-
if ((WIFEXITED(wstatus) && WEXITSTATUS(wstatus) != 0)
115-
|| (WIFSIGNALED(wstatus) && WTERMSIG(wstatus) != SIGINT && WTERMSIG(wstatus) != SIGTERM)) {
116-
error = 1;
117-
if (verbose) {
118-
printf("multirun: command %s with pid %d exited abnormally\n",
119-
process != NULL ? process->command : "unknown", pid);
110+
}
111+
if (process != NULL) {
112+
// check if process is down
113+
if (WIFEXITED(wstatus) || WIFSIGNALED(wstatus)) {
114+
process->up = 0;
115+
if ((WIFEXITED(wstatus) && WEXITSTATUS(wstatus) != 0)
116+
|| (WIFSIGNALED(wstatus) && WTERMSIG(wstatus) != SIGINT && WTERMSIG(wstatus) != SIGTERM)) {
117+
process->error = 1;
118+
if (verbose) {
119+
printf("multirun: command %s with pid %d exited abnormally\n", process->command, pid);
120+
}
121+
} else {
122+
if (verbose) {
123+
printf("multirun: command %s with pid %d exited normally\n", process->command, pid);
124+
}
120125
}
121-
} else {
122-
if (verbose) {
123-
printf("multirun: command %s with pid %d exited normally\n",
124-
process != NULL ? process->command : "unknown", pid);
126+
if (! closing) {
127+
closing = 1;
128+
// activate Goebbels mode
129+
if (verbose) {
130+
printf("multirun: sending SIGTERM to all subprocesses\n");
131+
}
132+
kill_all(SIGTERM);
125133
}
126134
}
127-
if (! closing) {
128-
closing = 1;
129-
if (verbose) {
130-
printf("multirun: sending SIGTERM to all subprocesses\n");
131-
}
132-
kill_all(SIGTERM);
133-
}
134-
} else {
135-
if (verbose) {
136-
printf("multirun: received unhandled signal from subprocess\n");
135+
}
136+
// check if all processes are stopped
137+
int running = 0;
138+
for (int i = 0; i < nbr_processes; i++) {
139+
if (subprocesses[i].up) {
140+
running = 1;
141+
break;
137142
}
138143
}
144+
if (! running)
145+
break;
146+
}
147+
// check if there are errors
148+
int error = 0;
149+
for (int i = 0; i < nbr_processes; i++) {
150+
if (subprocesses[i].error) {
151+
error = 1;
152+
break;
153+
}
139154
}
140-
if (error == 1) {
155+
if (error) {
141156
fprintf(stderr, "multirun: one or more of the provided commands ended abnormally\n");
142157
exit(-1);
143158
} else {

0 commit comments

Comments
 (0)