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:
Ben Noordhuis 2013-04-10 19:29:16 +02:00 committed by Bert Belder
parent fcac38abe4
commit 145f7b3560
3 changed files with 29 additions and 9 deletions

View File

@ -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

View File

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

View File

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