Commit Diff


commit - fe765fe37f5275f9401414459afca40b129b9e84
commit + e76ac8c4d20af37d1069caf4c2cf4b715983c512
blob - 4a3d57fa52d2dd981fdb1deb28c23527489d0ace
blob + 4d8842f876140346f08f7e3eb3a48f46e0fc96e7
--- main.c
+++ main.c
@@ -396,66 +396,71 @@ extends_sigchld(int fd, short event, void *arg)
 	struct command *cmd;
 	int avail;
 
-	if ((pid = wait(&st)) == -1)
-		fatal("wait");
+	while (1) {
+		if ((pid = waitpid(WAIT_ANY, &st, WNOHANG)) == -1)
+			fatal("wait");
+		if (pid == 0)
+			return;
 
-	RB_FOREACH(cmd, commands, &conf->commands) {
-		if (cmd->pid == pid)
-			break;
-	}
-
-	do {
-		if (cmd->outfd == -1)
-			break;
-		if (ioctl(cmd->outfd, FIONREAD, &avail) == -1) {
-			log_warn("%s: ioctl(FIONREAD)", cmd->token);
-			avail = 0;
+		RB_FOREACH(cmd, commands, &conf->commands) {
+			if (cmd->pid == pid)
+				break;
 		}
-		if (avail > 0)
-			extends_cmd_out(cmd->outfd, EV_READ, cmd);
-	} while (avail > 0);
-	do {
-		if (cmd->errfd == -1)
-			break;
-		if (ioctl(cmd->errfd, FIONREAD, &avail) == -1) {
-			log_warn("%s: ioctl(FIONREAD)", cmd->token);
-			avail = 0;
-		}
-		if (avail > 0)
-			extends_cmd_err(cmd->errfd, EV_READ, cmd);
-	} while (avail > 0);
 
-	if (cmd->errstr[0] != '\0')
-		log_warnx("%s: %s", cmd->token, cmd->errstr);
+		do {
+			if (cmd->outfd == -1)
+				break;
+			if (ioctl(cmd->outfd, FIONREAD, &avail) == -1) {
+				log_warn("%s: ioctl(FIONREAD)", cmd->token);
+				avail = 0;
+			}
+			if (avail > 0)
+				extends_cmd_out(cmd->outfd, EV_READ, cmd);
+		} while (avail > 0);
+		do {
+			if (cmd->errfd == -1)
+				break;
+			if (ioctl(cmd->errfd, FIONREAD, &avail) == -1) {
+				log_warn("%s: ioctl(FIONREAD)", cmd->token);
+				avail = 0;
+			}
+			if (avail > 0)
+				extends_cmd_err(cmd->errfd, EV_READ, cmd);
+		} while (avail > 0);
 
-	if (cmd->result == 0) {
-		if (WIFCONTINUED(st))
-			return;
-		if (WIFSTOPPED(st)) {
-			log_info("%s: stopped, restarting", cmd->token);
-			if (kill(pid, SIGCONT) == -1)
-				fatal("kill(SIGCONT)");
-			return;
+		if (cmd->errstr[0] != '\0')
+			log_warnx("%s: %s", cmd->token, cmd->errstr);
+
+		if (cmd->result == 0) {
+			if (WIFCONTINUED(st))
+				return;
+			if (WIFSTOPPED(st)) {
+				log_info("%s: stopped, restarting", cmd->token);
+				if (kill(pid, SIGCONT) == -1)
+					fatal("kill(SIGCONT)");
+				return;
+			}
+			code = WEXITSTATUS(st);
+			if (imsg_compose(&pc, IMSG_RESULT, cmd->id, 0, -1,
+			    &code, sizeof(code)) == -1)
+				fatal("imsg_compose");
+		} else {
+			if (imsg_compose(&pc, IMSG_FAIL,
+			    cmd->id, 0, -1, NULL, 0) == -1)
+				fatal("imsg_compose");
 		}
-		code = WEXITSTATUS(st);
-		if (imsg_compose(&pc, IMSG_RESULT, cmd->id, 0, -1,
-		    &code, sizeof(code)) == -1)
-			fatal("imsg_compose");
-	} else {
-		if (imsg_compose(&pc, IMSG_FAIL, cmd->id, 0, -1, NULL, 0) == -1)
-			fatal("imsg_compose");
+		cmd->errstr[0] = '\0';
+		event_del(&cmd->inev);
+		event_del(&cmd->outev);
+		event_del(&cmd->errev);
+		close(cmd->infd);
+		close(cmd->outfd);
+		close(cmd->errfd);
+		cmd->infd = cmd->outfd = cmd->errfd = -1;
+		cmd->pid = -1;
+		if (imsgbuf_write(&pc) == -1)
+			fatal("imsgbuf_write");
 	}
-	cmd->errstr[0] = '\0';
-	event_del(&cmd->inev);
-	event_del(&cmd->outev);
-	event_del(&cmd->errev);
-	close(cmd->infd);
-	close(cmd->outfd);
-	close(cmd->errfd);
-	cmd->infd = cmd->outfd = cmd->errfd = -1;
-	cmd->pid = -1;
-	if (imsgbuf_write(&pc) == -1)
-		fatal("imsgbuf_write");
 }
 
 void