Skip to content

Commit

Permalink
OpenBSD port work
Browse files Browse the repository at this point in the history
  • Loading branch information
abbec committed May 6, 2024
1 parent c16a45e commit c42412e
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 32 deletions.
36 changes: 28 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -35,7 +36,10 @@ datadir = share/dged
.SUFFIXES:
.SUFFIXES: .c .o .d

CFLAGS += -Werror -g -O2 -std=c99 -I $(.CURDIR)/src -I $(.CURDIR)/src/main -DDATADIR="$(prefix)/$(datadir)"
CFLAGS += -Werror -g -O2 -std=c99 \
-I $(.CURDIR)/src \
-I $(.CURDIR)/src/main \
-DDATADIR="$(prefix)/$(datadir)"

ASAN ?= false

Expand Down Expand Up @@ -69,7 +73,13 @@ PLATFORM_OBJS = $(PLATFORM_SOURCES:.c=.o)
MAIN_OBJS = $(MAIN_SOURCES:.c=.o)
TEST_OBJS = $(TEST_SOURCES:.c=.o)

FILES = $(DEPS) $(MAIN_OBJS) $(OBJS) dged libdged.a $(TEST_OBJS) $(PLATFORM_OBJS)
FILES = $(DEPS) \
$(MAIN_OBJS) \
$(OBJS) \
$(TEST_OBJS) \
$(PLATFORM_OBJS) \
dged \
libdged.a

# dependency generation
.c.d:
Expand Down Expand Up @@ -101,7 +111,12 @@ run-tests: $(TEST_OBJS) $(OBJS)
$(CC) $(LDFLAGS) $(TEST_OBJS) $(OBJS) -lm -o run-tests

check: run-tests
$(FORMAT_TOOL) --dry-run --Werror $(SOURCES:%.c=../%.c) $(MAIN_SOURCES:%.c=../%.c) $(TEST_SOURCES:%c=../%c) $(HEADERS:%.h=../%.h)
$(FORMAT_TOOL) --dry-run --Werror \
$(SOURCES:%.c=../%.c) \
$(PLATFORM_SOURCES:%.c=../%.c) \
$(MAIN_SOURCES:%.c=../%.c) \
$(TEST_SOURCES:%c=../%c) \
$(HEADERS:%.h=../%.h)
./run-tests

run: dged
Expand All @@ -114,7 +129,12 @@ debug-tests: run-tests
gdb ./run-tests

format:
$(FORMAT_TOOL) -i $(SOURCES:%.c=../%.c) $(MAIN_SOURCES:%.c=../%.c) $(TEST_SOURCES:%c=../%c) $(HEADERS:%.h=../%.h)
$(FORMAT_TOOL) -i \
$(SOURCES:%.c=../%.c) \
$(MAIN_SOURCES:%.c=../%.c) \
$(PLATFORM_SOURCES:%.c=../%.c) \
$(TEST_SOURCES:%c=../%c) \
$(HEADERS:%.h=../%.h)

clean:
rm -f $(FILES)
Expand All @@ -129,7 +149,7 @@ install: dged
install -m 644 $(.CURDIR)/dged.1 $(DESTDIR)/share/man/man1/dged.1

install -d $(DESTDIR)/$(datadir)/grammars
cp -rL $(.OBJDIR)/grammars "$(DESTDIR)/$(datadir)/"
cp -RL $(.OBJDIR)/grammars "$(DESTDIR)/$(datadir)/"

docs:
doxygen $(.CURDIR)/Doxyfile
Expand Down
10 changes: 7 additions & 3 deletions src/dged/display.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
112 changes: 104 additions & 8 deletions src/dged/reactor-kqueue.c
Original file line number Diff line number Diff line change
@@ -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);
}
4 changes: 2 additions & 2 deletions src/dged/text.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
32 changes: 21 additions & 11 deletions src/main/main.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <errno.h>
#include <getopt.h>
#include <locale.h>
#include <signal.h>
Expand Down Expand Up @@ -93,17 +94,7 @@ void reload_buffer(struct buffer *buffer) {
}

void update_file_watches(struct reactor *reactor) {
// first, find invalid file watches and try to update them
VEC_FOR_EACH(&g_watched_files, struct watched_file * w) {
if (w->watch_id == INVALID_WATCH) {
message("re-watching: %s", w->buffer->filename);
w->watch_id =
reactor_watch_file(reactor, w->buffer->filename, FileWritten);
reload_buffer(w->buffer);
}
}

// then pick up any events we might have
// first, pick up any events we might have
struct file_event ev;
while (reactor_next_file_event(reactor, &ev)) {
// find the buffer we need to reload
Expand All @@ -120,6 +111,16 @@ void update_file_watches(struct reactor *reactor) {
}
}
}

// then, find invalid file watches and try to update them
VEC_FOR_EACH(&g_watched_files, struct watched_file * w) {
if (w->watch_id == INVALID_WATCH) {
message("re-watching: %s", w->buffer->filename);
w->watch_id =
reactor_watch_file(reactor, w->buffer->filename, FileWritten);
reload_buffer(w->buffer);
}
}
}

static void usage() {
Expand Down Expand Up @@ -218,8 +219,17 @@ int main(int argc, char *argv[]) {
frame_allocator = frame_allocator_create(16 * 1024 * 1024);

struct reactor *reactor = reactor_create();
if (reactor == NULL) {
fprintf(stderr, "Failed to create event reactor: %s\n", strerror(errno));
return 8;
}

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);

Expand Down

0 comments on commit c42412e

Please sign in to comment.