@@ -27,6 +27,8 @@ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2727typedef struct {
2828 pid_t pid ;
2929 const char * command ;
30+ int up ;
31+ int error ;
3032} subprocess ;
3133
3234void print_help ();
@@ -39,8 +41,6 @@ int verbose = 0;
3941char * const * commands ;
4042int nbr_processes = 0 ;
4143subprocess * subprocesses = NULL ;
42- int error = 0 ;
43- int counter = 0 ;
4444int closing = 0 ;
4545
4646int 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