commit - e82d0e1ce54259918e9100d0cf6c388ea60c64e4
commit + c2274a511a7415078e2628f969b8459f69432411
blob - f52eb058111051a61a5c7424d7c40c928859452a
blob + ca804215774b6251b2ff96aea5d72ff6330e2973
--- gotd/session_read.c
+++ gotd/session_read.c
struct timeval request_timeout;
enum gotd_session_read_state state;
struct gotd_imsgev repo_child_iev;
+ int repo_child_packfd;
} gotd_session;
static struct gotd_session_client {
return err;
}
- /* Send pack pipe end 0 to repo child process. */
- if (gotd_imsg_compose_event(&gotd_session.repo_child_iev,
+ /*
+ * Send pack data pipe end 0 to gotsh(1) (expects just an fd, no data).
+ *
+ * We will forward the other pipe end to the repo_read process only
+ * once we have confirmation that gotsh(1) has received its end.
+ * It is important that we send a pipe end to gotsh(1) before the
+ * repo_read process starts sending pack progress messages via imsg
+ * to prevent spurious "unexpected privsep message" errors from gotsh.
+ */
+ if (gotd_imsg_compose_event(&client->iev,
GOTD_IMSG_PACKFILE_PIPE, PROC_GOTD, pipe[0], NULL, 0) == -1) {
err = got_error_from_errno("imsg compose PACKFILE_PIPE");
close(pipe[1]);
return err;
}
- /* Send pack pipe end 1 to gotsh(1) (expects just an fd, no data). */
- if (gotd_imsg_compose_event(&client->iev,
- GOTD_IMSG_PACKFILE_PIPE, PROC_GOTD, pipe[1], NULL, 0) == -1)
- err = got_error_from_errno("imsg compose PACKFILE_PIPE");
-
- return err;
+ gotd_session.repo_child_packfd = pipe[1];
+ return NULL;
}
static void
client->accept_flush_pkt = 1;
err = send_packfile(client);
break;
+ case GOTD_IMSG_PACKFILE_READY:
+ if (gotd_session.repo_child_packfd == -1) {
+ err = got_error(GOT_ERR_PRIVSEP_MSG);
+ break;
+ }
+ /*
+ * gotsh(1) has received its send of the pack pipe.
+ * Send pack pipe end 1 to repo child process.
+ */
+ if (gotd_imsg_compose_event(
+ &gotd_session.repo_child_iev,
+ GOTD_IMSG_PACKFILE_PIPE, PROC_GOTD,
+ gotd_session.repo_child_packfd, NULL, 0) == -1) {
+ err = got_error_from_errno("imsg compose "
+ "PACKFILE_PIPE");
+ } else
+ gotd_session.repo_child_packfd = -1;
+ break;
default:
log_debug("unexpected imsg %d", imsg.hdr.type);
err = got_error(GOT_ERR_PRIVSEP_MSG);
memcpy(&gotd_session.request_timeout, request_timeout,
sizeof(gotd_session.request_timeout));
gotd_session.repo_cfg = repo_cfg;
+ gotd_session.repo_child_packfd = -1;
if (imsgbuf_init(&gotd_session.notifier_iev.ibuf, -1) == -1) {
err = got_error_from_errno("imsgbuf_init");
got_repo_pack_fds_close(gotd_session.pack_fds);
got_repo_temp_fds_close(gotd_session.temp_fds);
free(gotd_session_client.username);
+ if (gotd_session.repo_child_packfd != -1)
+ close(gotd_session.repo_child_packfd);
exit(0);
}
blob - 4a2bab0b7932ec20883e152b231992ed8b75e0f4
blob + bf8e3261ba0241ac634ea7756c6793870799a9ed
--- lib/serve.c
+++ lib/serve.c
break;
case GOTD_IMSG_PACKFILE_PIPE:
fd = imsg_get_fd(&imsg);
- if (fd != -1)
- *packfd = fd;
- else
+ if (fd == -1) {
err = got_error(GOT_ERR_PRIVSEP_NO_FD);
+ break;
+ }
+ *packfd = fd;
+ if (imsg_compose(ibuf, GOTD_IMSG_PACKFILE_READY,
+ 0, 0, -1, NULL, 0) == -1)
+ err = got_error_from_errno("imsg_compose "
+ "PACKFILE_READY");
+ err = gotd_imsg_flush(ibuf);
break;
default:
err = got_error(GOT_ERR_PRIVSEP_MSG);