Update dmon.h with new macOS fixes

This commit is contained in:
Francesco Abbate 2021-10-03 00:00:20 +02:00
parent b83c1ade9b
commit ed483106ec
1 changed files with 25 additions and 17 deletions

View File

@ -1318,6 +1318,7 @@ typedef struct dmon__watch_state {
dmon__watch_cb* watch_cb; dmon__watch_cb* watch_cb;
void* user_data; void* user_data;
char rootdir[DMON_MAX_PATH]; char rootdir[DMON_MAX_PATH];
char rootdir_unmod[DMON_MAX_PATH];
bool init; bool init;
} dmon__watch_state; } dmon__watch_state;
@ -1425,22 +1426,22 @@ _DMON_PRIVATE void dmon__fsevent_process_events(void)
} }
if (ev->event_flags & kFSEventStreamEventFlagItemCreated) { if (ev->event_flags & kFSEventStreamEventFlagItemCreated) {
watch->watch_cb(ev->watch_id, DMON_ACTION_CREATE, watch->rootdir, ev->filepath, NULL, watch->watch_cb(ev->watch_id, DMON_ACTION_CREATE, watch->rootdir_unmod, ev->filepath, NULL,
watch->user_data); watch->user_data);
} else if (ev->event_flags & kFSEventStreamEventFlagItemModified) { } else if (ev->event_flags & kFSEventStreamEventFlagItemModified) {
watch->watch_cb(ev->watch_id, DMON_ACTION_MODIFY, watch->rootdir, ev->filepath, NULL, watch->watch_cb(ev->watch_id, DMON_ACTION_MODIFY, watch->rootdir_unmod, ev->filepath, NULL,
watch->user_data); watch->user_data);
} else if (ev->event_flags & kFSEventStreamEventFlagItemRenamed) { } else if (ev->event_flags & kFSEventStreamEventFlagItemRenamed) {
for (int j = i + 1; j < c; j++) { for (int j = i + 1; j < c; j++) {
dmon__fsevent_event* check_ev = &_dmon.events[j]; dmon__fsevent_event* check_ev = &_dmon.events[j];
if (check_ev->event_flags & kFSEventStreamEventFlagItemRenamed) { if (check_ev->event_flags & kFSEventStreamEventFlagItemRenamed) {
watch->watch_cb(check_ev->watch_id, DMON_ACTION_MOVE, watch->rootdir, watch->watch_cb(check_ev->watch_id, DMON_ACTION_MOVE, watch->rootdir_unmod,
check_ev->filepath, ev->filepath, watch->user_data); check_ev->filepath, ev->filepath, watch->user_data);
break; break;
} }
} }
} else if (ev->event_flags & kFSEventStreamEventFlagItemRemoved) { } else if (ev->event_flags & kFSEventStreamEventFlagItemRemoved) {
watch->watch_cb(ev->watch_id, DMON_ACTION_DELETE, watch->rootdir, ev->filepath, NULL, watch->watch_cb(ev->watch_id, DMON_ACTION_DELETE, watch->rootdir_unmod, ev->filepath, NULL,
watch->user_data); watch->user_data);
} }
} }
@ -1563,6 +1564,7 @@ _DMON_PRIVATE void dmon__fsevent_callback(ConstFSEventStreamRef stream_ref, void
DMON_ASSERT(watch_id.id > 0); DMON_ASSERT(watch_id.id > 0);
dmon__watch_state* watch = &_dmon.watches[watch_id.id - 1]; dmon__watch_state* watch = &_dmon.watches[watch_id.id - 1];
char abs_filepath[DMON_MAX_PATH]; char abs_filepath[DMON_MAX_PATH];
char abs_filepath_lower[DMON_MAX_PATH];
for (size_t i = 0; i < num_events; i++) { for (size_t i = 0; i < num_events; i++) {
const char* filepath = ((const char**)event_paths)[i]; const char* filepath = ((const char**)event_paths)[i];
@ -1572,17 +1574,14 @@ _DMON_PRIVATE void dmon__fsevent_callback(ConstFSEventStreamRef stream_ref, void
memset(&ev, 0x0, sizeof(ev)); memset(&ev, 0x0, sizeof(ev));
dmon__strcpy(abs_filepath, sizeof(abs_filepath), filepath); dmon__strcpy(abs_filepath, sizeof(abs_filepath), filepath);
dmon__unixpath(abs_filepath, sizeof(abs_filepath), abs_filepath);
// normalize path (TODO: have to recheck this to be consistent with other platforms) // normalize path, so it would be the same on both MacOS file-system types (case/nocase)
dmon__tolower(abs_filepath, sizeof(abs_filepath), dmon__tolower(abs_filepath_lower, sizeof(abs_filepath), abs_filepath);
dmon__unixpath(abs_filepath, sizeof(abs_filepath), abs_filepath)); DMON_ASSERT(strstr(abs_filepath_lower, watch->rootdir) == abs_filepath_lower);
// strip the root dir // strip the root dir from the begining
size_t len = strlen(watch->rootdir); dmon__strcpy(ev.filepath, sizeof(ev.filepath), abs_filepath + strlen(watch->rootdir));
// FIXME: filesystems on macOS can be case sensitive or not. The check below
// ignore case but we should check if the filesystem is case sensitive.
DMON_ASSERT(strncasecmp(abs_filepath, watch->rootdir, len) == 0);
dmon__strcpy(ev.filepath, sizeof(ev.filepath), abs_filepath + len);
ev.event_flags = flags; ev.event_flags = flags;
ev.event_id = event_id; ev.event_id = event_id;
@ -1630,16 +1629,22 @@ DMON_API_IMPL dmon_watch_id dmon_watch(const char* rootdir,
dmon__strcpy(watch->rootdir, sizeof(watch->rootdir) - 1, linkpath); dmon__strcpy(watch->rootdir, sizeof(watch->rootdir) - 1, linkpath);
} else { } else {
_DMON_LOG_ERRORF("symlinks are unsupported: %s. use DMON_WATCHFLAGS_FOLLOW_SYMLINKS", _DMON_LOG_ERRORF("symlinks are unsupported: %s. use DMON_WATCHFLAGS_FOLLOW_SYMLINKS", rootdir);
rootdir);
pthread_mutex_unlock(&_dmon.mutex); pthread_mutex_unlock(&_dmon.mutex);
__sync_lock_test_and_set(&_dmon.modify_watches, 0); __sync_lock_test_and_set(&_dmon.modify_watches, 0);
return dmon__make_id(0); return dmon__make_id(0);
} }
} else { } else {
dmon__strcpy(watch->rootdir, sizeof(watch->rootdir) - 1, rootdir); char rootdir_abspath[DMON_MAX_PATH];
if (realpath(rootdir, rootdir_abspath) != NULL) {
dmon__strcpy(watch->rootdir, sizeof(watch->rootdir) - 1, rootdir_abspath);
} else {
dmon__strcpy(watch->rootdir, sizeof(watch->rootdir) - 1, rootdir);
}
} }
dmon__unixpath(watch->rootdir, sizeof(watch->rootdir), watch->rootdir);
// add trailing slash // add trailing slash
int rootdir_len = (int)strlen(watch->rootdir); int rootdir_len = (int)strlen(watch->rootdir);
if (watch->rootdir[rootdir_len - 1] != '/') { if (watch->rootdir[rootdir_len - 1] != '/') {
@ -1647,8 +1652,11 @@ DMON_API_IMPL dmon_watch_id dmon_watch(const char* rootdir,
watch->rootdir[rootdir_len + 1] = '\0'; watch->rootdir[rootdir_len + 1] = '\0';
} }
dmon__strcpy(watch->rootdir_unmod, sizeof(watch->rootdir_unmod), watch->rootdir);
dmon__tolower(watch->rootdir, sizeof(watch->rootdir), watch->rootdir);
// create FS objects // create FS objects
CFStringRef cf_dir = CFStringCreateWithCString(NULL, watch->rootdir, kCFStringEncodingUTF8); CFStringRef cf_dir = CFStringCreateWithCString(NULL, watch->rootdir_unmod, kCFStringEncodingUTF8);
CFArrayRef cf_dirarr = CFArrayCreate(NULL, (const void**)&cf_dir, 1, NULL); CFArrayRef cf_dirarr = CFArrayCreate(NULL, (const void**)&cf_dir, 1, NULL);
FSEventStreamContext ctx; FSEventStreamContext ctx;