darwin: emit relative path in fsevents

This commit is contained in:
Fedor Indutny 2012-09-18 00:38:40 +04:00 committed by Ben Noordhuis
parent be2a2176ce
commit 778144f0b5
8 changed files with 67 additions and 18 deletions

View File

@ -41,6 +41,9 @@
ev_io event_watcher; \
int fflags; \
int fd; \
char* realpath; \
int realpath_len; \
int cf_flags; \
void* cf_eventstream; \
uv_async_t* cf_cb; \
ngx_queue_t cf_events; \

View File

@ -1675,7 +1675,14 @@ enum uv_fs_event_flags {
* regular interval.
* This flag is currently not implemented yet on any backend.
*/
UV_FS_EVENT_STAT = 2
UV_FS_EVENT_STAT = 2,
/*
* By default, event watcher, when watching directory, is not registering
* (is ignoring) changes in it's subdirectories.
* This flag will override this behaviour on platforms that support it.
*/
UV_FS_EVENT_RECURSIVE = 3
};

View File

@ -66,8 +66,13 @@ void uv__fsevents_cb(uv_async_t* cb, int status) {
handle = cb->data;
UV__FSEVENTS_WALK(handle, {
if (handle->fd != -1)
if (handle->fd != -1) {
#ifdef MAC_OS_X_VERSION_10_7
handle->cb(handle, event->path, event->events, 0);
#else
handle->cb(handle, NULL, event->events, 0);
#endif /* MAC_OS_X_VERSION_10_7 */
}
})
if ((handle->flags & (UV_CLOSING | UV_CLOSED)) == 0 && handle->fd == -1)
@ -84,6 +89,8 @@ void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef,
size_t i;
int len;
char** paths;
char* path;
char* pos;
uv_fs_event_t* handle;
uv__fsevents_event_t* event;
ngx_queue_t add_list;
@ -99,17 +106,50 @@ void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef,
kFSEventStreamEventFlagEventIdsWrapped |
kFSEventStreamEventFlagHistoryDone |
kFSEventStreamEventFlagMount |
kFSEventStreamEventFlagUnmount)) {
kFSEventStreamEventFlagUnmount |
kFSEventStreamEventFlagRootChanged)) {
continue;
}
/* TODO: Report errors */
len = strlen(paths[i]);
path = paths[i];
len = strlen(path);
/* Remove absolute path prefix */
if (strstr(path, handle->realpath) == path) {
path += handle->realpath_len;
len -= handle->realpath_len;
/* Skip back slash */
if (*path != 0) {
path++;
len--;
}
}
#ifdef MAC_OS_X_VERSION_10_7
/* Ignore events with path equal to directory itself */
if (len == 0)
continue;
#endif /* MAC_OS_X_VERSION_10_7 */
/* Do not emit events from subdirectories (without option set) */
pos = strchr(path, '/');
if ((handle->cf_flags & UV_FS_EVENT_RECURSIVE) == 0 &&
pos != NULL &&
pos != path + 1)
continue;
#ifndef MAC_OS_X_VERSION_10_7
path = "";
len = 0;
#endif /* MAC_OS_X_VERSION_10_7 */
event = malloc(sizeof(*event) + len);
if (event == NULL)
break;
memcpy(event->path, paths[i], len + 1);
memcpy(event->path, path, len + 1);
if (eventFlags[i] & kFSEventStreamEventFlagItemModified)
event->events = UV_CHANGE;
@ -153,6 +193,11 @@ int uv__fsevents_init(uv_fs_event_t* handle) {
ctx.release = NULL;
ctx.copyDescription = NULL;
/* Get absolute path to file */
handle->realpath = realpath(handle->filename, NULL);
if (handle->realpath != NULL)
handle->realpath_len = strlen(handle->realpath);
/* Initialize paths array */
path = CFStringCreateWithCString(NULL,
handle->filename,
@ -220,6 +265,9 @@ int uv__fsevents_close(uv_fs_event_t* handle) {
uv_mutex_destroy(&handle->cf_mutex);
uv_sem_destroy(&handle->cf_sem);
free(handle->realpath);
handle->realpath = NULL;
handle->realpath_len = 0;
return 0;
}

View File

@ -93,9 +93,6 @@ int uv_fs_event_init(uv_loop_t* loop,
struct stat statbuf;
#endif /* defined(__APPLE__) */
/* We don't support any flags yet. */
assert(!flags);
/* TODO open asynchronously - but how do we report back errors? */
if ((fd = open(filename, O_RDONLY)) == -1) {
uv__set_sys_error(loop, errno);
@ -112,6 +109,9 @@ int uv_fs_event_init(uv_loop_t* loop,
#if defined(__APPLE__)
/* Nullify field to perform checks later */
handle->cf_eventstream = NULL;
handle->realpath = NULL;
handle->realpath_len = 0;
handle->cf_flags = flags;
if (fstat(fd, &statbuf))
goto fallback;

View File

@ -176,9 +176,6 @@ int uv_fs_event_init(uv_loop_t* loop,
int events;
int wd;
/* We don't support any flags yet. */
assert(!flags);
if (init_inotify(loop)) return -1;
events = UV__IN_ATTRIB

View File

@ -196,8 +196,6 @@ int uv_fs_event_init(uv_loop_t* loop,
int portfd;
int first_run = 0;
/* We don't support any flags yet. */
assert(!flags);
if (loop->fs_fd == -1) {
if ((portfd = port_create()) == -1) {
uv__set_sys_error(loop, errno);

View File

@ -138,9 +138,6 @@ int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle,
WCHAR* dir = NULL, *dir_to_watch, *filenamew = NULL;
WCHAR short_path[MAX_PATH];
/* We don't support any flags yet. */
assert(!flags);
uv_fs_event_init_handle(loop, handle, filename, cb);
/* Convert name to UTF16. */

View File

@ -98,8 +98,7 @@ static void fs_event_cb_dir(uv_fs_event_t* handle, const char* filename,
ASSERT(handle == &fs_event);
ASSERT(status == 0);
ASSERT(events == UV_RENAME);
ASSERT(filename == NULL || strcmp(filename, "file1") == 0 ||
strstr(filename, "watch_dir") != NULL);
ASSERT(filename == NULL || strcmp(filename, "file1") == 0);
uv_close((uv_handle_t*)handle, close_cb);
}