commit - 6eaaaab872315df9626e7237d13ed8d5aeb81fc5
commit + 6be8143330044a05a09e0ea4510d28027f79c13a
blob - f6f8be81a73ad894f9c8ba465171001997a72ff4
blob + 1a65819f0cf1669eabd51b18d3eb54dae677dbf0
--- amused.c
+++ amused.c
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
-#include <poll.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
ssize_t n;
int shut = 0;
- if (event & POLLIN) {
+ if (event & EV_READ) {
if ((n = imsg_read(imsgbuf)) == -1 && errno != EAGAIN)
fatal("imsg_read error");
if (n == 0) /* Connection closed */
shut = 1;
}
- if (event & POLLOUT) {
+ if (event & EV_WRITE) {
if ((n = msgbuf_write(&imsgbuf->w)) == -1 && errno != EAGAIN)
fatal("msgbuf_write");
if (n == 0) /* Connection closed */
iev_player = xmalloc(sizeof(*iev_player));
imsg_init(&iev_player->imsgbuf, pipe_main2player[0]);
iev_player->handler = main_dispatch_player;
- iev_player->events = POLLIN;
+ iev_player->events = EV_READ;
ev_add(iev_player->imsgbuf.fd, iev_player->events,
iev_player->handler, iev_player);
void
imsg_event_add(struct imsgev *iev)
{
- iev->events = POLLIN;
+ iev->events = EV_READ;
if (iev->imsgbuf.w.queued)
- iev->events |= POLLOUT;
+ iev->events |= EV_WRITE;
ev_add(iev->imsgbuf.fd, iev->events, iev->handler, iev);
}
blob - 257d02f7f78471a6a377b68930cc73a5e8554f20
blob + c1c975ce279ad3396c8951b9dab02f4ef2374241
--- control.c
+++ control.c
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
-#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct {
int fd;
+ unsigned int tout;
struct playlist play;
int tx;
} control_state = {.fd = -1, .tx = -1};
static void
enable_accept(int fd, int ev, void *bula)
{
- ev_add(control_state.fd, POLLIN, control_accept, NULL);
+ control_state.tout = 0;
+ ev_add(control_state.fd, EV_READ, control_accept, NULL);
}
int
struct timeval evtpause = { 1, 0 };
ev_del(control_state.fd);
- ev_timer(&evtpause, enable_accept, NULL);
+ control_state.tout = ev_timer(&evtpause, enable_accept, NULL);
+ if (control_state.tout == 0)
+ fatal("ev_timer failed");
} else if (errno != EWOULDBLOCK && errno != EINTR &&
errno != ECONNABORTED)
log_warn("%s: accept4", __func__);
imsg_init(&c->iev.imsgbuf, connfd);
c->iev.handler = control_dispatch_imsg;
- c->iev.events = POLLIN;
+ c->iev.events = EV_READ;
ev_add(c->iev.imsgbuf.fd, c->iev.events, c->iev.handler, &c->iev);
TAILQ_INSERT_TAIL(&ctl_conns, c, entry);
close(c->iev.imsgbuf.fd);
/* Some file descriptors are available again. */
- if (ev_timer_pending()) {
+ if (ev_timer_pending(control_state.tout)) {
ev_timer(NULL, NULL, NULL);
- ev_add(control_state.fd, POLLIN, control_accept, NULL);
+ ev_add(control_state.fd, EV_READ, control_accept, NULL);
}
free(c);
imsgbuf = &c->iev.imsgbuf;
- if (event & POLLIN) {
+ if (event & EV_READ) {
if (((n = imsg_read(imsgbuf)) == -1 && errno != EAGAIN) ||
n == 0) {
control_close(fd);
return;
}
}
- if (event & POLLOUT) {
+ if (event & EV_WRITE) {
if (msgbuf_write(&imsgbuf->w) <= 0 && errno != EAGAIN) {
control_close(fd);
return;
blob - 34f6474a60c36c69c8755554776633328c8cb829
blob + ee52583d16e300a724a09907f9e0217847264343
--- ev.c
+++ ev.c
#include "config.h"
+#include <sys/time.h>
+
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <poll.h>
#include <signal.h>
#include <stdlib.h>
+#include <string.h>
#include <time.h>
#include <unistd.h>
void *udata;
};
+struct evtimer {
+ unsigned int id;
+ struct timeval tv;
+ struct evcb cb;
+};
+
struct evbase {
size_t len;
int sigpipe[2];
struct evcb sigcb;
- int timeout;
- struct evcb toutcb;
+ unsigned int tid;
+
+ /*
+ * Binary heap of timers. At runtime, new timers are added in
+ * the ``reserve'', a space after the caninocal end of the
+ * array, and at the end of every tick they're added to the
+ * heap.
+ */
+ struct evtimer *timers;
+ size_t ntimers;
+ size_t reserve_from;
+ size_t reserve_till;
+ size_t timerscap;
};
static struct evbase *base;
base->sigpipe[0] = -1;
base->sigpipe[1] = -1;
- base->timeout = INFTIM;
if (ev_resize(16) == -1) {
free(base->pfds);
return 0;
}
+static inline int
+ev2poll(int ev)
+{
+ int ret = 0;
+
+ if (ev & EV_READ)
+ ret |= POLLIN;
+ if (ev & EV_WRITE)
+ ret |= POLLOUT;
+
+ return (ret);
+}
+
int
ev_add(int fd, int ev, void (*cb)(int, int, void *), void *udata)
{
- if (fd >= base->len) {
+ if (fd < 0) {
+ errno = EBADF;
+ return -1;
+ }
+
+ if ((size_t)fd >= base->len) {
if (ev_resize(fd + 1) == -1)
return -1;
}
base->pfds[fd].fd = fd;
- base->pfds[fd].events = ev;
+ base->pfds[fd].events = ev2poll(ev);
+ base->pfds[fd].revents = 0;
base->cbs[fd].cb = cb;
base->cbs[fd].udata = udata;
if (read(fd, &signo, sizeof(signo)) != sizeof(signo))
return;
- base->sigcb.cb(signo, 0, base->sigcb.udata);
+ base->sigcb.cb(signo, EV_SIGNAL, base->sigcb.udata);
}
int
fcntl(base->sigpipe[1], F_SETFL, flags | O_NONBLOCK) == -1)
return -1;
- if (ev_add(base->sigpipe[0], POLLIN, ev_sigdispatch, NULL)
+ if (ev_add(base->sigpipe[0], EV_READ, ev_sigdispatch, NULL)
== -1)
return -1;
}
return 0;
}
-int
+unsigned int
ev_timer(const struct timeval *tv, void (*cb)(int, int, void*), void *udata)
{
- base->timeout = INFTIM;
- if (tv) {
- base->timeout = tv->tv_sec * 1000;
- base->timeout += tv->tv_usec / 1000;
+ struct evtimer *evt;
+ void *t;
+ size_t newcap;
+ unsigned int nextid;
+
+ if (tv == NULL) {
+ errno = EINVAL;
+ return 0;
}
- base->toutcb.cb = cb;
- base->toutcb.udata = udata;
+ if (base->reserve_till == base->timerscap) {
+ newcap = base->timerscap + 8;
+ t = recallocarray(base->timers, base->timerscap, newcap,
+ sizeof(*base->timers));
+ if (t == NULL)
+ return 0;
+ base->timers = t;
+ base->timerscap = newcap;
+ }
- return 0;
-}
+ if ((nextid = ++base->tid) == 0)
+ nextid = ++base->tid;
-int
-ev_timer_pending(void)
+ evt = &base->timers[base->reserve_till];
+ evt->id = nextid;
+ memcpy(&evt->tv, tv, sizeof(*tv));
+ evt->cb.cb = cb;
+ evt->cb.udata = udata;
+
+ base->reserve_till++;
+ return (nextid);
+}
+
+static int
+find_timer(unsigned int id, size_t *pos)
{
- return base->timeout != INFTIM;
+ size_t i;
+
+ if (id == 0)
+ return (0);
+
+ for (i = 0; i < base->ntimers; ++i) {
+ if (base->timers[i].id == id) {
+ *pos = i;
+ return (1);
+ }
+ }
+
+ for (i = base->reserve_from; i < base->reserve_till; ++i) {
+ if (base->timers[i].id == id) {
+ *pos = i;
+ return (1);
+ }
+ }
+
+ return (0);
}
+int
+ev_timer_pending(unsigned int id)
+{
+ size_t i;
+
+ return (find_timer(id, &i));
+}
+
+static void
+bubbledown(size_t i)
+{
+ struct evtimer tmp;
+ size_t l, r, s;
+
+ for (;;) {
+ l = 2 * i + 1;
+ r = 2 * i + 2;
+
+ /* base case: there are no children */
+ if (l >= base->ntimers)
+ return;
+
+ /* find the smaller child */
+ s = r;
+ if (r >= base->ntimers ||
+ timercmp(&base->timers[l].tv, &base->timers[r].tv, <))
+ s = l;
+
+ /* other base case: it's at the right place */
+ if (timercmp(&base->timers[i].tv, &base->timers[s].tv, <))
+ return;
+
+ /* swap */
+ memcpy(&tmp, &base->timers[s], sizeof(tmp));
+ memcpy(&base->timers[s], &base->timers[i], sizeof(tmp));
+ memcpy(&base->timers[i], &tmp, sizeof(tmp));
+
+ i = s;
+ }
+}
+
+static inline void
+cancel_timer(size_t i)
+{
+ base->ntimers--;
+ if (i != base->ntimers) {
+ memcpy(&base->timers[i], &base->timers[base->ntimers],
+ sizeof(*base->timers));
+ bubbledown(i);
+ }
+}
+
int
+ev_timer_cancel(unsigned int id)
+{
+ size_t i;
+
+ if (!find_timer(id, &i))
+ return (-1);
+
+ if (i < base->ntimers) {
+ cancel_timer(i);
+ return (0);
+ }
+
+ base->reserve_till--;
+ if (i != base->reserve_till)
+ memcpy(&base->timers[i], &base->timers[base->reserve_till],
+ sizeof(*base->timers));
+ return (0);
+}
+
+int
ev_del(int fd)
{
- if (fd >= base->len) {
+ if (fd < 0) {
+ errno = EBADF;
+ return -1;
+ }
+
+ if ((size_t)fd >= base->len) {
errno = ERANGE;
return -1;
}
return 0;
}
+static void
+timerheapify(void)
+{
+ size_t i, reserve, gap;
+
+ reserve = base->reserve_till - base->reserve_from;
+ if (reserve == 0)
+ return;
+
+ gap = base->reserve_from - base->ntimers;
+ if (gap != 0) {
+ memmove(&base->timers[base->ntimers],
+ &base->timers[base->reserve_from],
+ reserve * sizeof(*base->timers));
+ base->reserve_from -= gap;
+ base->reserve_till -= gap;
+ }
+
+ base->ntimers = base->reserve_till;
+
+ if (base->ntimers < 2)
+ return;
+
+ i = base->ntimers / 2 - 1;
+ for (;;) {
+ bubbledown(i);
+ if (i == 0)
+ break;
+ i--;
+ }
+}
+
+static inline int
+poll2ev(int ev)
+{
+ int r = 0;
+
+ if (ev & (POLLIN|POLLHUP))
+ r |= EV_READ;
+ if (ev & (POLLOUT|POLLWRNORM|POLLWRBAND))
+ r |= EV_WRITE;
+
+ return (r);
+}
+
int
-ev_loop(void)
+ev_step(void)
{
struct timespec elapsed, beg, end;
- int n, em;
+ struct timeval tv, sub, *min;
+ struct evcb cb;
+ int n, msec;
size_t i;
- while (!ev_stop) {
- clock_gettime(CLOCK_MONOTONIC, &beg);
- if ((n = poll(base->pfds, base->len, base->timeout)) == -1) {
- if (errno != EINTR)
- return -1;
- }
- clock_gettime(CLOCK_MONOTONIC, &end);
+ timerheapify();
+ base->reserve_from = base->ntimers;
+ base->reserve_till = base->ntimers;
+ min = NULL;
+ msec = -1;
+ if (base->ntimers) {
+ min = &base->timers[0].tv;
+ msec = min->tv_sec * 1000 + (min->tv_usec + 999) / 1000;
+ }
+
+ clock_gettime(CLOCK_MONOTONIC, &beg);
+ if ((n = poll(base->pfds, base->len, msec)) == -1) {
+ if (errno != EINTR)
+ return -1;
+ }
+
+ if (n == 0 && min)
+ memcpy(&tv, min, sizeof(tv));
+ else {
+ clock_gettime(CLOCK_MONOTONIC, &end);
timespecsub(&end, &beg, &elapsed);
- em = elapsed.tv_sec * 1000 + elapsed.tv_nsec / 1000000;
- if (base->timeout != INFTIM) {
- if (base->timeout - em < 0 || n == 0) {
- base->timeout = INFTIM;
- base->toutcb.cb(-1, 0, base->toutcb.udata);
- } else
- base->timeout -= em;
+ TIMESPEC_TO_TIMEVAL(&tv, &elapsed);
+ }
+
+ for (i = 0; i < base->ntimers && !ev_stop; /* nop */) {
+ timersub(&base->timers[i].tv, &tv, &sub);
+ if (sub.tv_sec <= 0) {
+ /*
+ * delete the timer before calling its
+ * callback; protects from timer that
+ * attempt to delete themselves.
+ */
+ memcpy(&cb, &base->timers[i].cb, sizeof(cb));
+ cancel_timer(i);
+ cb.cb(-1, EV_TIMEOUT, cb.udata);
+ continue;
}
- for (i = 0; i < base->len && n > 0 && !ev_stop; ++i) {
- if (base->pfds[i].fd == -1)
- continue;
- if (base->pfds[i].revents & (POLLIN|POLLOUT|POLLHUP)) {
- n--;
- base->cbs[i].cb(base->pfds[i].fd,
- base->pfds[i].revents,
- base->cbs[i].udata);
- }
+ memcpy(&base->timers[i].tv, &sub, sizeof(sub));
+ i++;
+ }
+
+ for (i = 0; i < base->len && n > 0 && !ev_stop; ++i) {
+ if (base->pfds[i].fd == -1)
+ continue;
+ if (base->pfds[i].revents & (POLLIN|POLLOUT|POLLHUP)) {
+ n--;
+ base->cbs[i].cb(base->pfds[i].fd,
+ poll2ev(base->pfds[i].revents),
+ base->cbs[i].udata);
}
}
+ return (0);
+}
+
+int
+ev_loop(void)
+{
+ while (!ev_stop) {
+ if (ev_step() == -1)
+ return (-1);
+ }
+
return 0;
}
blob - 7acacfe73721b2c98e67bc1df641f3c9510c1c61
blob + eced7ccf6ec9531156df977c26ab0244f27348fa
--- ev.h
+++ ev.h
struct timeval;
-int ev_init(void);
-int ev_add(int, int, void(*)(int, int, void *), void *);
-int ev_signal(int, void(*)(int, int, void * ), void *);
-int ev_timer(const struct timeval *, void(*)(int, int, void *), void *);
-int ev_timer_pending(void);
-int ev_del(int);
-int ev_loop(void);
-void ev_break(void);
+#define EV_READ 0x1
+#define EV_WRITE 0x2
+#define EV_SIGNAL 0x4
+#define EV_TIMEOUT 0x8
+
+int ev_init(void);
+int ev_add(int, int, void(*)(int, int, void *), void *);
+int ev_signal(int, void(*)(int, int, void * ), void *);
+unsigned int ev_timer(const struct timeval *, void(*)(int, int, void *),
+ void *);
+int ev_timer_pending(unsigned int);
+int ev_timer_cancel(unsigned int);
+int ev_del(int);
+int ev_step(void);
+int ev_step(void);
+int ev_loop(void);
+void ev_break(void);
blob - b6666792ae040e1ee339dc20a68db0cf74208e6f
blob + 7ed26ffa838545a2a5e2e82b66f57f527e4aef7a
--- web/Makefile
+++ web/Makefile
rm ${DESTDIR}${MANDIR}/man1/${PROG}.1
.c.o:
- ${CC} -I../ ${CFLAGS} -c $< -o $@
+ ${CC} -I../ ${CFLAGS} -DBUFIO_WITHOUT_TLS -c $< -o $@
# --- maintainer targets ---
blob - da7bde52d49d841a387fa5a9526fe9bb66410503
blob + 424516bc75c38f21feafbd73cdcc6c5b22799fd1
--- web/bufio.c
+++ web/bufio.c
#include <assert.h>
#include <errno.h>
-#include <poll.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
+#ifndef BUFIO_WITHOUT_TLS
+#include <tls.h>
+#endif
+
#include "bufio.h"
int
-buf_init(struct buffer *buf)
+buf_init(struct buf *buf)
{
const size_t cap = BIO_CHUNK;
}
static int
-buf_grow(struct buffer *buf)
+buf_grow(struct buf *buf)
{
size_t newcap;
void *t;
}
int
-buf_write(struct buffer *buf, const void *d, size_t len)
+buf_write(struct buf *buf, const void *d, size_t len)
{
while (buf->len + len > buf->cap) {
if (buf_grow(buf) == -1)
}
int
-buf_has_line(struct buffer *buf, const char *nl)
+buf_has_line(struct buf *buf, const char *nl)
{
return (memmem(buf->buf, buf->len, nl, strlen(nl)) != NULL);
}
+char *
+buf_getdelim(struct buf *buf, const char *nl, size_t *len)
+{
+ uint8_t *endl;
+ size_t nlen;
+
+ *len = 0;
+
+ nlen = strlen(nl);
+ if ((endl = memmem(buf->buf, buf->len, nl, nlen)) == NULL)
+ return (NULL);
+ *len = endl + nlen - buf->buf;
+ *endl = '\0';
+ return (buf->buf);
+}
+
void
-buf_drain(struct buffer *buf, size_t l)
+buf_drain(struct buf *buf, size_t l)
{
+ buf->cur = 0;
+
if (l >= buf->len) {
buf->len = 0;
return;
}
void
-buf_drain_line(struct buffer *buf, const char *nl)
+buf_drain_line(struct buf *buf, const char *nl)
{
uint8_t *endln;
size_t nlen;
}
void
-buf_free(struct buffer *buf)
+buf_free(struct buf *buf)
{
free(buf->buf);
memset(buf, 0, sizeof(*buf));
void
bufio_free(struct bufio *bio)
{
+#ifndef BUFIO_WITHOUT_TLS
+ if (bio->ctx)
+ tls_free(bio->ctx);
+ bio->ctx = NULL;
+#endif
+
if (bio->fd != -1)
close(bio->fd);
+ bio->fd = -1;
buf_free(&bio->rbuf);
buf_free(&bio->wbuf);
}
int
+bufio_close(struct bufio *bio)
+{
+#ifndef BUFIO_WITHOUT_TLS
+ if (bio->ctx == NULL)
+ return (0);
+
+ switch (tls_close(bio->ctx)) {
+ case 0:
+ return 0;
+ case TLS_WANT_POLLIN:
+ errno = EAGAIN;
+ bio->wantev = BUFIO_WANT_READ;
+ return (-1);
+ case TLS_WANT_POLLOUT:
+ errno = EAGAIN;
+ bio->wantev = BUFIO_WANT_WRITE;
+ return (-1);
+ default:
+ return (-1);
+ }
+#else
+ return (0);
+#endif
+}
+
+int
bufio_reset(struct bufio *bio)
{
bufio_free(bio);
bio->chunked = chunked;
}
-short
-bufio_pollev(struct bufio *bio)
+int
+bufio_starttls(struct bufio *bio, const char *host, int insecure,
+ const uint8_t *cert, size_t certlen, const uint8_t *key, size_t keylen)
{
- short ev;
+#ifndef BUFIO_WITHOUT_TLS
+ struct tls_config *conf;
- ev = POLLIN;
- if (bio->wbuf.len != 0)
- ev |= POLLOUT;
+ if ((conf = tls_config_new()) == NULL)
+ return (-1);
+
+ if (insecure) {
+ tls_config_insecure_noverifycert(conf);
+ tls_config_insecure_noverifyname(conf);
+ tls_config_insecure_noverifytime(conf);
+ }
+
+ if (cert && tls_config_set_keypair_mem(conf, cert, certlen,
+ key, keylen) == -1) {
+ tls_config_free(conf);
+ return (-1);
+ }
+
+ if ((bio->ctx = tls_client()) == NULL) {
+ tls_config_free(conf);
+ return (-1);
+ }
+
+ if (tls_configure(bio->ctx, conf) == -1) {
+ tls_config_free(conf);
+ return (-1);
+ }
+
+ tls_config_free(conf);
+
+ if (tls_connect_socket(bio->ctx, bio->fd, host) == -1)
+ return (-1);
+
+ return (0);
+#else
+ errno = EINVAL;
+ return (-1);
+#endif
+}
+
+int
+bufio_ev(struct bufio *bio)
+{
+ short ev;
+ if (bio->wantev)
+ return (bio->wantev);
+
+ ev = BUFIO_WANT_READ;
+ if (bio->wbuf.len != 0)
+ ev |= BUFIO_WANT_WRITE;
+
return (ev);
}
+int
+bufio_handshake(struct bufio *bio)
+{
+#ifndef BUFIO_WITHOUT_TLS
+ if (bio->ctx == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ switch (tls_handshake(bio->ctx)) {
+ case 0:
+ return (0);
+ case TLS_WANT_POLLIN:
+ errno = EAGAIN;
+ bio->wantev = BUFIO_WANT_READ;
+ return (-1);
+ case TLS_WANT_POLLOUT:
+ errno = EAGAIN;
+ bio->wantev = BUFIO_WANT_WRITE;
+ return (-1);
+ default:
+ return (-1);
+ }
+#else
+ errno = EINVAL;
+ return (-1);
+#endif
+}
+
ssize_t
bufio_read(struct bufio *bio)
{
- struct buffer *rbuf = &bio->rbuf;
+ struct buf *rbuf = &bio->rbuf;
ssize_t r;
assert(rbuf->cap >= rbuf->len);
return (-1);
}
+#ifndef BUFIO_WITHOUT_TLS
+ if (bio->ctx) {
+ r = tls_read(bio->ctx, rbuf->buf + rbuf->len,
+ rbuf->cap - rbuf->len);
+ switch (r) {
+ case TLS_WANT_POLLIN:
+ errno = EAGAIN;
+ bio->wantev = BUFIO_WANT_READ;
+ return (-1);
+ case TLS_WANT_POLLOUT:
+ errno = EAGAIN;
+ bio->wantev = BUFIO_WANT_WRITE;
+ return (-1);
+ case -1:
+ return (-1);
+ default:
+ bio->wantev = 0;
+ rbuf->len += r;
+ return (r);
+ }
+ }
+#endif
+
r = read(bio->fd, rbuf->buf + rbuf->len, rbuf->cap - rbuf->len);
if (r == -1)
return (-1);
size_t
bufio_drain(struct bufio *bio, void *d, size_t len)
{
- struct buffer *rbuf = &bio->rbuf;
+ struct buf *rbuf = &bio->rbuf;
if (len > rbuf->len)
len = rbuf->len;
ssize_t
bufio_write(struct bufio *bio)
{
- struct buffer *wbuf = &bio->wbuf;
+ struct buf *wbuf = &bio->wbuf;
ssize_t w;
+#ifndef BUFIO_WITHOUT_TLS
+ if (bio->ctx) {
+ switch (w = tls_write(bio->ctx, wbuf->buf, wbuf->len)) {
+ case TLS_WANT_POLLIN:
+ errno = EAGAIN;
+ bio->wantev = BUFIO_WANT_READ;
+ return (-1);
+ case TLS_WANT_POLLOUT:
+ errno = EAGAIN;
+ bio->wantev = BUFIO_WANT_WRITE;
+ return (-1);
+ case -1:
+ return (-1);
+ default:
+ bio->wantev = 0;
+ buf_drain(wbuf, w);
+ return (w);
+ }
+ }
+#endif
+
w = write(bio->fd, wbuf->buf, wbuf->len);
if (w == -1)
return (-1);
static int
bufio_append(struct bufio *bio, const void *d, size_t len)
{
- struct buffer *wbuf = &bio->wbuf;
+ struct buf *wbuf = &bio->wbuf;
if (len == 0)
return (0);
free(str);
return (r);
}
+
+void
+bufio_rewind_cursor(struct bufio *bio)
+{
+ bio->rbuf.cur = 0;
+}
+
+int
+bufio_get_cb(void *d)
+{
+ struct bufio *bio = d;
+ struct buf *rbuf = &bio->rbuf;
+
+ if (rbuf->cur >= rbuf->len)
+ return (EOF);
+ return (rbuf->buf[rbuf->cur++]);
+}
+
+int
+bufio_peek_cb(void *d)
+{
+ struct bufio *bio = d;
+ struct buf *rbuf = &bio->rbuf;
+
+ if (rbuf->cur >= rbuf->len)
+ return (EOF);
+ return (rbuf->buf[rbuf->cur]);
+}
blob - 98fdeb1d1412eae123638b65b2c840c85352e4ea
blob + 257a931f662a9d92b602a0b41305198f2ced784c
--- web/bufio.h
+++ web/bufio.h
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#define BIO_CHUNK 1024
-struct buffer {
+#ifndef BUFIO_WITHOUT_TLS
+struct tls;
+#endif
+
+#define BIO_CHUNK 128
+struct buf {
uint8_t *buf;
size_t len;
size_t cap;
+ size_t cur;
};
struct bufio {
int fd;
int chunked;
- struct buffer wbuf;
- struct buffer rbuf;
+#ifndef BUFIO_WITHOUT_TLS
+ struct tls *ctx;
+#endif
+ int wantev;
+ struct buf wbuf;
+ struct buf rbuf;
};
-int buf_init(struct buffer *);
-int buf_write(struct buffer *, const void *, size_t);
-int buf_has_line(struct buffer *, const char *);
-void buf_drain(struct buffer *, size_t);
-void buf_drain_line(struct buffer *, const char *);
-void buf_free(struct buffer *);
+#define BUFIO_WANT_READ 0x1
+#define BUFIO_WANT_WRITE 0x2
+int buf_init(struct buf *);
+int buf_write(struct buf *, const void *, size_t);
+int buf_has_line(struct buf *, const char *);
+char *buf_getdelim(struct buf *, const char *, size_t *);
+void buf_drain(struct buf *, size_t);
+void buf_drain_line(struct buf *, const char *);
+void buf_free(struct buf *);
+
int bufio_init(struct bufio *);
void bufio_free(struct bufio *);
+int bufio_close(struct bufio *);
int bufio_reset(struct bufio *);
void bufio_set_fd(struct bufio *, int);
void bufio_set_chunked(struct bufio *, int);
-short bufio_pollev(struct bufio *);
+int bufio_starttls(struct bufio *, const char *, int,
+ const uint8_t *, size_t, const uint8_t *, size_t);
+int bufio_ev(struct bufio *);
+int bufio_handshake(struct bufio *);
ssize_t bufio_read(struct bufio *);
size_t bufio_drain(struct bufio *, void *, size_t);
ssize_t bufio_write(struct bufio *);
int bufio_compose_str(struct bufio *, const char *);
int bufio_compose_fmt(struct bufio *, const char *, ...)
__attribute__((__format__ (printf, 2, 3)));
+void bufio_rewind_cursor(struct bufio *);
+
+/* callbacks for pdjson */
+int bufio_get_cb(void *);
+int bufio_peek_cb(void *);
blob - 75b8cd43bfd889cd1f33d56beb1869ad32225af7
blob + b24bd2f26157718c7e62a92aea5c2ae4fbfe148a
--- web/http.c
+++ web/http.c
int
http_parse(struct client *clt)
{
- struct buffer *rbuf = &clt->bio.rbuf;
+ struct buf *rbuf = &clt->bio.rbuf;
struct request *req = &clt->req;
size_t len;
uint8_t *endln;
http_read(struct client *clt)
{
struct request *req = &clt->req;
- struct buffer *rbuf = &clt->bio.rbuf;
+ struct buf *rbuf = &clt->bio.rbuf;
size_t left;
/* clients may have sent more data than advertised */
blob - b6888f4d5f07b6e4310164980fc32c0d3a82f9be
blob + 16ad7fe7ebf1a6a063c5bd5e0c857c199237825b
--- web/web.c
+++ web/web.c
#include <limits.h>
#include <locale.h>
#include <netdb.h>
-#include <poll.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
const char *foot = "<script src='/app.js?v=0'></script></body></html>";
+static inline int
+bio_ev(struct bufio *bio)
+{
+ int ret, ev;
+
+ ret = 0;
+ ev = bufio_ev(bio);
+ if (ev & BUFIO_WANT_READ)
+ ret |= EV_READ;
+ if (ev & BUFIO_WANT_WRITE)
+ ret |= EV_WRITE;
+ return ret;
+}
+
static int
dial(const char *sock)
{
if (ws_compose(clt, WST_TEXT, msg, len) == -1)
ret = -1;
- ev_add(clt->bio.fd, POLLIN|POLLOUT, client_ev, clt);
+ ev_add(clt->bio.fd, EV_READ|EV_WRITE, client_ev, clt);
}
return (ret);
size_t datalen;
int r;
- if (ev & (POLLIN|POLLHUP)) {
+ if (ev & EV_READ) {
if ((n = imsg_read(&imsgbuf)) == -1 && errno != EAGAIN)
fatal("imsg_read");
if (n == 0)
fatalx("pipe closed");
}
- if (ev & POLLOUT) {
+ if (ev & EV_WRITE) {
if ((n = msgbuf_write(&imsgbuf.w)) == -1 && errno != EAGAIN)
fatal("msgbuf_write");
if (n == 0)
}
}
- ev = POLLIN;
+ ev = EV_READ;
if (imsgbuf.w.queued)
- ev |= POLLOUT;
+ ev |= EV_WRITE;
ev_add(fd, ev, imsg_dispatch, NULL);
}
imsg_compose(&imsgbuf, IMSG_CTL_JUMP, 0, 0, -1,
path, sizeof(path));
- ev_add(imsgbuf.w.fd, POLLIN|POLLOUT, imsg_dispatch, NULL);
+ ev_add(imsgbuf.w.fd, EV_READ|EV_WRITE, imsg_dispatch, NULL);
break;
}
imsg_compose(&imsgbuf, IMSG_CTL_MODE, 0, 0, -1,
&pm, sizeof(pm));
- ev_add(imsgbuf.w.fd, POLLIN|POLLOUT, imsg_dispatch, NULL);
+ ev_add(imsgbuf.w.fd, EV_READ|EV_WRITE, imsg_dispatch, NULL);
break;
}
static void
route_handle_ws(struct client *clt)
{
- struct buffer *rbuf = &clt->bio.rbuf;
+ struct buf *rbuf = &clt->bio.rbuf;
int type;
size_t len;
{
struct client *clt = d;
- if (ev & (POLLIN|POLLHUP)) {
+ if (ev & EV_READ) {
if (bufio_read(&clt->bio) == -1 && errno != EAGAIN) {
log_warn("bufio_read");
goto err;
}
}
- if (ev & POLLOUT) {
+ if (ev & EV_WRITE) {
if (bufio_write(&clt->bio) == -1 && errno != EAGAIN) {
log_warn("bufio_write");
goto err;
clt->route(clt);
again:
- ev = bufio_pollev(&clt->bio);
- if (ev == POLLIN && (clt->done || clt->err)) {
+ ev = bio_ev(&clt->bio);
+ if (ev == EV_READ && (clt->done || clt->err)) {
goto err; /* done with this client */
}
TAILQ_INSERT_TAIL(&clients, clt, clients);
- client_ev(sock, POLLIN, clt);
+ client_ev(sock, EV_READ, clt);
return;
}
imsg_compose(&imsgbuf, IMSG_CTL_SHOW, 0, 0, -1, NULL, 0);
imsg_compose(&imsgbuf, IMSG_CTL_STATUS, 0, 0, -1, NULL, 0);
imsg_compose(&imsgbuf, IMSG_CTL_MONITOR, 0, 0, -1, NULL, 0);
- ev_add(amused_sock, POLLIN|POLLOUT, imsg_dispatch, NULL);
+ ev_add(amused_sock, EV_READ|EV_WRITE, imsg_dispatch, NULL);
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
if (listen(fd, 5) == -1)
err(1, "listen");
- if (ev_add(fd, POLLIN, web_accept, NULL) == -1)
+ if (ev_add(fd, EV_READ, web_accept, NULL) == -1)
fatal("ev_add");
nsock++;
}
blob - 16fab184ad65d5ba6cbe6e2c5fa25f9b404af1f1
blob + 0e7302da3d95b628068ffacd9a5d67dd102a5cc1
--- web/ws.c
+++ web/ws.c
int
ws_read(struct client *clt, int *type, size_t *len)
{
- struct buffer *rbuf = &clt->bio.rbuf;
+ struct buf *rbuf = &clt->bio.rbuf;
size_t i;
uint32_t mask;
uint8_t first, second, op, plen;