commit 74ef8aae7e2bc5e35fe53a09877d13f1bc5ccaf5 from: Stefan Sperling date: Mon Oct 24 10:05:39 2022 UTC close parent's end of imsg pipe before waiting for a child process to exit Prevents a dead-lock in 'tog log' where tog wants to exit (e.g. because the user pressed Ctrl-C) while a got-read-pack child process wants to send more commits. Closing the parent's pipe descriptor makes writes to the pipe fail in the child process. The child then unwinds via an ERR_EOF error and exits, instead of forever polling its end of the pipe in order to write more data. ok jamsek commit - bc854c7bc75429b27c69c3d76a040b8c428799ad commit + 74ef8aae7e2bc5e35fe53a09877d13f1bc5ccaf5 blob - b23e07e8e54eaf89df334656dbd6aa25515290d2 blob + a0e4605db9d0e09c13d9759d920424011998a329 --- lib/pack.c +++ lib/pack.c @@ -791,7 +791,7 @@ done: static const struct got_error * pack_stop_privsep_child(struct got_pack *pack) { - const struct got_error *err = NULL; + const struct got_error *err = NULL, *close_err = NULL; if (pack->privsep_child == NULL) return NULL; @@ -799,9 +799,12 @@ pack_stop_privsep_child(struct got_pack *pack) err = got_privsep_send_stop(pack->privsep_child->imsg_fd); if (err) return err; + if (close(pack->privsep_child->imsg_fd) == -1) + close_err = got_error_from_errno("close"); err = got_privsep_wait_for_child(pack->privsep_child->pid); - if (close(pack->privsep_child->imsg_fd) == -1 && err == NULL) - err = got_error_from_errno("close"); + if (close_err && err == NULL) + err = close_err; + imsg_clear(pack->privsep_child->ibuf); free(pack->privsep_child->ibuf); free(pack->privsep_child); pack->privsep_child = NULL;