commit 39b18c7c0c3039efb57a18c79cc86e677515b015 from: Stefan Sperling date: Thu Nov 21 21:07:17 2024 UTC in gotd, use a polling loop around imsgbuf_write() instead of imsgbuf_flush() Avoids potential endless loops with non-blocking I/O. commit - 15fbb79b06dceefaebabb71fcd744fe8d47c6a9e commit + 39b18c7c0c3039efb57a18c79cc86e677515b015 blob - d5a675a1d448373ce99ea836c9148299c88f3d4e blob + d553e9560b4c02da94cd93934d81447fe7120a4b --- gotd/auth.c +++ gotd/auth.c @@ -259,8 +259,9 @@ auth_dispatch(int fd, short event, void *arg) } if (event & EV_WRITE) { - if (imsgbuf_flush(ibuf) == -1) - fatal("imsgbuf_flush"); + err = gotd_imsg_flush(ibuf); + if (err) + fatalx("%s", err->msg); } for (;;) { blob - 9555322131694aae331af8a3a6bbdc8250c1d531 blob + 03d8a3567b8ca2ae7126fba4812e92f0f2c9f7d9 --- gotd/gotd.c +++ gotd/gotd.c @@ -581,17 +581,17 @@ gotd_request(int fd, short events, void *arg) ssize_t n; if (events & EV_WRITE) { - if (imsgbuf_flush(ibuf) == -1) { + err = gotd_imsg_flush(ibuf); + if (err) { /* * The client has closed its socket. This can * happen when Git clients are done sending * pack file data. */ - if (errno == EPIPE) { + if (err->code == GOT_ERR_ERRNO && errno == EPIPE) { disconnect(client); return; } - err = got_error_from_errno("imsgbuf_flush"); disconnect_on_error(client, err); return; } @@ -1045,6 +1045,7 @@ connect_repo_child(struct gotd_client *client, static void gotd_dispatch_listener(int fd, short event, void *arg) { + const struct got_error *err = NULL; struct gotd_imsgev *iev = arg; struct imsgbuf *ibuf = &iev->ibuf; struct gotd_child_proc *proc = gotd.listen_proc; @@ -1066,8 +1067,9 @@ gotd_dispatch_listener(int fd, short event, void *arg) } if (event & EV_WRITE) { - if (imsgbuf_flush(ibuf) == -1) - fatal("imsgbuf_flush"); + err = gotd_imsg_flush(ibuf); + if (err) + fatalx("%s", err->msg); } for (;;) { @@ -1126,6 +1128,7 @@ done: static void gotd_dispatch_notifier(int fd, short event, void *arg) { + const struct got_error *err = NULL; struct gotd_imsgev *iev = arg; struct imsgbuf *ibuf = &iev->ibuf; struct gotd_child_proc *proc = gotd.notify_proc; @@ -1147,8 +1150,9 @@ gotd_dispatch_notifier(int fd, short event, void *arg) } if (event & EV_WRITE) { - if (imsgbuf_flush(ibuf) == -1) - fatal("imsgbuf_flush"); + err = gotd_imsg_flush(ibuf); + if (err) + fatalx("%s", err->msg); } for (;;) { @@ -1220,8 +1224,9 @@ gotd_dispatch_auth_child(int fd, short event, void *ar } if (event & EV_WRITE) { - if (imsgbuf_flush(ibuf) == -1) - fatal("imsgbuf_flush"); + err = gotd_imsg_flush(ibuf); + if (err) + fatalx("%s", err->msg); goto done; } @@ -1362,6 +1367,7 @@ connect_session(struct gotd_client *client) static void gotd_dispatch_client_session(int fd, short event, void *arg) { + const struct got_error *err = NULL; struct gotd_imsgev *iev = arg; struct imsgbuf *ibuf = &iev->ibuf; struct gotd_child_proc *proc = NULL; @@ -1389,8 +1395,9 @@ gotd_dispatch_client_session(int fd, short event, void } if (event & EV_WRITE) { - if (imsgbuf_flush(ibuf) == -1) - fatal("imsgbuf_flush"); + err = gotd_imsg_flush(ibuf); + if (err) + fatalx("%s", err->msg); } proc = client->session; @@ -1517,6 +1524,7 @@ connect_notifier_and_session(struct gotd_client *clien static void gotd_dispatch_repo_child(int fd, short event, void *arg) { + const struct got_error *err = NULL; struct gotd_imsgev *iev = arg; struct imsgbuf *ibuf = &iev->ibuf; struct gotd_child_proc *proc = NULL; @@ -1544,8 +1552,9 @@ gotd_dispatch_repo_child(int fd, short event, void *ar } if (event & EV_WRITE) { - if (imsgbuf_flush(ibuf) == -1) - fatal("imsgbuf_flush"); + err = gotd_imsg_flush(ibuf); + if (err) + fatalx("%s", err->msg); } proc = client->repo; @@ -1553,7 +1562,6 @@ gotd_dispatch_repo_child(int fd, short event, void *ar fatalx("cannot find child process for fd %d", fd); for (;;) { - const struct got_error *err = NULL; uint32_t client_id = 0; int do_disconnect = 0; @@ -2395,8 +2403,9 @@ main(int argc, char **argv) if (imsg_compose(imsgbuf, GOTD_IMSG_SECRETS, 0, 0, -1, &n, sizeof(n)) == -1) fatal("imsg_compose GOTD_IMSG_SECRETS"); - if (imsgbuf_flush(imsgbuf)) - fatal("imsg_flush"); + error = gotd_imsg_flush(imsgbuf); + if (error) + fatalx("%s", error->msg); for (i = 0; i < n; ++i) { struct iovec iov[5]; @@ -2421,8 +2430,9 @@ main(int argc, char **argv) if (imsg_composev(imsgbuf, GOTD_IMSG_SECRET, 0, 0, -1, iov, 5) == -1) fatal("imsg_composev GOTD_IMSG_SECRET"); - if (imsgbuf_flush(imsgbuf)) - fatal("imsg_flush"); + error = gotd_imsg_flush(imsgbuf); + if (error) + fatalx("%s", error->msg); } gotd_secrets_free(gotd.secrets); blob - fa3a34257546e4f94e2a0884df1efca5d638a989 blob + bfd6bbf7fbb49725e8fc97d249263d3bab769903 --- gotd/listen.c +++ gotd/listen.c @@ -401,8 +401,9 @@ listen_dispatch(int fd, short event, void *arg) } if (event & EV_WRITE) { - if (imsgbuf_flush(ibuf) == -1) - fatal("imsgbuf_flush"); + err = gotd_imsg_flush(ibuf); + if (err) + fatalx("%s", err->msg); } for (;;) { blob - fe81597499b4aed3863e9dc2ec128dd6243675bf blob + 918d5245f9276afb922afaffb8650b0b74366238 --- gotd/notify.c +++ gotd/notify.c @@ -374,6 +374,7 @@ done: static void notify_dispatch_session(int fd, short event, void *arg) { + const struct got_error *err = NULL; struct gotd_imsgev *iev = arg; struct imsgbuf *ibuf = &iev->ibuf; ssize_t n; @@ -391,9 +392,10 @@ notify_dispatch_session(int fd, short event, void *arg } if (event & EV_WRITE) { - if (imsgbuf_flush(ibuf) == -1) { - if (errno != EPIPE) - fatal("imsgbuf_flush"); + err = gotd_imsg_flush(ibuf); + if (err) { + if (err->code != GOT_ERR_ERRNO || errno != EPIPE) + fatalx("%s", err->msg); shut = 1; goto done; } @@ -504,6 +506,7 @@ notify_ibuf_get_str(char **ret, struct ibuf *ibuf) static void notify_dispatch(int fd, short event, void *arg) { + const struct got_error *err = NULL; struct gotd_imsgev *iev = arg; struct imsgbuf *imsgbuf = &iev->ibuf; ssize_t n; @@ -523,8 +526,9 @@ notify_dispatch(int fd, short event, void *arg) } if (event & EV_WRITE) { - if (imsgbuf_flush(imsgbuf) == -1) - fatal("imsgbuf_flush"); + err = gotd_imsg_flush(imsgbuf); + if (err) + fatalx("%s", err->msg); } for (;;) { blob - 775032711c4fdef151b37569d36eb4ae6f096289 blob + e0ce4b14263c87ffadab937db6475f3c27f5b726 --- gotd/repo_read.c +++ gotd/repo_read.c @@ -694,8 +694,9 @@ repo_read_dispatch_session(int fd, short event, void * } if (event & EV_WRITE) { - if (imsgbuf_flush(ibuf) == -1) - fatal("imsgbuf_flush"); + err = gotd_imsg_flush(ibuf); + if (err) + fatalx("%s", err->msg); } while (err == NULL && check_cancelled(NULL) == NULL) { @@ -814,8 +815,9 @@ repo_read_dispatch(int fd, short event, void *arg) } if (event & EV_WRITE) { - if (imsgbuf_flush(ibuf) == -1) - fatal("imsgbuf_flush"); + err = gotd_imsg_flush(ibuf); + if (err) + fatalx("%s", err->msg); } while (err == NULL && check_cancelled(NULL) == NULL) { blob - e2cb36c1801787fe97ea444ce0cfd506c8756242 blob + 3671b677adb0d7b91ccc4ee66f0bf4efdcbb0fa1 --- gotd/repo_write.c +++ gotd/repo_write.c @@ -2181,8 +2181,9 @@ repo_write_dispatch_session(int fd, short event, void } if (event & EV_WRITE) { - if (imsgbuf_flush(ibuf) == -1) - fatal("imsgbuf_flush"); + err = gotd_imsg_flush(ibuf); + if (err) + fatalx("%s", err->msg); } for (;;) { @@ -2338,8 +2339,9 @@ repo_write_dispatch(int fd, short event, void *arg) } if (event & EV_WRITE) { - if (imsgbuf_flush(ibuf) == -1) - fatal("imsgbuf_flush"); + err = gotd_imsg_flush(ibuf); + if (err) + fatalx("%s", err->msg); } while (err == NULL) { blob - 609ad42bb7cd685756ef7ece7671bd972cc5c5fd blob + 08488403d28781f88b745596e03646c72fb388fb --- gotd/session_read.c +++ gotd/session_read.c @@ -196,6 +196,7 @@ recv_packfile_done(struct imsg *imsg) static void session_dispatch_repo_child(int fd, short event, void *arg) { + const struct got_error *err = NULL; struct gotd_imsgev *iev = arg; struct imsgbuf *ibuf = &iev->ibuf; struct gotd_session_client *client = &gotd_session_client; @@ -214,8 +215,9 @@ session_dispatch_repo_child(int fd, short event, void } if (event & EV_WRITE) { - if (imsgbuf_flush(ibuf) == -1) - fatal("imsgbuf_flush"); + err = gotd_imsg_flush(ibuf); + if (err) + fatalx("%s", err->msg); } for (;;) { @@ -456,8 +458,8 @@ session_dispatch_client(int fd, short events, void *ar ssize_t n; if (events & EV_WRITE) { - if (imsgbuf_flush(ibuf) == -1) { - err = got_error_from_errno("imsg_flush"); + err = gotd_imsg_flush(ibuf); + if (err) { disconnect_on_error(client, err); return; } @@ -737,6 +739,7 @@ recv_repo_child(struct imsg *imsg) static void session_dispatch(int fd, short event, void *arg) { + const struct got_error *err = NULL; struct gotd_imsgev *iev = arg; struct imsgbuf *ibuf = &iev->ibuf; struct gotd_session_client *client = &gotd_session_client; @@ -755,9 +758,9 @@ session_dispatch(int fd, short event, void *arg) } if (event & EV_WRITE) { - n = imsgbuf_flush(ibuf); - if (n == -1) - fatal("imsgbuf_flush"); + err = gotd_imsg_flush(ibuf); + if (err) + fatalx("%s", err->msg); } for (;;) { blob - 319e71e7eb3d58e4fa2f98bf5ff1ed64e8b6b52a blob + d8aa07fc9092cb768a02427b7abd993f30b20971 --- gotd/session_write.c +++ gotd/session_write.c @@ -863,6 +863,7 @@ recv_notification_content(struct imsg *imsg) static void session_dispatch_repo_child(int fd, short event, void *arg) { + const struct got_error *err = NULL; struct gotd_imsgev *iev = arg; struct imsgbuf *ibuf = &iev->ibuf; struct gotd_session_client *client = &gotd_session_client; @@ -881,8 +882,9 @@ session_dispatch_repo_child(int fd, short event, void } if (event & EV_WRITE) { - if (imsgbuf_flush(ibuf) == -1) - fatal("imsgbuf_flush"); + err = gotd_imsg_flush(ibuf); + if (err) + fatalx("%s", err->msg); } for (;;) { @@ -1207,7 +1209,8 @@ session_dispatch_client(int fd, short events, void *ar ssize_t n; if (events & EV_WRITE) { - if (imsgbuf_flush(ibuf) == -1) { + err = gotd_imsg_flush(ibuf); + if (err) { /* * The client has closed its socket. This can * happen when Git clients are done sending @@ -1216,11 +1219,10 @@ session_dispatch_client(int fd, short events, void *ar */ if (STAILQ_FIRST(¬ifications) != NULL) return; - if (errno == EPIPE) { + if (err->code == GOT_ERR_ERRNO && errno == EPIPE) { disconnect(client); return; } - err = got_error_from_errno("imsgbuf_flush"); disconnect_on_error(client, err); return; } @@ -1455,8 +1457,9 @@ session_dispatch_notifier(int fd, short event, void *a } if (event & EV_WRITE) { - if (imsgbuf_flush(ibuf) == -1) - fatal("imsgbuf_flush"); + err = gotd_imsg_flush(ibuf); + if (err) + fatalx("%s", err->msg); } for (;;) { @@ -1591,6 +1594,7 @@ recv_repo_child(struct imsg *imsg) static void session_dispatch(int fd, short event, void *arg) { + const struct got_error *err = NULL; struct gotd_imsgev *iev = arg; struct imsgbuf *ibuf = &iev->ibuf; struct gotd_session_client *client = &gotd_session_client; @@ -1609,8 +1613,9 @@ session_dispatch(int fd, short event, void *arg) } if (event & EV_WRITE) { - if (imsgbuf_flush(ibuf) == -1) - fatal("imsgbuf_flush"); + err = gotd_imsg_flush(ibuf); + if (err) + fatalx("%s", err->msg); } for (;;) {