forked from lite-xl/lite-xl
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
seperate dirmonitor logic, add build time detection of features (lite…
…-xl#866) this also adds libkqueue support
- Loading branch information
Showing
7 changed files
with
263 additions
and
131 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#include <stdlib.h> | ||
|
||
struct dirmonitor { | ||
}; | ||
|
||
struct dirmonitor* init_dirmonitor_dummy() { | ||
return NULL; | ||
} | ||
|
||
void deinit_dirmonitor_dummy(struct dirmonitor* monitor) { | ||
} | ||
|
||
int check_dirmonitor_dummy(struct dirmonitor* monitor, int (*change_callback)(int, const char*, void*), void* data) { | ||
return -1; | ||
} | ||
|
||
int add_dirmonitor_dummy(struct dirmonitor* monitor, const char* path) { | ||
return -1; | ||
} | ||
|
||
void remove_dirmonitor_dummy(struct dirmonitor* monitor, int fd) { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
#include <sys/inotify.h> | ||
#include <limits.h> | ||
#include <unistd.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <errno.h> | ||
#include <fcntl.h> | ||
|
||
struct dirmonitor { | ||
int fd; | ||
}; | ||
|
||
struct dirmonitor* init_dirmonitor_inotify() { | ||
struct dirmonitor* monitor = calloc(sizeof(struct dirmonitor), 1); | ||
|
||
monitor->fd = inotify_init(); | ||
fcntl(monitor->fd, F_SETFL, O_NONBLOCK); | ||
|
||
|
||
return monitor; | ||
} | ||
|
||
void deinit_dirmonitor_inotify(struct dirmonitor* monitor) { | ||
close(monitor->fd); | ||
free(monitor); | ||
} | ||
|
||
int check_dirmonitor_inotify(struct dirmonitor* monitor, int (*change_callback)(int, const char*, void*), void* data) { | ||
char buf[PATH_MAX + sizeof(struct inotify_event)]; | ||
ssize_t offset = 0; | ||
|
||
while (1) { | ||
ssize_t len = read(monitor->fd, &buf[offset], sizeof(buf) - offset); | ||
|
||
if (len == -1 && errno != EAGAIN) { | ||
return errno; | ||
} | ||
|
||
if (len <= 0) { | ||
return 0; | ||
} | ||
|
||
while (len > sizeof(struct inotify_event) && len >= ((struct inotify_event*)buf)->len + sizeof(struct inotify_event)) { | ||
change_callback(((const struct inotify_event *)buf)->wd, NULL, data); | ||
len -= sizeof(struct inotify_event) + ((struct inotify_event*)buf)->len; | ||
memmove(buf, &buf[sizeof(struct inotify_event) + ((struct inotify_event*)buf)->len], len); | ||
offset = len; | ||
} | ||
} | ||
} | ||
|
||
int add_dirmonitor_inotify(struct dirmonitor* monitor, const char* path) { | ||
return inotify_add_watch(monitor->fd, path, IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO); | ||
} | ||
|
||
void remove_dirmonitor_inotify(struct dirmonitor* monitor, int fd) { | ||
inotify_rm_watch(monitor->fd, fd); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
#include <sys/event.h> | ||
#include <sys/stat.h> | ||
#include <stdlib.h> | ||
#include <errno.h> | ||
#include <fcntl.h> | ||
#include <unistd.h> | ||
|
||
struct dirmonitor { | ||
int fd; | ||
}; | ||
|
||
struct dirmonitor* init_dirmonitor_kqueue() { | ||
struct dirmonitor* monitor = calloc(sizeof(struct dirmonitor), 1); | ||
monitor->fd = kqueue(); | ||
return monitor; | ||
} | ||
|
||
void deinit_dirmonitor_kqueue(struct dirmonitor* monitor) { | ||
close(monitor->fd); | ||
free(monitor); | ||
} | ||
|
||
int check_dirmonitor_kqueue(struct dirmonitor* monitor, int (*change_callback)(int, const char*, void*), void* data) { | ||
struct kevent event; | ||
while (1) { | ||
struct timespec tm = {0}; | ||
int nev = kevent(monitor->fd, NULL, 0, &event, 1, &tm); | ||
|
||
if (nev == -1) { | ||
return errno; | ||
} | ||
|
||
if (nev <= 0) { | ||
return 0; | ||
} | ||
|
||
change_callback(event.ident, NULL, data); | ||
} | ||
} | ||
|
||
int add_dirmonitor_kqueue(struct dirmonitor* monitor, const char* path) { | ||
int fd = open(path, O_RDONLY); | ||
struct kevent change; | ||
|
||
EV_SET(&change, fd, EVFILT_VNODE, EV_ADD | EV_CLEAR, NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB | NOTE_LINK | NOTE_RENAME, 0, (void*)path); | ||
kevent(monitor->fd, &change, 1, NULL, 0, NULL); | ||
|
||
return fd; | ||
} | ||
|
||
void remove_dirmonitor_kqueue(struct dirmonitor* monitor, int fd) { | ||
close(fd); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
#include <stdbool.h> | ||
#include <windows.h> | ||
|
||
struct dirmonitor { | ||
HANDLE handle; | ||
char buffer[8192]; | ||
OVERLAPPED overlapped; | ||
bool running; | ||
}; | ||
|
||
struct dirmonitor* init_dirmonitor_win32() { | ||
struct dirmonitor* monitor = calloc(sizeof(struct dirmonitor), 1); | ||
|
||
return monitor; | ||
} | ||
|
||
static void close_monitor_handle(struct dirmonitor* monitor) { | ||
if (monitor->handle) { | ||
if (monitor->running) { | ||
BOOL result = CancelIoEx(monitor->handle, &monitor->overlapped); | ||
DWORD error = GetLastError(); | ||
if (result == TRUE || error != ERROR_NOT_FOUND) { | ||
DWORD bytes_transferred; | ||
GetOverlappedResult( monitor->handle, &monitor->overlapped, &bytes_transferred, TRUE ); | ||
} | ||
monitor->running = false; | ||
} | ||
CloseHandle(monitor->handle); | ||
} | ||
monitor->handle = NULL; | ||
} | ||
|
||
void deinit_dirmonitor_win32(struct dirmonitor* monitor) { | ||
close_monitor_handle(monitor); | ||
free(monitor); | ||
} | ||
|
||
int check_dirmonitor_win32(struct dirmonitor* monitor, int (*change_callback)(int, const char*, void*), void* data) { | ||
if (!monitor->running) { | ||
if (ReadDirectoryChangesW(monitor->handle, monitor->buffer, sizeof(monitor->buffer), TRUE, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME, NULL, &monitor->overlapped, NULL) == 0) { | ||
return GetLastError(); | ||
} | ||
monitor->running = true; | ||
} | ||
|
||
DWORD bytes_transferred; | ||
|
||
if (!GetOverlappedResult(monitor->handle, &monitor->overlapped, &bytes_transferred, FALSE)) { | ||
int error = GetLastError(); | ||
return error == ERROR_IO_PENDING || error == ERROR_IO_INCOMPLETE ? 0 : error; | ||
} | ||
|
||
monitor->running = false; | ||
|
||
for (FILE_NOTIFY_INFORMATION* info = (FILE_NOTIFY_INFORMATION*)monitor->buffer; (char*)info < monitor->buffer + sizeof(monitor->buffer); info = (FILE_NOTIFY_INFORMATION*)((char*)info) + info->NextEntryOffset) { | ||
change_callback(info->FileNameLength, (char*)info->FileName, data); | ||
if (!info->NextEntryOffset) | ||
break; | ||
} | ||
|
||
monitor->running = false; | ||
return 0; | ||
} | ||
|
||
int add_dirmonitor_win32(struct dirmonitor* monitor, const char* path) { | ||
close_monitor_handle(monitor); | ||
monitor->handle = CreateFileA(path, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL); | ||
if (monitor->handle && monitor->handle != INVALID_HANDLE_VALUE) { | ||
return 1; | ||
} | ||
monitor->handle = NULL; | ||
return -1; | ||
} | ||
|
||
void remove_dirmonitor_win32(struct dirmonitor* monitor, int fd) { | ||
close_monitor_handle(monitor); | ||
} |
Oops, something went wrong.