@@ -27,6 +27,8 @@ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27
27
typedef struct {
28
28
pid_t pid ;
29
29
const char * command ;
30
+ int up ;
31
+ int error ;
30
32
} subprocess ;
31
33
32
34
void print_help ();
@@ -39,8 +41,6 @@ int verbose = 0;
39
41
char * const * commands ;
40
42
int nbr_processes = 0 ;
41
43
subprocess * subprocesses = NULL ;
42
- int error = 0 ;
43
- int counter = 0 ;
44
44
int closing = 0 ;
45
45
46
46
int main (int argc , char * const * argv ) {
@@ -87,6 +87,8 @@ void launch_processes() {
87
87
subprocess new_sub ;
88
88
new_sub .pid = pid ;
89
89
new_sub .command = commands [i ];
90
+ new_sub .up = 1 ;
91
+ new_sub .error = 0 ;
90
92
subprocesses [i ] = new_sub ;
91
93
}
92
94
}
@@ -97,47 +99,60 @@ void launch_processes() {
97
99
if (sigaction (SIGTERM , & ssig , NULL ))
98
100
exit (-1 );
99
101
100
- while (counter < nbr_processes ) {
102
+ while (1 ) {
101
103
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 ;
112
109
}
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
+ }
120
125
}
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 );
125
133
}
126
134
}
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 ;
137
142
}
138
143
}
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
+ }
139
154
}
140
- if (error == 1 ) {
155
+ if (error ) {
141
156
fprintf (stderr , "multirun: one or more of the provided commands ended abnormally\n" );
142
157
exit (-1 );
143
158
} else {
0 commit comments