darwin: look up file path with F_GETPATH
Look up the file path with fcntl(F_GETPATH) and pass it to the uv_fs_event_cb callback.
This commit is contained in:
parent
fcac38abe4
commit
145f7b3560
@ -26,6 +26,7 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h> /* abort */
|
||||
#include <string.h> /* strrchr */
|
||||
|
||||
#if defined(__STRICT_ANSI__)
|
||||
# define inline __inline
|
||||
@ -256,6 +257,18 @@ static void uv__update_time(uv_loop_t* loop) {
|
||||
loop->time = uv__hrtime() / 1000000;
|
||||
}
|
||||
|
||||
__attribute__((unused))
|
||||
static char* uv__basename_r(const char* path) {
|
||||
char* s;
|
||||
|
||||
s = strrchr(path, '/');
|
||||
if (s == NULL)
|
||||
return (char*) path;
|
||||
|
||||
return s + 1;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_DTRACE
|
||||
#include "uv-dtrace.h"
|
||||
#else
|
||||
|
||||
@ -259,6 +259,11 @@ static void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int fflags) {
|
||||
uv_fs_event_t* handle;
|
||||
struct kevent ev;
|
||||
int events;
|
||||
const char* path;
|
||||
#if defined(F_GETPATH)
|
||||
/* MAXPATHLEN == PATH_MAX but the former is what XNU calls it internally. */
|
||||
char pathbuf[MAXPATHLEN];
|
||||
#endif
|
||||
|
||||
handle = container_of(w, uv_fs_event_t, event_watcher);
|
||||
|
||||
@ -267,7 +272,16 @@ static void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int fflags) {
|
||||
else
|
||||
events = UV_RENAME;
|
||||
|
||||
handle->cb(handle, NULL, events, 0);
|
||||
path = NULL;
|
||||
#if defined(F_GETPATH)
|
||||
/* Also works when the file has been unlinked from the file system. Passing
|
||||
* in the path when the file has been deleted is arguably a little strange
|
||||
* but it's consistent with what the inotify backend does.
|
||||
*/
|
||||
if (fcntl(handle->event_watcher.fd, F_GETPATH, pathbuf) == 0)
|
||||
path = uv__basename_r(pathbuf);
|
||||
#endif
|
||||
handle->cb(handle, path, events, 0);
|
||||
|
||||
if (handle->event_watcher.fd == -1)
|
||||
return;
|
||||
|
||||
@ -45,13 +45,6 @@ struct watcher_root {
|
||||
#define CAST(p) ((struct watcher_root*)(p))
|
||||
|
||||
|
||||
/* Don't look aghast, this is exactly how glibc's basename() works. */
|
||||
static char* basename_r(const char* path) {
|
||||
char* s = strrchr(path, '/');
|
||||
return s ? (s + 1) : (char*)path;
|
||||
}
|
||||
|
||||
|
||||
static int compare_watchers(const struct watcher_list* a,
|
||||
const struct watcher_list* b) {
|
||||
if (a->wd < b->wd) return -1;
|
||||
@ -156,7 +149,7 @@ static void uv__inotify_read(uv_loop_t* loop,
|
||||
* for modifications. Repurpose the filename for API compatibility.
|
||||
* I'm not convinced this is a good thing, maybe it should go.
|
||||
*/
|
||||
path = e->len ? (const char*) (e + 1) : basename_r(w->path);
|
||||
path = e->len ? (const char*) (e + 1) : uv__basename_r(w->path);
|
||||
|
||||
QUEUE_FOREACH(q, &w->watchers) {
|
||||
h = QUEUE_DATA(q, uv_fs_event_t, watchers);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user