summaryrefslogtreecommitdiff
path: root/src/dged
diff options
context:
space:
mode:
authorAlbert Cervin <albert@acervin.com>2024-04-29 11:03:47 +0200
committerAlbert Cervin <albert@acervin.com>2024-05-06 11:05:30 +0200
commitc42412e1643c88c81cf5b38404cc010881437fe9 (patch)
tree2650521affdaf0ba9c62f276514250f28af3129e /src/dged
parentc16a45eb19e436a558d2d8723fa4fda663ed3da8 (diff)
downloaddged-c42412e1643c88c81cf5b38404cc010881437fe9.tar.gz
dged-c42412e1643c88c81cf5b38404cc010881437fe9.tar.xz
dged-c42412e1643c88c81cf5b38404cc010881437fe9.zip
OpenBSD port work
Diffstat (limited to 'src/dged')
-rw-r--r--src/dged/display.c10
-rw-r--r--src/dged/reactor-kqueue.c112
-rw-r--r--src/dged/text.c4
3 files changed, 113 insertions, 13 deletions
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 <errno.h>
+#include <fcntl.h>
#include <stdlib.h>
+#include <string.h>
+#include <sys/event.h>
+#include <sys/types.h>
+#include <unistd.h>
-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,