commit 10b6dbfa3cb419e92d575e24b5f37c0748f97a97 from: Isaac Meerleo date: Wed Jul 15 14:58:37 2026 UTC centralize checked imsg sends commit - 056b9939639819c1a2e85f0e73fc02dda5b27b78 commit + 10b6dbfa3cb419e92d575e24b5f37c0748f97a97 blob - 93314c1cf5366d4e2cbfa834d399e80834883a5f blob + 199147eb2fd7136670773126d6998110a272d666 --- regress/imsgev/Makefile +++ regress/imsgev/Makefile @@ -1,5 +1,5 @@ PROG= imsgev_test -SRCS= imsgev_test.c imsgev.c log.c +SRCS= imsgev_test.c imsgev_regress.c log.c LDADD= -levent -lutil DPADD= ${LIBEVENT} ${LIBUTIL} blob - f2fdf7f0d1295eab089010d5678c8daf04235d2d blob + 6c3766888c8fd793a430fc901c944614bfa62815 --- regress/imsgev/imsgev_test.c +++ regress/imsgev/imsgev_test.c @@ -16,18 +16,28 @@ #include #include +#include #include #include +#include +#include #include #include +#include #include +#include #include #include "imsgev.h" +#include "log.h" +#include "imsgev_regress.h" #include "regress.h" +#define TEST_DATA 41 +#define TEST_END 42 + static void make_imsg(const void *data, size_t len, struct imsgbuf *receiver, struct imsg *imsg) @@ -54,15 +64,183 @@ make_imsg(const void *data, size_t len, struct imsgbuf close(fds[1]); } +static void +channel_init(struct imsgev *iev, struct imsgbuf *receiver, int fds[2]) +{ + if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, fds) == -1) + err(1, "socketpair"); + imsgev_regress_reset(); + imsgev_init(iev, fds[0], NULL, NULL); + if (imsgbuf_init(receiver, fds[1]) == -1) + err(1, "imsgbuf_init receiver"); +} + +static void +channel_clear(struct imsgev *iev, struct imsgbuf *receiver, int fds[2]) +{ + imsgev_clear(iev); + imsgbuf_clear(receiver); + close(fds[0]); + close(fds[1]); +} + +static int +receive_one(struct imsgev *iev, struct imsgbuf *receiver, struct imsg *imsg) +{ + if (imsgbuf_flush(&iev->ibuf) == -1) + err(1, "imsgbuf_flush"); + if (imsgbuf_read(receiver) != 1) + errx(1, "imsgbuf_read"); + return (imsgbuf_get(receiver, imsg)); +} + +static int +dies(void (*fn)(void)) +{ + pid_t pid; + int devnull, status; + + fflush(stdout); + switch (pid = fork()) { + case -1: + err(1, "fork"); + case 0: + if ((devnull = open("/dev/null", O_WRONLY)) != -1) + (void)dup2(devnull, STDERR_FILENO); + fn(); + _exit(0); + default: + if (waitpid(pid, &status, 0) == -1) + err(1, "waitpid"); + return (WIFEXITED(status) && WEXITSTATUS(status) == 1); + } +} + +static void +die_init_add(void) +{ + struct imsgev iev; + int fds[2]; + + if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, fds) == -1) + err(1, "socketpair"); + imsgev_regress_reset(); + imsgev_regress_fail(IMSGEV_REGRESS_EVENT_ADD, 1); + imsgev_init(&iev, fds[0], NULL, NULL); +} + +static void +die_compose(void) +{ + struct imsgbuf receiver; + struct imsgev iev; + int fds[2]; + + channel_init(&iev, &receiver, fds); + imsgev_regress_reset(); + imsgev_regress_fail(IMSGEV_REGRESS_COMPOSE, 1); + imsgev_send(&iev, TEST_DATA, 0, NULL, 0); +} + +static void +die_rearm_del(void) +{ + struct imsgbuf receiver; + struct imsgev iev; + int fds[2]; + + channel_init(&iev, &receiver, fds); + imsgev_regress_reset(); + imsgev_regress_fail(IMSGEV_REGRESS_EVENT_DEL, 1); + imsgev_send(&iev, TEST_DATA, 0, NULL, 0); +} + +static void +die_rearm_add(void) +{ + struct imsgbuf receiver; + struct imsgev iev; + int fds[2]; + + channel_init(&iev, &receiver, fds); + imsgev_regress_reset(); + imsgev_regress_fail(IMSGEV_REGRESS_EVENT_ADD, 1); + imsgev_send(&iev, TEST_DATA, 0, NULL, 0); +} + +static void +die_clear_del(void) +{ + struct imsgbuf receiver; + struct imsgev iev; + int fds[2]; + + channel_init(&iev, &receiver, fds); + imsgev_regress_reset(); + imsgev_regress_fail(IMSGEV_REGRESS_EVENT_DEL, 1); + imsgev_clear(&iev); +} + +static int +failed_sequence(unsigned int fail_at, uint32_t *trace, size_t *trace_len) +{ + struct imsgbuf receiver; + struct imsgev iev; + ssize_t n; + size_t off; + pid_t pid; + int devnull, fds[2], pfd[2], status; + + if (pipe(pfd) == -1) + err(1, "pipe"); + fflush(stdout); + switch (pid = fork()) { + case -1: + err(1, "fork"); + case 0: + close(pfd[0]); + if ((devnull = open("/dev/null", O_WRONLY)) != -1) + (void)dup2(devnull, STDERR_FILENO); + channel_init(&iev, &receiver, fds); + imsgev_regress_reset(); + imsgev_regress_trace(pfd[1]); + imsgev_regress_fail(IMSGEV_REGRESS_COMPOSE, fail_at); + imsgev_send(&iev, TEST_DATA, 0, "a", 1); + imsgev_send(&iev, TEST_DATA, 0, "b", 1); + imsgev_send(&iev, TEST_END, 0, NULL, 0); + _exit(0); + default: + close(pfd[1]); + off = 0; + while (off < 4 * sizeof(*trace) && + (n = read(pfd[0], (u_char *)trace + off, + 4 * sizeof(*trace) - off)) > 0) + off += (size_t)n; + close(pfd[0]); + if (waitpid(pid, &status, 0) == -1) + err(1, "waitpid"); + *trace_len = off / sizeof(*trace); + return (WIFEXITED(status) && WEXITSTATUS(status) == 1); + } +} + int main(void) { static const u_char binary[] = { 'a', '\0', 'b' }; struct imsgev_payload payload; struct imsgbuf receiver; + struct imsgev iev; struct imsg imsg; + uint32_t trace[4]; + size_t trace_len; u_char byte; + int fds[2]; + log_init(LOG_TO_STDERR, 0, LOG_USER); + if (event_init() == NULL) + errx(1, "event_init"); + make_imsg(NULL, 0, &receiver, &imsg); payload.data = (const u_char *)1; payload.len = 1; @@ -93,5 +271,80 @@ main(void) imsg_free(&imsg); imsgbuf_clear(&receiver); + /* A normal send queues one exact empty frame and arms EV_WRITE. */ + channel_init(&iev, &receiver, fds); + imsgev_send(&iev, TEST_DATA, 7, NULL, 0); + CHECK(imsgbuf_queuelen(&iev.ibuf) == 1); + CHECK(iev.events == (EV_READ | EV_WRITE)); + CHECK(receive_one(&iev, &receiver, &imsg) == 1); + CHECK(imsg.hdr.type == TEST_DATA && imsg.hdr.peerid == 7); + CHECK(imsg_get_len(&imsg) == 0); + imsg_free(&imsg); + channel_clear(&iev, &receiver, fds); + + /* Embedded NULs remain bytes across the checked-send Interface. */ + channel_init(&iev, &receiver, fds); + imsgev_send(&iev, TEST_DATA, 9, binary, sizeof(binary)); + CHECK(imsgbuf_queuelen(&iev.ibuf) == 1); + CHECK(iev.events == (EV_READ | EV_WRITE)); + CHECK(receive_one(&iev, &receiver, &imsg) == 1); + CHECK(imsg.hdr.type == TEST_DATA && imsg.hdr.peerid == 9); + CHECK(imsgev_get_payload(&imsg, &payload) == 0); + CHECK(payload.len == sizeof(binary) && + memcmp(payload.data, binary, sizeof(binary)) == 0); + imsg_free(&imsg); + channel_clear(&iev, &receiver, fds); + + /* Every checked event operation and composition failure is fatal. */ + CHECK(dies(die_init_add)); + CHECK(dies(die_compose)); + CHECK(dies(die_rearm_del)); + CHECK(dies(die_rearm_add)); + CHECK(dies(die_clear_del)); + + /* A failed chunk stops the exchange before any terminal send. */ + CHECK(failed_sequence(1, trace, &trace_len)); + CHECK(trace_len == 1 && trace[0] == TEST_DATA); + CHECK(failed_sequence(2, trace, &trace_len)); + CHECK(trace_len == 2 && trace[0] == TEST_DATA && + trace[1] == TEST_DATA); + CHECK(failed_sequence(3, trace, &trace_len)); + CHECK(trace_len == 3 && trace[0] == TEST_DATA && + trace[1] == TEST_DATA && trace[2] == TEST_END); + + /* Teardown is synchronous, best effort, and never re-arms events. */ + channel_init(&iev, &receiver, fds); + imsgev_regress_reset(); + imsgev_send_teardown(&iev, TEST_END); + CHECK(imsgev_regress_calls(IMSGEV_REGRESS_COMPOSE) == 1); + CHECK(imsgev_regress_calls(IMSGEV_REGRESS_FLUSH) == 1); + CHECK(imsgev_regress_calls(IMSGEV_REGRESS_EVENT_ADD) == 0); + CHECK(imsgev_regress_calls(IMSGEV_REGRESS_EVENT_DEL) == 0); + CHECK(imsgbuf_read(&receiver) == 1); + CHECK(imsgbuf_get(&receiver, &imsg) == 1 && + imsg.hdr.type == TEST_END && imsg_get_len(&imsg) == 0); + imsg_free(&imsg); + channel_clear(&iev, &receiver, fds); + + channel_init(&iev, &receiver, fds); + imsgev_regress_reset(); + imsgev_regress_fail(IMSGEV_REGRESS_COMPOSE, 1); + imsgev_send_teardown(&iev, TEST_END); + CHECK(imsgev_regress_calls(IMSGEV_REGRESS_COMPOSE) == 1); + CHECK(imsgev_regress_calls(IMSGEV_REGRESS_FLUSH) == 0); + CHECK(imsgev_regress_calls(IMSGEV_REGRESS_EVENT_ADD) == 0); + CHECK(imsgev_regress_calls(IMSGEV_REGRESS_EVENT_DEL) == 0); + channel_clear(&iev, &receiver, fds); + + channel_init(&iev, &receiver, fds); + imsgev_regress_reset(); + imsgev_regress_fail(IMSGEV_REGRESS_FLUSH, 1); + imsgev_send_teardown(&iev, TEST_END); + CHECK(imsgev_regress_calls(IMSGEV_REGRESS_COMPOSE) == 1); + CHECK(imsgev_regress_calls(IMSGEV_REGRESS_FLUSH) == 1); + CHECK(imsgev_regress_calls(IMSGEV_REGRESS_EVENT_ADD) == 0); + CHECK(imsgev_regress_calls(IMSGEV_REGRESS_EVENT_DEL) == 0); + channel_clear(&iev, &receiver, fds); + REGRESS_END(); } blob - /dev/null blob + 12829ba9ecd954ba6f7469ad64678f1a2ff6585e (mode 644) --- /dev/null +++ regress/imsgev/imsgev_regress.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2026 Isaac + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Compile the production implementation against regression-private + * transport adapters. The public imsgev Interface stays free of failure + * injection while this internal seam can force every checked operation. + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include "imsgev.h" +#include "imsgev_regress.h" + +static struct { + enum imsgev_regress_op fail_op; + unsigned int fail_at; + unsigned int calls[IMSGEV_REGRESS_OPS]; + int trace_fd; +} regress_state = { + .fail_op = IMSGEV_REGRESS_OPS, + .trace_fd = -1 +}; + +void +imsgev_regress_reset(void) +{ + memset(regress_state.calls, 0, sizeof(regress_state.calls)); + regress_state.fail_op = IMSGEV_REGRESS_OPS; + regress_state.fail_at = 0; + regress_state.trace_fd = -1; +} + +void +imsgev_regress_fail(enum imsgev_regress_op op, unsigned int call) +{ + regress_state.fail_op = op; + regress_state.fail_at = call; +} + +void +imsgev_regress_trace(int fd) +{ + regress_state.trace_fd = fd; +} + +unsigned int +imsgev_regress_calls(enum imsgev_regress_op op) +{ + return (regress_state.calls[op]); +} + +static int +regress_fails(enum imsgev_regress_op op) +{ + regress_state.calls[op]++; + if (regress_state.fail_op == op && + regress_state.calls[op] == regress_state.fail_at) { + errno = EIO; + return (1); + } + return (0); +} + +static int +regress_imsg_compose(struct imsgbuf *ibuf, uint32_t type, uint32_t id, + pid_t pid, int fd, const void *data, size_t len) +{ + ssize_t n; + + if (regress_state.trace_fd != -1) { + n = write(regress_state.trace_fd, &type, sizeof(type)); + if (n != (ssize_t)sizeof(type)) { + errno = EIO; + return (-1); + } + } + if (regress_fails(IMSGEV_REGRESS_COMPOSE)) + return (-1); + return (imsg_compose(ibuf, type, id, pid, fd, data, len)); +} + +static int +regress_imsgbuf_flush(struct imsgbuf *ibuf) +{ + if (regress_fails(IMSGEV_REGRESS_FLUSH)) + return (-1); + return (imsgbuf_flush(ibuf)); +} + +static int +regress_event_add(struct event *ev, const struct timeval *tv) +{ + if (regress_fails(IMSGEV_REGRESS_EVENT_ADD)) + return (-1); + return (event_add(ev, tv)); +} + +static int +regress_event_del(struct event *ev) +{ + if (regress_fails(IMSGEV_REGRESS_EVENT_DEL)) + return (-1); + return (event_del(ev)); +} + +#define imsg_compose regress_imsg_compose +#define imsgbuf_flush regress_imsgbuf_flush +#define event_add regress_event_add +#define event_del regress_event_del + +#include "../../src/common/imsgev.c" + +#undef imsg_compose +#undef imsgbuf_flush +#undef event_add +#undef event_del blob - /dev/null blob + 5feb4bd80968781b2a2b5843315aae47adfcd4fd (mode 644) --- /dev/null +++ regress/imsgev/imsgev_regress.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2026 Isaac + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef IMSGEV_REGRESS_H +#define IMSGEV_REGRESS_H + +enum imsgev_regress_op { + IMSGEV_REGRESS_COMPOSE, + IMSGEV_REGRESS_FLUSH, + IMSGEV_REGRESS_EVENT_ADD, + IMSGEV_REGRESS_EVENT_DEL, + IMSGEV_REGRESS_OPS +}; + +void imsgev_regress_reset(void); +void imsgev_regress_fail(enum imsgev_regress_op, unsigned int); +void imsgev_regress_trace(int); +unsigned int imsgev_regress_calls(enum imsgev_regress_op); + +#endif /* IMSGEV_REGRESS_H */ blob - eae76c222a9645b9bd3757daa9fcf0204a9b45c7 blob + a871534c0365bae20aa5ea5ee4e649d5bc73f8dd --- src/common/imsgev.c +++ src/common/imsgev.c @@ -35,7 +35,8 @@ imsgev_init(struct imsgev *iev, int fd, iev->data = data; iev->events = EV_READ; event_set(&iev->ev, fd, iev->events, handler, data); - event_add(&iev->ev, NULL); + if (event_add(&iev->ev, NULL) == -1) + fatal("event_add"); } /* @@ -49,23 +50,35 @@ imsgev_add(struct imsgev *iev) if (imsgbuf_queuelen(&iev->ibuf) > 0) iev->events |= EV_WRITE; - event_del(&iev->ev); + if (event_del(&iev->ev) == -1) + fatal("event_del"); event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev->data); - event_add(&iev->ev, NULL); + if (event_add(&iev->ev, NULL) == -1) + fatal("event_add"); } -int -imsgev_compose(struct imsgev *iev, uint32_t type, uint32_t peerid, - pid_t pid, int fd, const void *data, size_t datalen) +void +imsgev_send(struct imsgev *iev, uint32_t type, uint32_t peerid, + const void *data, size_t datalen) { - int ret; + if (imsg_compose(&iev->ibuf, type, peerid, -1, -1, data, + datalen) == -1) + fatal("imsg_compose"); + imsgev_add(iev); +} - ret = imsg_compose(&iev->ibuf, type, peerid, pid, fd, - data, datalen); - if (ret != -1) - imsgev_add(iev); - return (ret); +/* + * Teardown has no event-loop future in which queued output can drain. + * Attempt one synchronous empty frame and flush, but never turn cleanup + * failure into a second fatal path while the Role is already exiting. + */ +void +imsgev_send_teardown(struct imsgev *iev, uint32_t type) +{ + if (imsg_compose(&iev->ibuf, type, 0, -1, -1, NULL, 0) == -1) + return; + (void)imsgbuf_flush(&iev->ibuf); } int @@ -99,6 +112,7 @@ imsgev_get_payload(struct imsg *imsg, struct imsgev_pa void imsgev_clear(struct imsgev *iev) { - event_del(&iev->ev); + if (event_del(&iev->ev) == -1) + fatal("event_del"); imsgbuf_clear(&iev->ibuf); } blob - c19e3d504553e550f77a3268b8d2a63617840730 blob + 17920eec05b8c5a24a21b4d3d47c72941dd0298f --- src/common/imsgev.h +++ src/common/imsgev.h @@ -46,8 +46,11 @@ struct imsgev_payload { void imsgev_init(struct imsgev *, int, void (*)(int, short, void *), void *); void imsgev_add(struct imsgev *); -int imsgev_compose(struct imsgev *, uint32_t, uint32_t, pid_t, int, - const void *, size_t); +/* Normal sends are checked and own the no-fd/no-pid transport policy. */ +void imsgev_send(struct imsgev *, uint32_t, uint32_t, const void *, + size_t); +/* Teardown attempts one synchronous empty frame without re-arming events. */ +void imsgev_send_teardown(struct imsgev *, uint32_t); int imsgev_get_payload(struct imsg *, struct imsgev_payload *); void imsgev_clear(struct imsgev *); blob - fb18c42b8dae64d769db946ee08450cff6456cce blob + 3bec9f667fc5ff3e063fd8573fc16846cb499c22 --- src/common/worker.c +++ src/common/worker.c @@ -114,7 +114,7 @@ selftest(int action) /* If we are still alive, the action was not pledge-killed; * report the syscall outcome for the test to judge. */ - imsgev_compose(&worker->iev, FUGU_IMSG_SELFTEST_RESULT, 0, -1, -1, + imsgev_send(&worker->iev, FUGU_IMSG_SELFTEST_RESULT, 0, &r, sizeof(r)); } @@ -177,14 +177,10 @@ worker_dispatch(int fd, short event, void *arg) if (w->lockdown(w, &imsg) == -1) fatalx("%s: lockdown failed", w->title); w->ready = 1; - if (imsgev_compose(&w->iev, FUGU_IMSG_READY, 0, -1, - -1, NULL, 0) == -1) - fatal("compose READY"); + imsgev_send(&w->iev, FUGU_IMSG_READY, 0, NULL, 0); break; case FUGU_IMSG_PING: - if (imsgev_compose(&w->iev, FUGU_IMSG_PONG, 0, -1, - -1, NULL, 0) == -1) - fatal("compose PONG"); + imsgev_send(&w->iev, FUGU_IMSG_PONG, 0, NULL, 0); break; case FUGU_IMSG_LOG_SYSLOG: if (imsg_get_len(&imsg) != 0) blob - 6a041592b8100a7964a10178d9a337589172090f blob + 23e224028b672b78a69570779b65f39049b5ca2e --- src/fugu/coord.c +++ src/fugu/coord.c @@ -357,9 +357,7 @@ tool_turn_ctl(struct coord *c, uint32_t type) fatalx("nested tool Turn control"); c->tool_ctl_expected = type; c->tool_ctl_done = 0; - if (imsgev_compose(&c->iev[ROLE_TOOL], type, 0, -1, -1, - NULL, 0) == -1) - fatal("compose tool Turn control"); + imsgev_send(&c->iev[ROLE_TOOL], type, 0, NULL, 0); while (!c->tool_ctl_done) { c->wait = WAIT_TOOL_CTL; rc = event_dispatch(); @@ -668,9 +666,7 @@ send_tool_hello(struct coord *c, struct imsgev *iev, i h.agent = agent; h.protect_snapshot = 1; h.protect_len = c->protect_len; - if (imsgev_compose(iev, FUGU_IMSG_HELLO, 0, -1, -1, &h, - sizeof(h)) == -1) - fatal("compose tool HELLO"); + imsgev_send(iev, FUGU_IMSG_HELLO, 0, &h, sizeof(h)); } static void @@ -686,9 +682,7 @@ send_hello(struct coord *c, enum fugu_role role) h.cols = 80; h.rows = 24; h.curses = c->ui; /* only start curses in terminal mode */ - if (imsgev_compose(iev, FUGU_IMSG_HELLO, 0, -1, -1, &h, - sizeof(h)) == -1) - fatal("compose tty HELLO"); + imsgev_send(iev, FUGU_IMSG_HELLO, 0, &h, sizeof(h)); break; } case ROLE_API: { @@ -714,11 +708,7 @@ send_hello(struct coord *c, enum fugu_role role) buf_add(&b, &h, sizeof(h)); if (key != NULL) buf_add(&b, key, strlen(key)); - if (imsgev_compose(iev, FUGU_IMSG_HELLO, 0, -1, -1, b.data, - b.len) == -1) { - buf_freezero(&b); - fatal("compose api HELLO"); - } + imsgev_send(iev, FUGU_IMSG_HELLO, 0, b.data, b.len); buf_freezero(&b); /* the key traversed this buffer */ /* every named provider block follows: the custodian holds @@ -745,11 +735,7 @@ send_hello(struct coord *c, enum fugu_role role) buf_add(&b, &hp, sizeof(hp)); if (fp->api_key != NULL) buf_add(&b, fp->api_key, strlen(fp->api_key)); - if (imsgev_compose(iev, FUGU_IMSG_PROV, 0, -1, -1, - b.data, b.len) == -1) { - buf_freezero(&b); - fatal("compose provider"); - } + imsgev_send(iev, FUGU_IMSG_PROV, 0, b.data, b.len); buf_freezero(&b); } if (c->conf->initial_provider_slot > 0) { @@ -757,9 +743,8 @@ send_hello(struct coord *c, enum fugu_role role) memset(&sel, 0, sizeof(sel)); sel.slot = c->conf->initial_provider_slot; - if (imsgev_compose(iev, FUGU_IMSG_SET_PROVIDER, 0, -1, - -1, &sel, sizeof(sel)) == -1) - fatal("compose initial provider"); + imsgev_send(iev, FUGU_IMSG_SET_PROVIDER, 0, &sel, + sizeof(sel)); } break; } @@ -794,16 +779,12 @@ send_hello(struct coord *c, enum fugu_role role) buf_add(&b, token, h.tokenlen); buf_add(&b, allow, h.allowlen); buf_add(&b, block, h.blocklen); - if (imsgev_compose(iev, FUGU_IMSG_HELLO, 0, -1, -1, - b.data, b.len) == -1) - fatal("compose web HELLO"); + imsgev_send(iev, FUGU_IMSG_HELLO, 0, b.data, b.len); buf_freezero(&b); break; } case ROLE_EDIT: - if (imsgev_compose(iev, FUGU_IMSG_HELLO, 0, -1, -1, - NULL, 0) == -1) - fatal("compose editor HELLO"); + imsgev_send(iev, FUGU_IMSG_HELLO, 0, NULL, 0); break; case ROLE_TOOL: { send_tool_hello(c, iev, 0); @@ -835,7 +816,7 @@ tcall_at(struct coord *c, int index) static void ui_send(struct coord *c, int type, const void *p, size_t len) { - imsgev_compose(&c->iev[ROLE_TTY], type, 0, -1, -1, p, len); + imsgev_send(&c->iev[ROLE_TTY], type, 0, p, len); } static void @@ -1622,8 +1603,8 @@ ui_event(struct coord *c, struct imsg *imsg) c->conf->provider_type = fp->type; } else fatalx("bad provider slot"); - imsgev_compose(&c->iev[ROLE_API], FUGU_IMSG_SET_PROVIDER, 0, - -1, -1, &sel, sizeof(sel)); + imsgev_send(&c->iev[ROLE_API], FUGU_IMSG_SET_PROVIDER, 0, + &sel, sizeof(sel)); c->active_provider_slot = sel.slot; c->provider_window = sel.context_window; free(c->conf->model); @@ -1740,13 +1721,11 @@ compose_event(struct coord *c, struct imsg *imsg) if (c->compose_in + len > FUGU_EDIT_MAX) fatalx("compose seed overrun"); c->compose_in += len; - imsgev_compose(&c->iev[ROLE_EDIT], FUGU_IMSG_EDIT_SEED, 0, - -1, -1, p, len); + imsgev_send(&c->iev[ROLE_EDIT], FUGU_IMSG_EDIT_SEED, 0, p, len); break; case FUGU_IMSG_UI_COMPOSE_GO: c->compose_in = 0; - imsgev_compose(&c->iev[ROLE_EDIT], FUGU_IMSG_EDIT_RUN, 0, - -1, -1, NULL, 0); + imsgev_send(&c->iev[ROLE_EDIT], FUGU_IMSG_EDIT_RUN, 0, NULL, 0); break; case FUGU_IMSG_EDIT_DATA: if (len == 0) @@ -1832,14 +1811,10 @@ agent_web_local_error(struct subagent *a, const char * if (a->done) return; - if (imsgev_compose(&a->iev, FUGU_IMSG_AGENT_WEB_OUT, 0, -1, -1, - s, strlen(s)) == -1) - fatal("compose subagent web local error"); + imsgev_send(&a->iev, FUGU_IMSG_AGENT_WEB_OUT, 0, s, strlen(s)); memset(&r, 0, sizeof(r)); r.is_error = 1; - if (imsgev_compose(&a->iev, FUGU_IMSG_AGENT_WEB_RESULT, 0, -1, -1, - &r, sizeof(r)) == -1) - fatal("compose subagent web local result"); + imsgev_send(&a->iev, FUGU_IMSG_AGENT_WEB_RESULT, 0, &r, sizeof(r)); } static void @@ -1867,23 +1842,19 @@ agent_web_start_next(struct coord *c) a->web_inflight = 1; c->agent_web_active = a; c->web_busy_id = a->web_id; - if (imsgev_compose(&c->iev[ROLE_WEB], FUGU_IMSG_WEB_REQ, - a->web_id, -1, -1, &req, sizeof(req)) == -1) - fatal("relay subagent WEB_REQ"); + imsgev_send(&c->iev[ROLE_WEB], FUGU_IMSG_WEB_REQ, + a->web_id, &req, sizeof(req)); for (off = 0; off < a->web_arg.len; ) { size_t k = a->web_arg.len - off; if (k > FUGU_CHUNK) k = FUGU_CHUNK; - if (imsgev_compose(&c->iev[ROLE_WEB], - FUGU_IMSG_WEB_ARG, a->web_id, -1, -1, - a->web_arg.data + off, k) == -1) - fatal("relay subagent WEB_ARG"); + imsgev_send(&c->iev[ROLE_WEB], FUGU_IMSG_WEB_ARG, + a->web_id, a->web_arg.data + off, k); off += k; } - if (imsgev_compose(&c->iev[ROLE_WEB], FUGU_IMSG_WEB_RUN, - a->web_id, -1, -1, NULL, 0) == -1) - fatal("relay subagent WEB_RUN"); + imsgev_send(&c->iev[ROLE_WEB], FUGU_IMSG_WEB_RUN, + a->web_id, NULL, 0); agent_web_arg_free(c, a); return; } @@ -1903,8 +1874,8 @@ agent_provider_event(struct subagent *a, struct imsg * fatal("get relayed provider payload"); p = payload.data; len = payload.len; - if (!a->done && imsgev_compose(&a->iev, type, 0, -1, -1, p, len) == -1) - fatal("relay provider event to subagent"); + if (!a->done) + imsgev_send(&a->iev, type, 0, p, len); if (type == FUGU_IMSG_A_DONE || type == FUGU_IMSG_A_ERROR) a->api_inflight = 0; if (a->coord->wait == WAIT_AGENTS && agents_settled(a->coord)) @@ -1933,9 +1904,8 @@ agent_web_event(struct subagent *a, struct imsg *imsg) outtype = FUGU_IMSG_AGENT_WEB_RESULT; else fatalx("bad subagent web event"); - if (!a->done && imsgev_compose(&a->iev, outtype, 0, -1, -1, p, - len) == -1) - fatal("relay web event to subagent"); + if (!a->done) + imsgev_send(&a->iev, outtype, 0, p, len); if (outtype == FUGU_IMSG_AGENT_WEB_RESULT) { a->web_inflight = 0; a->web_id = 0; @@ -2010,10 +1980,8 @@ coord_dispatch(int fd, short event, void *arg) log_init(LOG_TO_SYSLOG, coord->verbose, LOG_DAEMON); for (r = ROLE_TTY; r < ROLE_MAX; r++) - if (imsgev_compose(&coord->iev[r], - FUGU_IMSG_LOG_SYSLOG, 0, -1, -1, - NULL, 0) == -1) - fatal("compose LOG_SYSLOG"); + imsgev_send(&coord->iev[r], + FUGU_IMSG_LOG_SYSLOG, 0, NULL, 0); } if (++coord->nready == coord->nkids) event_loopexit(NULL); @@ -2121,13 +2089,13 @@ send_request(struct coord *c, struct buf *body, uint32 if (n > FUGU_CHUNK) n = FUGU_CHUNK; - imsgev_compose(iev, FUGU_IMSG_REQUEST, id, -1, -1, + imsgev_send(iev, FUGU_IMSG_REQUEST, id, body->data + off, n); off += n; } memset(&end, 0, sizeof(end)); end.provider_slot = provider_slot; - imsgev_compose(iev, FUGU_IMSG_REQUEST_END, id, -1, -1, &end, + imsgev_send(iev, FUGU_IMSG_REQUEST_END, id, &end, sizeof(end)); } @@ -2141,17 +2109,17 @@ run_tool(struct coord *c, struct tool_call *tc) memset(&req, 0, sizeof(req)); strlcpy(req.name, tc->name, sizeof(req.name)); - imsgev_compose(iev, FUGU_IMSG_TOOL_REQ, 0, -1, -1, &req, sizeof(req)); + imsgev_send(iev, FUGU_IMSG_TOOL_REQ, 0, &req, sizeof(req)); for (off = 0; off < tc->input.len; ) { size_t n = tc->input.len - off; if (n > FUGU_CHUNK) n = FUGU_CHUNK; - imsgev_compose(iev, FUGU_IMSG_TOOL_ARG, 0, -1, -1, + imsgev_send(iev, FUGU_IMSG_TOOL_ARG, 0, tc->input.data + off, n); off += n; } - imsgev_compose(iev, FUGU_IMSG_TOOL_RUN, 0, -1, -1, NULL, 0); + imsgev_send(iev, FUGU_IMSG_TOOL_RUN, 0, NULL, 0); buf_reset(&c->tool_out); buf_reset(&c->diff); @@ -2195,22 +2163,17 @@ run_web(struct coord *c, struct tool_call *tc) strlcpy(req.name, tc->name, sizeof(req.name)); c->web_id = agent_unique_id(c); c->web_busy_id = c->web_id; - if (imsgev_compose(iev, FUGU_IMSG_WEB_REQ, c->web_id, -1, -1, &req, - sizeof(req)) == -1) - fatal("compose WEB_REQ"); + imsgev_send(iev, FUGU_IMSG_WEB_REQ, c->web_id, &req, sizeof(req)); for (off = 0; off < tc->input.len; ) { size_t n = tc->input.len - off; if (n > FUGU_CHUNK) n = FUGU_CHUNK; - if (imsgev_compose(iev, FUGU_IMSG_WEB_ARG, c->web_id, -1, -1, - tc->input.data + off, n) == -1) - fatal("compose WEB_ARG"); + imsgev_send(iev, FUGU_IMSG_WEB_ARG, c->web_id, + tc->input.data + off, n); off += n; } - if (imsgev_compose(iev, FUGU_IMSG_WEB_RUN, c->web_id, -1, -1, - NULL, 0) == -1) - fatal("compose WEB_RUN"); + imsgev_send(iev, FUGU_IMSG_WEB_RUN, c->web_id, NULL, 0); c->wait = WAIT_WEB; rc = event_dispatch(); @@ -2241,10 +2204,8 @@ agent_failed(struct subagent *a, const char *reason) agent_web_arg_free(c, a); } if (a->api_assembling || a->api_inflight) { - if (imsgev_compose(&c->iev[ROLE_API], - FUGU_IMSG_REQUEST_CANCEL, a->api_id, -1, -1, - NULL, 0) == -1) - fatal("compose failed-agent REQUEST_CANCEL"); + imsgev_send(&c->iev[ROLE_API], FUGU_IMSG_REQUEST_CANCEL, + a->api_id, NULL, 0); a->api_assembling = 0; a->api_inflight = 1; /* cleared by the cancellation terminal */ } @@ -2340,9 +2301,8 @@ agent_dispatch(int fd, short event, void *arg) fatalx("bad subagent provider request chunk"); a->api_assembling = 1; a->request_bytes += len; - if (imsgev_compose(&c->iev[ROLE_API], FUGU_IMSG_REQUEST, - a->api_id, -1, -1, p, len) == -1) - fatal("relay subagent provider request"); + imsgev_send(&c->iev[ROLE_API], FUGU_IMSG_REQUEST, + a->api_id, p, len); break; case FUGU_IMSG_AGENT_REQUEST_END: { struct api_request_end end; @@ -2351,10 +2311,8 @@ agent_dispatch(int fd, short event, void *arg) fatalx("bad subagent provider request end"); memset(&end, 0, sizeof(end)); end.provider_slot = a->provider_slot; - if (imsgev_compose(&c->iev[ROLE_API], - FUGU_IMSG_REQUEST_END, a->api_id, -1, -1, &end, - sizeof(end)) == -1) - fatal("relay subagent request end"); + imsgev_send(&c->iev[ROLE_API], FUGU_IMSG_REQUEST_END, + a->api_id, &end, sizeof(end)); a->api_assembling = 0; a->api_inflight = 1; a->request_bytes = 0; @@ -2524,7 +2482,7 @@ read_personal(struct coord *c) static void ctx_read_project(struct coord *c, const char *path) { - imsgev_compose(&c->iev[ROLE_TOOL], FUGU_IMSG_CTX_READ, 0, -1, -1, + imsgev_send(&c->iev[ROLE_TOOL], FUGU_IMSG_CTX_READ, 0, path, strlen(path)); buf_reset(&c->ctx_data); c->ctx_done = 0; @@ -2959,8 +2917,7 @@ agent_compose_bytes(struct imsgev *iev, uint32_t type, n = len - off; if (n > FUGU_CHUNK) n = FUGU_CHUNK; - if (imsgev_compose(iev, type, 0, -1, -1, p + off, n) == -1) - fatal("compose subagent launch bytes"); + imsgev_send(iev, type, 0, p + off, n); } } @@ -2982,17 +2939,13 @@ agent_start(struct coord *c, struct subagent *a, const buf_addc(&b, '\0'); buf_addstr(&b, a->label); buf_addc(&b, '\0'); - if (imsgev_compose(&a->iev, FUGU_IMSG_AGENT_START, 0, -1, -1, - b.data, b.len) == -1) - fatal("compose AGENT_START"); + imsgev_send(&a->iev, FUGU_IMSG_AGENT_START, 0, b.data, b.len); buf_free(&b); agent_compose_bytes(&a->iev, FUGU_IMSG_AGENT_SYSTEM, system->data, system->len); agent_compose_bytes(&a->iev, FUGU_IMSG_AGENT_PROMPT, a->prompt.data, a->prompt.len); - if (imsgev_compose(&a->iev, FUGU_IMSG_AGENT_RUN, 0, -1, -1, - NULL, 0) == -1) - fatal("compose AGENT_RUN"); + imsgev_send(&a->iev, FUGU_IMSG_AGENT_RUN, 0, NULL, 0); } static void @@ -3012,10 +2965,8 @@ agent_wave_cleanup(struct coord *c, int cancel) if (cancel && (a->api_assembling || a->api_inflight)) { cancelled_id_add(c->cancelled_api, &c->ncancelled_api, a->api_id); - if (imsgev_compose(&c->iev[ROLE_API], - FUGU_IMSG_REQUEST_CANCEL, a->api_id, -1, -1, - NULL, 0) == -1) - fatal("compose subagent REQUEST_CANCEL"); + imsgev_send(&c->iev[ROLE_API], FUGU_IMSG_REQUEST_CANCEL, + a->api_id, NULL, 0); a->api_assembling = 0; a->api_inflight = 0; } @@ -3038,9 +2989,8 @@ agent_wave_cleanup(struct coord *c, int cancel) } if (a->kid.fd >= 0) { if (cancel) { - (void)imsgev_compose(&a->iev, FUGU_IMSG_SHUTDOWN, 0, - -1, -1, NULL, 0); - (void)imsgbuf_flush(&a->iev.ibuf); + imsgev_send_teardown(&a->iev, + FUGU_IMSG_SHUTDOWN); (void)kill(a->kid.pid, SIGTERM); } imsgev_clear(&a->iev); @@ -3628,7 +3578,7 @@ cmd_capture(struct coord *c, const char *text) buf_addstr(&m, "\n- "); buf_addstr(&m, text); buf_addc(&m, '\n'); - imsgev_compose(&c->iev[ROLE_TOOL], FUGU_IMSG_CTX_APPEND, 0, -1, -1, + imsgev_send(&c->iev[ROLE_TOOL], FUGU_IMSG_CTX_APPEND, 0, m.data, m.len); buf_free(&m); @@ -3784,8 +3734,8 @@ line_command(struct coord *c, const char *line, int *t c->listed_models = NULL; c->nlisted_models = 0; c->models_collecting = 1; - imsgev_compose(&c->iev[ROLE_API], - FUGU_IMSG_LIST_MODELS, 0, -1, -1, NULL, 0); + imsgev_send(&c->iev[ROLE_API], + FUGU_IMSG_LIST_MODELS, 0, NULL, 0); emit_note(c, "fetching the model list..."); } else fprintf(stderr, "fugu: /model is interactive-only\n"); @@ -4036,9 +3986,7 @@ coord_teardown(struct coord *c) for (role = ROLE_TTY; role < ROLE_MAX; role++) { if (c->kids[role].pid <= 0) continue; - (void)imsgev_compose(&c->iev[role], FUGU_IMSG_SHUTDOWN, 0, - -1, -1, NULL, 0); - (void)imsgbuf_flush(&c->iev[role].ibuf); + imsgev_send_teardown(&c->iev[role], FUGU_IMSG_SHUTDOWN); } /* Give cooperative workers time to dispatch SHUTDOWN and run atexit. * In particular fugu-tty must restore termios/bracketed paste before a blob - 2935e1ff82c36ffc61949854b34bf9e6fe29eda1 blob + c6f79ced52336f1652d68757b1b3409f1ade861f --- src/fugu-api/main.c +++ src/fugu-api/main.c @@ -591,8 +591,7 @@ static void relay_id(struct worker *w, uint32_t id, uint32_t type, const void *data, size_t len) { - if (imsgev_compose(&w->iev, type, id, -1, -1, data, len) == -1) - fatal("compose provider event"); + imsgev_send(&w->iev, type, id, data, len); } static void blob - 7840fd7766fb54edcb5b70b8462764f98d184973 blob + a8a09dd372615a9daec10e4c7d8ee5ac4e2ecfdf --- src/fugu-editor/main.c +++ src/fugu-editor/main.c @@ -111,9 +111,7 @@ send_result(struct worker *w, int ok, int reason) memset(&r, 0, sizeof(r)); r.ok = ok; r.reason = reason; - if (imsgev_compose(&w->iev, FUGU_IMSG_EDIT_RESULT, 0, -1, -1, &r, - sizeof(r)) == -1) - fatal("compose EDIT_RESULT"); + imsgev_send(&w->iev, FUGU_IMSG_EDIT_RESULT, 0, &r, sizeof(r)); } /* @@ -285,9 +283,8 @@ compose(struct worker *w) send_result(w, 0, EDIT_R_OVERSIZE); return; } - if (imsgev_compose(&w->iev, FUGU_IMSG_EDIT_DATA, 0, -1, -1, - tmp, (size_t)n) == -1) - fatal("compose EDIT_DATA"); + imsgev_send(&w->iev, FUGU_IMSG_EDIT_DATA, 0, tmp, + (size_t)n); sent += (size_t)n; } close(fd); blob - 2f07ba49a039d9992f3210584cd7ced3f6ef9042 blob + 07b7f6d8e57a4e1802416d7fe25b7a3b420d0546 --- src/fugu-tool/main.c +++ src/fugu-tool/main.c @@ -365,7 +365,7 @@ send_result(struct worker *w, const struct buf *out, c if (n > FUGU_CHUNK) n = FUGU_CHUNK; - imsgev_compose(&w->iev, FUGU_IMSG_TOOL_OUT, 0, -1, -1, + imsgev_send(&w->iev, FUGU_IMSG_TOOL_OUT, 0, out->data + off, n); off += n; } @@ -375,13 +375,13 @@ send_result(struct worker *w, const struct buf *out, c if (n > FUGU_CHUNK) n = FUGU_CHUNK; - imsgev_compose(&w->iev, FUGU_IMSG_TOOL_DIFF, 0, -1, -1, + imsgev_send(&w->iev, FUGU_IMSG_TOOL_DIFF, 0, diff->data + off, n); off += n; } memset(&r, 0, sizeof(r)); r.is_error = is_error; - imsgev_compose(&w->iev, FUGU_IMSG_TOOL_RESULT, 0, -1, -1, &r, + imsgev_send(&w->iev, FUGU_IMSG_TOOL_RESULT, 0, &r, sizeof(r)); } @@ -443,9 +443,8 @@ tool_dispatch(struct worker *w, struct imsg *imsg) if (type == FUGU_IMSG_TOOL_TURN_ABORT) cancel_tool = 0; ack.control = type; - if (imsgev_compose(&w->iev, FUGU_IMSG_TOOL_TURN_ACK, 0, - -1, -1, &ack, sizeof(ack)) == -1) - fatal("compose TURN_ACK"); + imsgev_send(&w->iev, FUGU_IMSG_TOOL_TURN_ACK, 0, &ack, + sizeof(ack)); return (0); } case FUGU_IMSG_TOOL_REQ: { @@ -496,11 +495,11 @@ tool_dispatch(struct worker *w, struct imsg *imsg) if (k > FUGU_CHUNK) k = FUGU_CHUNK; - imsgev_compose(&w->iev, FUGU_IMSG_CTX_DATA, 0, -1, -1, + imsgev_send(&w->iev, FUGU_IMSG_CTX_DATA, 0, ctx.data + off, k); off += k; } - imsgev_compose(&w->iev, FUGU_IMSG_CTX_END, 0, -1, -1, NULL, 0); + imsgev_send(&w->iev, FUGU_IMSG_CTX_END, 0, NULL, 0); buf_free(&ctx); return (0); } @@ -522,7 +521,7 @@ tool_dispatch(struct worker *w, struct imsg *imsg) r.reason = ctx_file_append(ts->ctx, path, bytes, len - plen - 1); r.ok = (r.reason == 0); - imsgev_compose(&w->iev, FUGU_IMSG_CTX_RESULT, 0, -1, -1, &r, + imsgev_send(&w->iev, FUGU_IMSG_CTX_RESULT, 0, &r, sizeof(r)); return (0); } blob - a3bfff69f738ee02517ed6fd50a3bd136efdecc8 blob + 5606c58654257e575fb61aaa0b53c773f7495e87 --- src/fugu-tty/ui.c +++ src/fugu-tty/ui.c @@ -901,10 +901,10 @@ send_chunked(struct ui *u, int chunk_type, int end_typ if (n > FUGU_CHUNK) n = FUGU_CHUNK; - imsgev_compose(&u->w->iev, chunk_type, 0, -1, -1, p + off, n); + imsgev_send(&u->w->iev, chunk_type, 0, p + off, n); off += n; } - imsgev_compose(&u->w->iev, end_type, 0, -1, -1, NULL, 0); + imsgev_send(&u->w->iev, end_type, 0, NULL, 0); } static void @@ -1007,11 +1007,11 @@ compose_begin(struct ui *u) if (n > FUGU_CHUNK) n = FUGU_CHUNK; - imsgev_compose(&u->w->iev, FUGU_IMSG_UI_COMPOSE, 0, -1, -1, + imsgev_send(&u->w->iev, FUGU_IMSG_UI_COMPOSE, 0, text + off, n); off += n; } - imsgev_compose(&u->w->iev, FUGU_IMSG_UI_COMPOSE_GO, 0, -1, -1, + imsgev_send(&u->w->iev, FUGU_IMSG_UI_COMPOSE_GO, 0, NULL, 0); u->composing = 1; } @@ -1066,8 +1066,8 @@ drawer_key(struct ui *u, enum ed_key k, uint32_t cp) break; case K_ENTER: if (u->drawer_sel == 0) { /* a fresh session */ - imsgev_compose(&u->w->iev, FUGU_IMSG_UI_SWITCH, 0, - -1, -1, NULL, 0); + imsgev_send(&u->w->iev, FUGU_IMSG_UI_SWITCH, 0, + NULL, 0); strlcpy(u->notice, "switching...", sizeof(u->notice)); } else { struct sess *s = &u->sess[u->drawer_sel - 1]; @@ -1076,8 +1076,8 @@ drawer_key(struct ui *u, enum ed_key k, uint32_t cp) drawer_close(u); break; } - imsgev_compose(&u->w->iev, FUGU_IMSG_UI_SWITCH, 0, - -1, -1, s->id, strlen(s->id)); + imsgev_send(&u->w->iev, FUGU_IMSG_UI_SWITCH, 0, + s->id, strlen(s->id)); strlcpy(u->notice, "switching...", sizeof(u->notice)); } break; @@ -1149,8 +1149,8 @@ pick_key(struct ui *u, enum ed_key k, uint32_t cp) buf_init(&b); buf_add(&b, &sel, sizeof(sel)); buf_addstr(&b, m->id); - imsgev_compose(&u->w->iev, FUGU_IMSG_UI_SELECT_MODEL, 0, - -1, -1, b.data, b.len); + imsgev_send(&u->w->iev, FUGU_IMSG_UI_SELECT_MODEL, 0, + b.data, b.len); buf_free(&b); pick_close(u); break; @@ -1246,7 +1246,7 @@ handle_result(struct ui *u, enum ed_result r) case R_QUIT: /* ask the coordinator to quit; it will send SHUTDOWN back, * which restores the terminal and exits cleanly */ - imsgev_compose(&u->w->iev, FUGU_IMSG_UI_QUIT, 0, -1, -1, + imsgev_send(&u->w->iev, FUGU_IMSG_UI_QUIT, 0, NULL, 0); break; case R_SCROLL_LINE_UP: scroll_by(u, -1); break; blob - efcc30a384f2600ea0ffd58567d501f97d1025dc blob + c2665884939d8193e3321c1b2f77f94048dae9bd --- src/fugu-web/main.c +++ src/fugu-web/main.c @@ -202,16 +202,13 @@ send_result(struct worker *w, uint32_t reqid, const st if (n > FUGU_CHUNK) n = FUGU_CHUNK; - if (imsgev_compose(&w->iev, FUGU_IMSG_WEB_OUT, reqid, -1, -1, - out->data + off, n) == -1) - fatal("compose WEB_OUT"); + imsgev_send(&w->iev, FUGU_IMSG_WEB_OUT, reqid, + out->data + off, n); off += n; } memset(&r, 0, sizeof(r)); r.is_error = is_error; - if (imsgev_compose(&w->iev, FUGU_IMSG_WEB_RESULT, reqid, -1, -1, &r, - sizeof(r)) == -1) - fatal("compose WEB_RESULT"); + imsgev_send(&w->iev, FUGU_IMSG_WEB_RESULT, reqid, &r, sizeof(r)); } static int