commit - 4913b479eed668b06a90b1c150b71065a6e2ce36
commit + bc10f6a5fcbae63627490a4c11e13a34b1c2525a
blob - cf5c375e1ddc25eb54258080abae9d56e86fede8
blob + d535286a058e3ccba133933c570bdaaea01fe5aa
--- ChangeLog
+++ ChangeLog
2021-07-12 Omar Polo <op@omarpolo.com>
+ * util.c (dispatch_imsg): refactor: all imsgs are completely asynchronous
+
* minibuffer.c (minibuffer_taint_hist): bugfix: allow editing minibuffer history
2021-07-10 Omar Polo <op@omarpolo.com>
blob - 963419e60ea0dd6f1e0c50729256dc3ed9d47f2e
blob + 881651984cd91e5d9f826a8a9a68219e43f3a436
--- fs.c
+++ fs.c
static void handle_session_tab(struct imsg*, size_t);
static void handle_session_end(struct imsg*, size_t);
static void handle_dispatch_imsg(int, short, void*);
+static int fs_send_ui(int, uint32_t, int, const void *, uint16_t);
-static struct event imsgev;
-static struct imsgbuf *ibuf;
-
+static struct imsgev *iev_ui;
static FILE *session;
static char bookmark_file[PATH_MAX];
t = "# Bookmarks\n\n"
"No bookmarks yet!\n"
"Create ~/.telescope/bookmarks.gmi or use `bookmark-page'.\n";
- imsg_compose(ibuf, IMSG_BUF, peerid, 0, -1, t, strlen(t));
- imsg_compose(ibuf, IMSG_EOF, peerid, 0, -1, NULL, 0);
- imsg_flush(ibuf);
+ fs_send_ui(IMSG_BUF, peerid, -1, t, strlen(t));
+ fs_send_ui(IMSG_EOF, peerid, -1, NULL, 0);
return;
}
for (;;) {
r = fread(buf, 1, sizeof(buf), f);
- imsg_compose(ibuf, IMSG_BUF, peerid, 0, -1, buf, r);
- imsg_flush(ibuf);
+ fs_send_ui(IMSG_BUF, peerid, -1, buf, r);
if (r != sizeof(buf))
break;
}
- imsg_compose(ibuf, IMSG_EOF, peerid, 0, -1, NULL, 0);
- imsg_flush(ibuf);
+ fs_send_ui(IMSG_EOF, peerid, -1, NULL, 0);
fclose(f);
}
static void
send_page(struct imsg *imsg, const char *page)
{
- imsg_compose(ibuf, IMSG_BUF, imsg->hdr.peerid, 0, -1,
- page, strlen(page));
- imsg_compose(ibuf, IMSG_EOF, imsg->hdr.peerid, 0, -1, NULL, 0);
- imsg_flush(ibuf);
+ fs_send_ui(IMSG_BUF, imsg->hdr.peerid, -1, page, strlen(page));
+ fs_send_ui(IMSG_EOF, imsg->hdr.peerid, -1, NULL, 0);
}
static void
send_page(imsg, about_new);
} else {
p = "# not found!\n";
- imsg_compose(ibuf, IMSG_BUF, imsg->hdr.peerid, 0, -1, p, strlen(p));
- imsg_compose(ibuf, IMSG_EOF, imsg->hdr.peerid, 0, -1, NULL, 0);
- imsg_flush(ibuf);
+ fs_send_ui(IMSG_BUF, imsg->hdr.peerid, -1, p, strlen(p));
+ fs_send_ui(IMSG_EOF, imsg->hdr.peerid, -1, NULL, 0);
}
}
res = 0;
end:
- imsg_compose(ibuf, IMSG_BOOKMARK_OK, 0, 0, -1, &res, sizeof(res));
- imsg_flush(ibuf);
+ fs_send_ui(IMSG_BOOKMARK_OK, 0, -1, &res, sizeof(res));
}
static void
res = 0;
end:
- imsg_compose(ibuf, IMSG_SAVE_CERT_OK, imsg->hdr.peerid, 0, -1,
+ fs_send_ui(IMSG_SAVE_CERT_OK, imsg->hdr.peerid, -1,
&res, sizeof(res));
- imsg_flush(ibuf);
}
static void
res = rename(sfn, known_hosts_file) != -1;
end:
- imsg_compose(ibuf, IMSG_UPDATE_CERT_OK, imsg->hdr.peerid, 0, -1,
+ fs_send_ui(IMSG_UPDATE_CERT_OK, imsg->hdr.peerid, -1,
&res, sizeof(res));
- imsg_flush(ibuf);
}
static void
if ((fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, 0644)) == -1) {
e = strerror(errno);
- imsg_compose(ibuf, IMSG_FILE_OPENED, imsg->hdr.peerid, 0, -1,
+ fs_send_ui(IMSG_FILE_OPENED, imsg->hdr.peerid, -1,
e, strlen(e)+1);
} else
- imsg_compose(ibuf, IMSG_FILE_OPENED, imsg->hdr.peerid, 0, fd,
+ fs_send_ui(IMSG_FILE_OPENED, imsg->hdr.peerid, fd,
NULL, 0);
-
- imsg_flush(ibuf);
}
static void
static void
handle_dispatch_imsg(int fd, short ev, void *d)
{
- struct imsgbuf *ibuf = d;
- dispatch_imsg(ibuf, handlers, sizeof(handlers));
+ struct imsgev *iev = d;
+ dispatch_imsg(iev, ev, handlers, sizeof(handlers));
}
+static int
+fs_send_ui(int type, uint32_t peerid, int fd, const void *data,
+ uint16_t datalen)
+{
+ return imsg_compose_event(iev_ui, type, peerid, 0, fd,
+ data, datalen);
+}
+
int
fs_init(void)
{
event_init();
- if ((ibuf = calloc(1, sizeof(*ibuf))) == NULL)
+ /* Setup pipe and event handler to the main process */
+ if ((iev_ui = malloc(sizeof(*iev_ui))) == NULL)
die();
- imsg_init(ibuf, 3);
- event_set(&imsgev, ibuf->fd, EV_READ | EV_PERSIST, handle_dispatch_imsg, ibuf);
- event_add(&imsgev, NULL);
+ imsg_init(&iev_ui->ibuf, 3);
+ iev_ui->handler = handle_dispatch_imsg;
+ iev_ui->events = EV_READ;
+ event_set(&iev_ui->ev, iev_ui->ibuf.fd, iev_ui->events,
+ iev_ui->handler, iev_ui);
+ event_add(&iev_ui->ev, NULL);
sandbox_fs_process();
blob - 65cfc482332d0226e5db475c9eeca9d9d607f5dd
blob + 80b58738cec69d9ab8eb9bca16c88a19139b2c70
--- gemini.c
+++ gemini.c
# include <asr.h>
#endif
-static struct event imsgev;
+static struct imsgev *iev_ui;
static struct tls_config *tlsconf;
-static struct imsgbuf *ibuf;
struct req;
static void handle_quit(struct imsg*, size_t);
static void handle_dispatch_imsg(int, short, void*);
+static int net_send_ui(int, uint32_t, const void *, uint16_t);
+
/* TODO: making this customizable */
struct timeval timeout_for_handshake = { 5, 0 };
static void
close_with_err(struct req *req, const char *err)
{
- imsg_compose(ibuf, IMSG_ERR, req->id, 0, -1, err, strlen(err)+1);
- imsg_flush(ibuf);
+ net_send_ui(IMSG_ERR, req->id, err, strlen(err)+1);
close_conn(0, 0, req);
}
close_with_errf(req, "handshake failed: %s", tls_error(req->ctx));
return;
}
- imsg_compose(ibuf, IMSG_CHECK_CERT, req->id, 0, -1, hash, strlen(hash)+1);
- imsg_flush(ibuf);
+ net_send_ui(IMSG_CHECK_CERT, req->id, hash, strlen(hash)+1);
}
static void
*e = '\0';
e++;
len = e - req->buf;
- imsg_compose(ibuf, IMSG_GOT_CODE, req->id, 0, -1, &code, sizeof(code));
- imsg_compose(ibuf, IMSG_GOT_META, req->id, 0, -1, req->buf, len);
- imsg_flush(ibuf);
+ net_send_ui(IMSG_GOT_CODE, req->id, &code, sizeof(code));
+ net_send_ui(IMSG_GOT_META, req->id, req->buf, len);
if (20 <= code && code < 30)
advance_buf(req, len+1); /* skip \n too */
for (;;) {
if (req->off != 0) {
- imsg_compose(ibuf, IMSG_BUF, req->id, 0, -1,
+ net_send_ui(IMSG_BUF, req->id,
req->buf, req->off);
- imsg_flush(ibuf);
req->off = 0;
}
yield_w(req, copy_body, NULL);
return;
case 0:
- imsg_compose(ibuf, IMSG_EOF, req->id, 0, -1, NULL, 0);
- imsg_flush(ibuf);
+ net_send_ui(IMSG_EOF, req->id, NULL, 0);
close_conn(0, 0, req);
return;
default:
static void
handle_dispatch_imsg(int fd, short ev, void *d)
{
- struct imsgbuf *ibuf = d;
- dispatch_imsg(ibuf, handlers, sizeof(handlers));
+ struct imsgev *iev = d;
+ dispatch_imsg(iev, ev, handlers, sizeof(handlers));
}
+static int
+net_send_ui(int type, uint32_t peerid, const void *data,
+ uint16_t datalen)
+{
+ return imsg_compose_event(iev_ui, type, peerid, 0, -1,
+ data, datalen);
+}
+
int
client_main(void)
{
event_init();
/* Setup pipe and event handler to the main process */
- if ((ibuf = calloc(1, sizeof(*ibuf))) == NULL)
+ if ((iev_ui = malloc(sizeof(*iev_ui))) == NULL)
die();
- imsg_init(ibuf, 3);
- event_set(&imsgev, ibuf->fd, EV_READ | EV_PERSIST, handle_dispatch_imsg, ibuf);
- event_add(&imsgev, NULL);
+ imsg_init(&iev_ui->ibuf, 3);
+ iev_ui->handler = handle_dispatch_imsg;
+ iev_ui->events = EV_READ;
+ event_set(&iev_ui->ev, iev_ui->ibuf.fd, iev_ui->events,
+ iev_ui->handler, iev_ui);
+ event_add(&iev_ui->ev, NULL);
sandbox_net_process();
blob - 3a5e9032c73ddc1d011e95b68f1361f62e2d7bbc
blob + 537ed46ae73149851e1f2ca7ec85fc37b1cc6dde
--- telescope.c
+++ telescope.c
#include "telescope.h"
#include "ui.h"
-struct event netev, fsev;
+static struct imsgev *iev_fs, *iev_net;
+
struct tabshead tabshead = TAILQ_HEAD_INITIALIZER(tabshead);
struct proxylist proxies = TAILQ_HEAD_INITIALIZER(proxies);
{ NULL, NULL },
};
-static struct imsgbuf *netibuf, *fsibuf;
-
static void die(void) __attribute__((__noreturn__));
static struct tab *tab_by_id(uint32_t);
static void handle_imsg_err(struct imsg*, size_t);
static void load_page_from_str(struct tab*, const char*);
static void do_load_url(struct tab*, const char*);
static pid_t start_child(enum telescope_process, const char *, int);
+static int ui_send_net(int, uint32_t, const void *, uint16_t);
+static int ui_send_fs(int, uint32_t, const void *, uint16_t);
static imsg_handlerfn *handlers[] = {
[IMSG_ERR] = handle_imsg_err,
}
strlcpy(e->hash, hash, sizeof(e->hash));
tofu_add(&certs, e);
- imsg_compose(fsibuf, IMSG_SAVE_CERT, tab->id, 0, -1,
- e, sizeof(*e));
- imsg_flush(fsibuf);
+ ui_send_fs(IMSG_SAVE_CERT, tab->id, e, sizeof(*e));
} else
tofu_res = !strcmp(hash, e->hash);
else
tab->trust = TS_TRUSTED;
- imsg_compose(netibuf, IMSG_CERT_STATUS, imsg->hdr.peerid, 0, -1,
+ ui_send_net(IMSG_CERT_STATUS, imsg->hdr.peerid,
&tofu_res, sizeof(tofu_res));
- imsg_flush(netibuf);
} else {
tab->trust = TS_UNTRUSTED;
load_page_from_str(tab, "# Certificate mismatch\n");
static void
handle_check_cert_user_choice(int accept, struct tab *tab)
{
- imsg_compose(netibuf, IMSG_CERT_STATUS, tab->id, 0, -1,
- &accept, sizeof(accept));
- imsg_flush(netibuf);
+ ui_send_net(IMSG_CERT_STATUS, tab->id, &accept,
+ sizeof(accept));
if (accept) {
/*
strlcat(e->domain, port, sizeof(e->domain));
}
strlcpy(e->hash, tab->cert, sizeof(e->hash));
- imsg_compose(fsibuf, IMSG_UPDATE_CERT, 0, 0, -1, e, sizeof(*e));
- imsg_flush(fsibuf);
+ ui_send_fs(IMSG_UPDATE_CERT, 0, e, sizeof(*e));
tofu_update(&certs, e);
ui_require_input(tab, tab->code == 11);
} else if (tab->code == 20) {
if (setup_parser_for(tab)) {
- imsg_compose(netibuf, IMSG_PROCEED, tab->id, 0, -1, NULL, 0);
- imsg_flush(netibuf);
+ ui_send_net(IMSG_PROCEED, tab->id, NULL, 0);
} else {
load_page_from_str(tab, err_pages[UNKNOWN_TYPE_OR_CSET]);
ui_yornp("Can't display page, wanna save?",
tab = tab_by_id(tabid);
tab->path = strdup(path);
- imsg_compose(fsibuf, IMSG_FILE_OPEN, tabid, 0, -1, path, strlen(path)+1);
- imsg_flush(fsibuf);
+ ui_send_fs(IMSG_FILE_OPEN, tabid, path, strlen(path)+1);
}
static void
free(page);
} else {
tab->fd = imsg->fd;
- imsg_compose(netibuf, IMSG_PROCEED, tab->id, 0, -1, NULL, 0);
- imsg_flush(netibuf);
+ ui_send_net(IMSG_PROCEED, tab->id, NULL, 0);
}
}
static void
handle_dispatch_imsg(int fd, short ev, void *d)
{
- struct imsgbuf *ibuf = d;
- dispatch_imsg(ibuf, handlers, sizeof(handlers));
+ struct imsgev *iev = d;
+ dispatch_imsg(iev, ev, handlers, sizeof(handlers));
}
static void
gemtext_initparser(&tab->buffer.page);
- imsg_compose(fsibuf, IMSG_GET, tab->id, 0, -1,
+ ui_send_fs(IMSG_GET, tab->id,
tab->hist_cur->h, strlen(tab->hist_cur->h)+1);
- imsg_flush(fsibuf);
}
void
req.proto = PROTO_GEMINI;
- imsg_compose(netibuf, IMSG_GET_RAW, tab->id, 0, -1,
+ ui_send_net(IMSG_GET_RAW, tab->id,
&req, sizeof(req));
- imsg_flush(netibuf);
}
void
req.proto = p->proto;
- imsg_compose(netibuf, IMSG_GET_RAW, tab->id, 0, -1,
+ ui_send_net(IMSG_GET_RAW, tab->id,
&req, sizeof(req));
- imsg_flush(netibuf);
}
static void
void
stop_tab(struct tab *tab)
{
- imsg_compose(netibuf, IMSG_STOP, tab->id, 0, -1, NULL, 0);
- imsg_flush(netibuf);
+ ui_send_net(IMSG_STOP, tab->id, NULL, 0);
if (tab->fd != -1) {
close(tab->fd);
void
add_to_bookmarks(const char *str)
{
- imsg_compose(fsibuf, IMSG_BOOKMARK_PAGE, 0, 0, -1, str, strlen(str)+1);
- imsg_flush(fsibuf);
+ ui_send_fs(IMSG_BOOKMARK_PAGE, 0,
+ str, strlen(str)+1);
}
void
{
struct tab *tab;
- imsg_compose(fsibuf, IMSG_SESSION_START, 0, 0, -1, NULL, 0);
- imsg_flush(fsibuf);
+ ui_send_fs(IMSG_SESSION_START, 0, NULL, 0);
TAILQ_FOREACH(tab, &tabshead, tabs) {
- imsg_compose(fsibuf, IMSG_SESSION_TAB, 0, 0, -1,
+ ui_send_fs(IMSG_SESSION_TAB, 0,
tab->hist_cur->h, strlen(tab->hist_cur->h)+1);
- imsg_flush(fsibuf);
}
- imsg_compose(fsibuf, IMSG_SESSION_END, 0, 0, -1, NULL, 0);
- imsg_flush(fsibuf);
+ ui_send_fs(IMSG_SESSION_END, 0, NULL, 0);
}
static void
err(1, "execvp(%s)", argv0);
}
+static int
+ui_send_net(int type, uint32_t peerid, const void *data,
+ uint16_t datalen)
+{
+ return imsg_compose_event(iev_net, type, peerid, 0, -1, data,
+ datalen);
+}
+
+static int
+ui_send_fs(int type, uint32_t peerid, const void *data, uint16_t datalen)
+{
+ return imsg_compose_event(iev_fs, type, peerid, 0, -1, data,
+ datalen);
+}
+
static void __attribute__((noreturn))
usage(int r)
{
int
main(int argc, char * const *argv)
{
- struct imsgbuf net_ibuf, fs_ibuf;
- int net_fds[2], fs_fds[2];
+ struct imsgev net_ibuf, fs_ibuf;
+ int pipe2net[2], pipe2fs[2];
int ch, configtest = 0, fail = 0;
int has_url = 0;
int proc = -1;
}
/* Start children. */
- if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, fs_fds) == -1)
+ if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe2fs) == -1)
err(1, "socketpair");
- start_child(PROC_FS, argv0, fs_fds[1]);
- imsg_init(&fs_ibuf, fs_fds[0]);
- fsibuf = &fs_ibuf;
+ start_child(PROC_FS, argv0, pipe2fs[1]);
+ imsg_init(&fs_ibuf.ibuf, pipe2fs[0]);
+ iev_fs = &fs_ibuf;
+ iev_fs->handler = handle_dispatch_imsg;
- if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, net_fds) == -1)
+ if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe2net) == -1)
err(1, "socketpair");
- start_child(PROC_NET, argv0, net_fds[1]);
- imsg_init(&net_ibuf, net_fds[0]);
- netibuf = &net_ibuf;
+ start_child(PROC_NET, argv0, pipe2net[1]);
+ imsg_init(&net_ibuf.ibuf, pipe2net[0]);
+ iev_net = &net_ibuf;
+ iev_net->handler = handle_dispatch_imsg;
setproctitle("ui");
event_init();
- event_set(&netev, netibuf->fd, EV_READ | EV_PERSIST,
- handle_dispatch_imsg, netibuf);
- event_add(&netev, NULL);
+ /* Setup event handlers for pipes to fs/net */
+ iev_fs->events = EV_READ;
+ event_set(&iev_fs->ev, iev_fs->ibuf.fd, iev_fs->events,
+ iev_fs->handler, iev_fs);
+ event_add(&iev_fs->ev, NULL);
- event_set(&fsev, fsibuf->fd, EV_READ | EV_PERSIST,
- handle_dispatch_imsg, fsibuf);
- event_add(&fsev, NULL);
+ iev_net->events = EV_READ;
+ event_set(&iev_net->ev, iev_net->ibuf.fd, iev_net->events,
+ iev_net->handler, iev_net);
+ event_add(&iev_net->ev, NULL);
if (ui_init()) {
load_last_session(session_new_tab_cb);
ui_end();
}
- imsg_compose(netibuf, IMSG_QUIT, 0, 0, -1, NULL, 0);
- imsg_flush(netibuf);
+ ui_send_fs(IMSG_QUIT, 0, NULL, 0);
+ ui_send_net(IMSG_QUIT, 0, NULL, 0);
- imsg_compose(fsibuf, IMSG_QUIT, 0, 0, -1, NULL, 0);
- imsg_flush(fsibuf);
-
return 0;
}
blob - 1384bbb676be2cec810813e94257bcbe9b8ff103
blob + 18b35c9587fc01b7b09a7b890ca79d2554a20783
--- telescope.h
+++ telescope.h
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define GEMINI_URL_LEN 1024
+
+struct imsgev {
+ struct imsgbuf ibuf;
+ void (*handler)(int, short, void *);
+ struct event ev;
+ short events;
+};
enum imsg_type {
/* ui <-> client/fs */
int has_prefix(const char*, const char*);
int unicode_isspace(uint32_t);
int unicode_isgraph(uint32_t);
-void dispatch_imsg(struct imsgbuf*, imsg_handlerfn**, size_t);
+void dispatch_imsg(struct imsgev*, short, imsg_handlerfn**, size_t);
+int imsg_compose_event(struct imsgev *, uint16_t, uint32_t, pid_t, int, const void *, uint16_t);
/* wrap.c */
void erase_buffer(struct buffer *);
blob - 5d0267624c08d1c1f99cedfe2af9e7b944e563d8
blob + 9d51f36474be436c2bd10eae4ecd1f741a37ebd8
--- util.c
+++ util.c
#include <stdlib.h>
#include <unistd.h>
+static void imsg_event_add(struct imsgev *);
+
int
mark_nonblock(int fd)
{
return 1;
}
+static void
+imsg_event_add(struct imsgev *iev)
+{
+ iev->events = EV_READ;
+ if (iev->ibuf.w.queued)
+ iev->events |= EV_WRITE;
+
+ event_del(&iev->ev);
+ event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev);
+ event_add(&iev->ev, NULL);
+}
+
void
-dispatch_imsg(struct imsgbuf *ibuf, imsg_handlerfn **handlers, size_t size)
+dispatch_imsg(struct imsgev *iev, short event, imsg_handlerfn **handlers,
+ size_t size)
{
- struct imsg imsg;
- size_t datalen, i;
- ssize_t n;
+ struct imsgbuf *ibuf;
+ struct imsg imsg;
+ size_t datalen, i;
+ ssize_t n;
- if ((n = imsg_read(ibuf)) == -1) {
- if (errno == EAGAIN || errno == EWOULDBLOCK)
- return;
- _exit(1);
+ ibuf = &iev->ibuf;
+
+ if (event & EV_READ) {
+ if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
+ err(1, "imsg_read error");
+ if (n == 0)
+ err(1, "connection closed");
}
+ if (event & EV_WRITE) {
+ if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN)
+ err(1, "msgbuf_write");
+ if (n == 0)
+ err(1, "connection closed");
+ }
- if (n == 0)
- _exit(1);
-
for (;;) {
if ((n = imsg_get(ibuf, &imsg)) == -1)
_exit(1);
if (n == 0)
- return;
+ break;
datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
i = imsg.hdr.type;
if (i > (size / sizeof(imsg_handlerfn*)) || handlers[i] == NULL)
handlers[i](&imsg, datalen);
imsg_free(&imsg);
}
+
+ imsg_event_add(iev);
}
+
+int
+imsg_compose_event(struct imsgev *iev, uint16_t type, uint32_t peerid,
+ pid_t pid, int fd, const void *data, uint16_t datalen)
+{
+ int ret;
+
+ if ((ret = imsg_compose(&iev->ibuf, type, peerid, pid, fd, data,
+ datalen) != -1))
+ imsg_event_add(iev);
+
+ return ret;
+}