From 087c6628ce7909a0c79245168c582dc199f1593c Mon Sep 17 00:00:00 2001 From: Albert Cervin Date: Mon, 29 Apr 2024 11:03:47 +0200 Subject: [PATCH] OpenBSD port work --- Makefile | 7 +-- src/dged/display.c | 10 ++-- src/dged/reactor-kqueue.c | 96 +++++++++++++++++++++++++++++++++++++-- src/dged/text.c | 4 +- src/main/main.c | 6 +++ 5 files changed, 110 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index ecbccf4..6b62ec1 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,11 @@ -# Makefile for bmake +# Makefile for bmake/openbsd make + +default: dged + .PHONY: default clean check run debug debug-tests install format .OBJDIR: ./build SYNTAX_ENABLE ?= true -default: dged - build: mkdir -p build 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..4261f3c 100644 --- a/src/dged/reactor-kqueue.c +++ b/src/dged/reactor-kqueue.c @@ -1,45 +1,131 @@ #include "reactor.h" +#include +#include #include +#include +#include +#include +#include + +#include "minibuffer.h" struct reactor { + int queue; + struct kevent events[10]; + uint32_t nevents; + int file_queue; }; struct reactor *reactor_create() { - struct reactor *reactor = calloc(1, sizeof(struct reactor)); + int queue = kqueue(); + if (queue < 0) { + return NULL; + } + + int file_queue = kqueue(); + if (file_queue < 0) { + return NULL; + } + struct reactor *reactor = calloc(1, sizeof(struct reactor)); + reactor->queue = queue; + reactor->file_queue = file_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, 10, 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; + 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 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->file_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; + struct kevent ev; + struct timespec zt = { 0 }; + int nevents = kevent(reactor->file_queue, NULL, 0, &ev, 1, &zt); + + if (nevents < 0) { + return false; + } else if (nevents == 0) { + return false; + } + + 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, diff --git a/src/main/main.c b/src/main/main.c index b0e408d..d96de33 100644 --- a/src/main/main.c +++ b/src/main/main.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -220,6 +221,11 @@ int main(int argc, char *argv[]) { struct reactor *reactor = reactor_create(); display = display_create(); + if (display == NULL) { + fprintf(stderr, "Failed to set up display: %s\n", strerror(errno)); + return 9; + } + display_clear(display); signal(SIGWINCH, resized);