From c42412e1643c88c81cf5b38404cc010881437fe9 Mon Sep 17 00:00:00 2001 From: Albert Cervin Date: Mon, 29 Apr 2024 11:03:47 +0200 Subject: OpenBSD port work --- src/dged/display.c | 10 +++-- src/dged/reactor-kqueue.c | 112 ++++++++++++++++++++++++++++++++++++++++++---- src/dged/text.c | 4 +- 3 files changed, 113 insertions(+), 13 deletions(-) (limited to 'src/dged') diff --git a/src/dged/display.c b/src/dged/display.c index ed6fc00..675140a 100644 --- a/src/dged/display.c +++ b/src/dged/display.c @@ -99,13 +99,17 @@ struct display *display_create() { // save old settings struct termios orig_term; - tcgetattr(0, &orig_term); + if (tcgetattr(0, &orig_term) < 0) { + return NULL; + } // set terminal to raw mode - struct termios term = {0}; + struct termios term = orig_term; cfmakeraw(&term); - tcsetattr(0, TCSADRAIN, &term); + if (tcsetattr(0, TCSADRAIN, &term) < 0) { + return NULL; + } struct display *d = calloc(1, sizeof(struct display)); d->orig_term = orig_term; diff --git a/src/dged/reactor-kqueue.c b/src/dged/reactor-kqueue.c index 5543c04..58ab7af 100644 --- a/src/dged/reactor-kqueue.c +++ b/src/dged/reactor-kqueue.c @@ -1,45 +1,141 @@ #include "reactor.h" +#include +#include #include +#include +#include +#include +#include -struct reactor { +#include "minibuffer.h" +struct reactor { + int queue; + struct kevent events[16]; + uint32_t nevents; }; struct reactor *reactor_create() { - struct reactor *reactor = calloc(1, sizeof(struct reactor)); + int queue = kqueue(); + if (queue < 0) { + return NULL; + } + struct reactor *reactor = calloc(1, sizeof(struct reactor)); + reactor->queue = queue; + reactor->nevents = 0; return reactor; } void reactor_destroy(struct reactor *reactor) { + close(reactor->queue); + reactor->queue = -1; free(reactor); } void reactor_update(struct reactor *reactor) { + int events = kevent(reactor->queue, NULL, 0, reactor->events, 16, NULL); + if (events == -1) { + // TODO: what to do here? + return; + } + reactor->nevents = events; } bool reactor_poll_event(struct reactor *reactor, uint32_t ev_id) { + for (uint32_t ei = 0; ei < reactor->nevents; ++ei) { + struct kevent *ev = &reactor->events[ei]; + + if (ev->ident == ev_id) { + return true; + } + } + return false; } -uint32_t reactor_register_interest(struct reactor *reactor, int fd, enum interest interest) { - return -1; +uint32_t reactor_register_interest(struct reactor *reactor, int fd, + enum interest interest) { + struct kevent changes[2] = {0}; + uint32_t nchanges = 0; + + if ((interest & ReadInterest) != 0) { + EV_SET(&changes[0], fd, EVFILT_READ, EV_ADD, 0, 0, NULL); + ++nchanges; + } + + if ((interest & WriteInterest) != 0) { + EV_SET(&changes[1], fd, EVFILT_WRITE, EV_ADD, 0, 0, NULL); + ++nchanges; + } + + if (kevent(reactor->queue, changes, nchanges, NULL, 0, NULL) < 0) { + return -1; + } + + return fd; } -uint32_t reactor_watch_file(struct reactor *reactor, const char *path, uint32_t mask) { - return -1; +uint32_t reactor_watch_file(struct reactor *reactor, const char *path, + uint32_t mask) { + + uint32_t fflags = NOTE_WRITE | NOTE_DELETE | NOTE_RENAME | NOTE_REVOKE; + int fd = open(path, O_RDONLY); + if (fd < 0) { + minibuffer_echo_timeout(4, "failed to watch %s: %s", path, strerror(errno)); + return 0; + } + + struct kevent new_event; + EV_SET(&new_event, fd, EVFILT_VNODE, EV_ADD | EV_CLEAR | EV_ENABLE, fflags, 0, + NULL); + if (kevent(reactor->queue, &new_event, 1, NULL, 0, NULL) < 0) { + return 0; + } + + return fd; } void reactor_unwatch_file(struct reactor *reactor, uint32_t id) { - + // all kevents for this fd are removed automatically when closed + close(id); } bool reactor_next_file_event(struct reactor *reactor, struct file_event *out) { - return false; + + // find the next vnode event and pop it from the events + struct kevent ev; + bool found = false; + for (uint32_t e = 0; e < reactor->nevents; ++e) { + if (reactor->events[e].filter == EVFILT_VNODE) { + ev = reactor->events[e]; + reactor->events[e] = reactor->events[reactor->nevents - 1]; + --reactor->nevents; + found = true; + break; + } + } + + if (!found) { + return false; + } + + out->mask = FileWritten; + if ((ev.fflags & NOTE_DELETE) || (ev.fflags & NOTE_RENAME) || + (ev.fflags & NOTE_REVOKE)) { + out->mask |= LastEvent; + } + + out->id = ev.ident; + return true; } void reactor_unregister_interest(struct reactor *reactor, uint32_t ev_id) { + struct kevent changes[2] = {0}; + EV_SET(&changes[0], ev_id, EVFILT_READ, EV_DELETE, 0, 0, NULL); + EV_SET(&changes[1], ev_id, EVFILT_WRITE, EV_DELETE, 0, 0, NULL); + kevent(reactor->queue, changes, 2, NULL, 0, NULL); } diff --git a/src/dged/text.c b/src/dged/text.c index 82c49bc..3d1078f 100644 --- a/src/dged/text.c +++ b/src/dged/text.c @@ -389,8 +389,8 @@ void text_delete(struct text *text, uint32_t start_line, uint32_t start_col, // in this case we can "overwrite" uint32_t dstbytei = utf8_nbytes(firstline->data, firstline->nbytes, start_col); - memcpy(firstline->data + dstbytei, lastline->data + bytei, - lastline->nbytes - bytei); + memmove(firstline->data + dstbytei, lastline->data + bytei, + lastline->nbytes - bytei); } else { // otherwise we actually have to copy from the last line insert_at(text, start_line, start_col, lastline->data + bytei, -- cgit v1.2.3