From 648a0726d01b1c0d075560bc9036252635c8f12f Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Sat, 23 Mar 2013 19:17:12 +0100 Subject: [PATCH] deps: upgrade libuv to eca008a --- deps/uv/include/uv-private/uv-unix.h | 1 - deps/uv/include/uv-private/uv-win.h | 2 - deps/uv/include/uv.h | 60 +++++++++++++----------- deps/uv/src/fs-poll.c | 49 ++++---------------- deps/uv/src/unix/fs.c | 69 ++++++++++++++++++++++++++-- deps/uv/src/win/fs.c | 26 ++++++++--- deps/uv/test/test-fs-poll.c | 10 ++-- deps/uv/test/test-fs.c | 66 +++++++++++++++++++------- 8 files changed, 182 insertions(+), 101 deletions(-) diff --git a/deps/uv/include/uv-private/uv-unix.h b/deps/uv/include/uv-private/uv-unix.h index 729082e0bc..61f5d18b1c 100644 --- a/deps/uv/include/uv-private/uv-unix.h +++ b/deps/uv/include/uv-private/uv-unix.h @@ -121,7 +121,6 @@ typedef struct { typedef int uv_file; typedef int uv_os_sock_t; -typedef struct stat uv_statbuf_t; #define UV_ONCE_INIT PTHREAD_ONCE_INIT diff --git a/deps/uv/include/uv-private/uv-win.h b/deps/uv/include/uv-private/uv-win.h index c9ec38ef4c..b1c4179c8f 100644 --- a/deps/uv/include/uv-private/uv-win.h +++ b/deps/uv/include/uv-private/uv-win.h @@ -207,8 +207,6 @@ typedef struct uv_buf_t { typedef int uv_file; -typedef struct _stati64 uv_statbuf_t; - typedef SOCKET uv_os_sock_t; typedef HANDLE uv_thread_t; diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h index ea11a13bfd..3986ec85df 100644 --- a/deps/uv/include/uv.h +++ b/deps/uv/include/uv.h @@ -350,6 +350,29 @@ typedef void (*uv_getaddrinfo_cb)(uv_getaddrinfo_t* req, int status, struct addrinfo* res); +typedef struct { + long tv_sec; + long tv_nsec; +} uv_timespec_t; + + +typedef struct { + uint64_t st_dev; + uint64_t st_mode; + uint64_t st_nlink; + uint64_t st_uid; + uint64_t st_gid; + uint64_t st_rdev; + uint64_t st_ino; + uint64_t st_size; + uint64_t st_blksize; + uint64_t st_blocks; + uv_timespec_t st_atim; + uv_timespec_t st_mtim; + uv_timespec_t st_ctim; +} uv_stat_t; + + /* * This will be called repeatedly after the uv_fs_event_t is initialized. * If uv_fs_event_t was initialized with a directory the filename parameter @@ -361,8 +384,8 @@ typedef void (*uv_fs_event_cb)(uv_fs_event_t* handle, const char* filename, typedef void (*uv_fs_poll_cb)(uv_fs_poll_t* handle, int status, - const uv_statbuf_t* prev, - const uv_statbuf_t* curr); + const uv_stat_t* prev, + const uv_stat_t* curr); typedef void (*uv_signal_cb)(uv_signal_t* handle, int signum); @@ -1519,7 +1542,7 @@ struct uv_fs_s { void* ptr; const char* path; uv_err_code errorno; - uv_statbuf_t statbuf; /* Stores the result of uv_fs_stat and uv_fs_fstat. */ + uv_stat_t statbuf; /* Stores the result of uv_fs_stat and uv_fs_fstat. */ UV_FS_PRIVATE_FIELDS }; @@ -1646,7 +1669,7 @@ UV_EXTERN int uv_fs_poll_init(uv_loop_t* loop, uv_fs_poll_t* handle); * or the error reason changes). * * When `status == 0`, your callback receives pointers to the old and new - * `uv_statbuf_t` structs. They are valid for the duration of the callback + * `uv_stat_t` structs. They are valid for the duration of the callback * only! * * For maximum portability, use multi-second intervals. Sub-second intervals @@ -1902,35 +1925,16 @@ UV_EXTERN int uv_thread_create(uv_thread_t *tid, UV_EXTERN unsigned long uv_thread_self(void); UV_EXTERN int uv_thread_join(uv_thread_t *tid); -/* the presence of these unions force similar struct layout */ +/* The presence of these unions force similar struct layout. */ +#define XX(_, name) uv_ ## name ## _t name; union uv_any_handle { - uv_handle_t handle; - uv_stream_t stream; - uv_tcp_t tcp; - uv_pipe_t pipe; - uv_prepare_t prepare; - uv_check_t check; - uv_idle_t idle; - uv_async_t async; - uv_timer_t timer; - uv_fs_event_t fs_event; - uv_fs_poll_t fs_poll; - uv_poll_t poll; - uv_process_t process; - uv_tty_t tty; - uv_udp_t udp; + UV_HANDLE_TYPE_MAP(XX) }; union uv_any_req { - uv_req_t req; - uv_write_t write; - uv_connect_t connect; - uv_shutdown_t shutdown; - uv_fs_t fs_req; - uv_work_t work_req; - uv_udp_send_t udp_send_req; - uv_getaddrinfo_t getaddrinfo_req; + UV_REQ_TYPE_MAP(XX) }; +#undef XX struct uv_loop_s { diff --git a/deps/uv/src/fs-poll.c b/deps/uv/src/fs-poll.c index ad27f18432..9b2d03eef9 100644 --- a/deps/uv/src/fs-poll.c +++ b/deps/uv/src/fs-poll.c @@ -35,16 +35,16 @@ struct poll_ctx { uv_fs_poll_cb poll_cb; uv_timer_t timer_handle; uv_fs_t fs_req; /* TODO(bnoordhuis) mark fs_req internal */ - uv_statbuf_t statbuf; + uv_stat_t statbuf; char path[1]; /* variable length */ }; -static int statbuf_eq(const uv_statbuf_t* a, const uv_statbuf_t* b); +static int statbuf_eq(const uv_stat_t* a, const uv_stat_t* b); static void poll_cb(uv_fs_t* req); static void timer_cb(uv_timer_t* timer, int status); static void timer_close_cb(uv_handle_t* handle); -static uv_statbuf_t zero_statbuf; +static uv_stat_t zero_statbuf; int uv_fs_poll_init(uv_loop_t* loop, uv_fs_poll_t* handle) { @@ -137,7 +137,7 @@ static void timer_cb(uv_timer_t* timer, int status) { static void poll_cb(uv_fs_t* req) { - uv_statbuf_t* statbuf; + uv_stat_t* statbuf; struct poll_ctx* ctx; uint64_t interval; @@ -189,48 +189,17 @@ static void timer_close_cb(uv_handle_t* handle) { } -static int statbuf_eq(const uv_statbuf_t* a, const uv_statbuf_t* b) { -#if defined(_WIN32) - return a->st_mtime == b->st_mtime - && a->st_size == b->st_size - && a->st_mode == b->st_mode; -#else - - /* Jump through a few hoops to get sub-second granularity on Linux. */ -# if defined(__linux__) -# if defined(__USE_MISC) /* _BSD_SOURCE || _SVID_SOURCE */ - if (a->st_ctim.tv_nsec != b->st_ctim.tv_nsec) return 0; - if (a->st_mtim.tv_nsec != b->st_mtim.tv_nsec) return 0; -# else - if (a->st_ctimensec != b->st_ctimensec) return 0; - if (a->st_mtimensec != b->st_mtimensec) return 0; -# endif -# endif - - /* Jump through different hoops on OS X. */ -# if defined(__APPLE__) -# if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) - if (a->st_ctimespec.tv_nsec != b->st_ctimespec.tv_nsec) return 0; - if (a->st_mtimespec.tv_nsec != b->st_mtimespec.tv_nsec) return 0; -# else - if (a->st_ctimensec != b->st_ctimensec) return 0; - if (a->st_mtimensec != b->st_mtimensec) return 0; -# endif -# endif - - /* TODO(bnoordhuis) Other Unices have st_ctim and friends too, provided - * the stars and compiler flags are right... - */ - - return a->st_ctime == b->st_ctime - && a->st_mtime == b->st_mtime +static int statbuf_eq(const uv_stat_t* a, const uv_stat_t* b) { + return a->st_ctim.tv_nsec == b->st_ctim.tv_nsec + && a->st_mtim.tv_nsec == b->st_mtim.tv_nsec + && a->st_ctim.tv_sec == b->st_ctim.tv_sec + && a->st_mtim.tv_sec == b->st_mtim.tv_sec && a->st_size == b->st_size && a->st_mode == b->st_mode && a->st_uid == b->st_uid && a->st_gid == b->st_gid && a->st_ino == b->st_ino && a->st_dev == b->st_dev; -#endif } diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c index 53f46ce7c7..fb8cdb25b1 100644 --- a/deps/uv/src/unix/fs.c +++ b/deps/uv/src/unix/fs.c @@ -497,6 +497,69 @@ static ssize_t uv__fs_write(uv_fs_t* req) { return r; } +static inline void uv__to_stat(struct stat* src, uv_stat_t* dst) { + dst->st_dev = src->st_dev; + dst->st_mode = src->st_mode; + dst->st_nlink = src->st_nlink; + dst->st_uid = src->st_uid; + dst->st_gid = src->st_gid; + dst->st_rdev = src->st_rdev; + dst->st_ino = src->st_ino; + dst->st_size = src->st_size; + dst->st_blksize = src->st_blksize; + dst->st_blocks = src->st_blocks; + +#if defined(__APPLE__) + dst->st_atim.tv_sec = src->st_atimespec.tv_sec; + dst->st_atim.tv_nsec = src->st_atimespec.tv_nsec; + dst->st_mtim.tv_sec = src->st_mtimespec.tv_sec; + dst->st_mtim.tv_nsec = src->st_mtimespec.tv_nsec; + dst->st_ctim.tv_sec = src->st_ctimespec.tv_sec; + dst->st_ctim.tv_nsec = src->st_ctimespec.tv_nsec; +#elif defined(_BSD_SOURCE) || defined(_SVID_SOURCE) || defined(_XOPEN_SOURCE) + dst->st_atim.tv_sec = src->st_atim.tv_sec; + dst->st_atim.tv_nsec = src->st_atim.tv_nsec; + dst->st_mtim.tv_sec = src->st_mtim.tv_sec; + dst->st_mtim.tv_nsec = src->st_mtim.tv_nsec; + dst->st_ctim.tv_sec = src->st_ctim.tv_sec; + dst->st_ctim.tv_nsec = src->st_ctim.tv_nsec; +#else + dst->st_atim.tv_sec = src->st_atime; + dst->st_atim.tv_nsec = 0; + dst->st_mtim.tv_sec = src->st_mtime; + dst->st_mtim.tv_nsec = 0; + dst->st_ctim.tv_sec = src->st_ctime; + dst->st_ctim.tv_nsec = 0; +#endif +} + + +static int uv__fs_stat(const char *path, uv_stat_t *buf) { + struct stat pbuf; + int ret; + ret = stat(path, &pbuf); + uv__to_stat(&pbuf, buf); + return ret; +} + + +static int uv__fs_lstat(const char *path, uv_stat_t *buf) { + struct stat pbuf; + int ret; + ret = lstat(path, &pbuf); + uv__to_stat(&pbuf, buf); + return ret; +} + + +static int uv__fs_fstat(int fd, uv_stat_t *buf) { + struct stat pbuf; + int ret; + ret = fstat(fd, &pbuf); + uv__to_stat(&pbuf, buf); + return ret; +} + static void uv__fs_work(struct uv__work* w) { int retry_on_eintr; @@ -521,11 +584,11 @@ static void uv__fs_work(struct uv__work* w) { X(FCHMOD, fchmod(req->file, req->mode)); X(FCHOWN, fchown(req->file, req->uid, req->gid)); X(FDATASYNC, uv__fs_fdatasync(req)); - X(FSTAT, fstat(req->file, &req->statbuf)); + X(FSTAT, uv__fs_fstat(req->file, &req->statbuf)); X(FSYNC, fsync(req->file)); X(FTRUNCATE, ftruncate(req->file, req->off)); X(FUTIME, uv__fs_futime(req)); - X(LSTAT, lstat(req->path, &req->statbuf)); + X(LSTAT, uv__fs_lstat(req->path, &req->statbuf)); X(LINK, link(req->path, req->new_path)); X(MKDIR, mkdir(req->path, req->mode)); X(OPEN, open(req->path, req->flags, req->mode)); @@ -535,7 +598,7 @@ static void uv__fs_work(struct uv__work* w) { X(RENAME, rename(req->path, req->new_path)); X(RMDIR, rmdir(req->path)); X(SENDFILE, uv__fs_sendfile(req)); - X(STAT, stat(req->path, &req->statbuf)); + X(STAT, uv__fs_stat(req->path, &req->statbuf)); X(SYMLINK, symlink(req->path, req->new_path)); X(UNLINK, unlink(req->path)); X(UTIME, uv__fs_utime(req)); diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c index 60e67a41d5..c32b84bf13 100644 --- a/deps/uv/src/win/fs.c +++ b/deps/uv/src/win/fs.c @@ -77,8 +77,20 @@ return; \ } +#define FILETIME_TO_UINT(filetime) \ + (*((uint64_t*) &(filetime)) - 116444736000000000ULL) + #define FILETIME_TO_TIME_T(filetime) \ - ((*((uint64_t*) &(filetime)) - 116444736000000000ULL) / 10000000ULL); + (FILETIME_TO_UINT(filetime) / 10000000ULL); + +#define FILETIME_TO_TIME_NS(filetime, secs) \ + ((FILETIME_TO_UINT(filetime) - (secs * 10000000ULL)) * 100); + +#define FILETIME_TO_TIMESPEC(ts, filetime) \ + do { \ + (ts).tv_sec = FILETIME_TO_TIME_T(filetime); \ + (ts).tv_nsec = FILETIME_TO_TIME_NS(filetime, (ts).tv_sec); \ + } while(0) #define TIME_T_TO_FILETIME(time, filetime_ptr) \ do { \ @@ -86,7 +98,6 @@ 116444736000000000ULL; \ } while(0) - #define IS_SLASH(c) ((c) == L'\\' || (c) == L'/') #define IS_LETTER(c) (((c) >= L'a' && (c) <= L'z') || \ ((c) >= L'A' && (c) <= L'Z')) @@ -808,7 +819,7 @@ void fs__readdir(uv_fs_t* req) { } -INLINE static int fs__stat_handle(HANDLE handle, uv_statbuf_t* statbuf) { +INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf) { BY_HANDLE_FILE_INFORMATION info; if (!GetFileInformationByHandle(handle, &info)) { @@ -825,6 +836,9 @@ INLINE static int fs__stat_handle(HANDLE handle, uv_statbuf_t* statbuf) { statbuf->st_mode = 0; + statbuf->st_blksize = 0; + statbuf->st_blocks = 0; + if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { if (fs__readlink_handle(handle, NULL, &statbuf->st_size) != 0) { return -1; @@ -846,9 +860,9 @@ INLINE static int fs__stat_handle(HANDLE handle, uv_statbuf_t* statbuf) { ((_S_IREAD|_S_IWRITE) >> 6)); } - statbuf->st_mtime = FILETIME_TO_TIME_T(info.ftLastWriteTime); - statbuf->st_atime = FILETIME_TO_TIME_T(info.ftLastAccessTime); - statbuf->st_ctime = FILETIME_TO_TIME_T(info.ftCreationTime); + FILETIME_TO_TIMESPEC(statbuf->st_mtim, info.ftLastWriteTime); + FILETIME_TO_TIMESPEC(statbuf->st_atim, info.ftLastAccessTime); + FILETIME_TO_TIMESPEC(statbuf->st_ctim, info.ftCreationTime); statbuf->st_nlink = (info.nNumberOfLinks <= SHRT_MAX) ? (short) info.nNumberOfLinks : SHRT_MAX; diff --git a/deps/uv/test/test-fs-poll.c b/deps/uv/test/test-fs-poll.c index f312d87f80..87884181bc 100644 --- a/deps/uv/test/test-fs-poll.c +++ b/deps/uv/test/test-fs-poll.c @@ -30,8 +30,8 @@ static void timer_cb(uv_timer_t* handle, int status); static void close_cb(uv_handle_t* handle); static void poll_cb(uv_fs_poll_t* handle, int status, - const uv_statbuf_t* prev, - const uv_statbuf_t* curr); + const uv_stat_t* prev, + const uv_stat_t* curr); static uv_fs_poll_t poll_handle; static uv_timer_t timer_handle; @@ -74,9 +74,9 @@ static void timer_cb(uv_timer_t* handle, int status) { static void poll_cb(uv_fs_poll_t* handle, int status, - const uv_statbuf_t* prev, - const uv_statbuf_t* curr) { - uv_statbuf_t zero_statbuf; + const uv_stat_t* prev, + const uv_stat_t* curr) { + uv_stat_t zero_statbuf; memset(&zero_statbuf, 0, sizeof(zero_statbuf)); diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c index 0016b3bede..6459d125cf 100644 --- a/deps/uv/test/test-fs.c +++ b/deps/uv/test/test-fs.c @@ -107,7 +107,7 @@ static char test_buf[] = "test-buffer\n"; static void check_permission(const char* filename, int mode) { int r; uv_fs_t req; - uv_statbuf_t* s; + uv_stat_t* s; r = uv_fs_stat(uv_default_loop(), &req, filename, NULL); ASSERT(r == 0); @@ -213,7 +213,7 @@ static void unlink_cb(uv_fs_t* req) { } static void fstat_cb(uv_fs_t* req) { - struct stat* s = req->ptr; + uv_stat_t* s = req->ptr; ASSERT(req->fs_type == UV_FS_FSTAT); ASSERT(req->result == 0); ASSERT(s->st_size == sizeof(test_buf)); @@ -543,7 +543,7 @@ TEST_IMPL(fs_file_loop) { } static void check_utime(const char* path, double atime, double mtime) { - uv_statbuf_t* s; + uv_stat_t* s; uv_fs_t req; int r; @@ -553,16 +553,8 @@ static void check_utime(const char* path, double atime, double mtime) { ASSERT(req.result == 0); s = &req.statbuf; -#if defined(_WIN32) || defined(_AIX) - ASSERT(s->st_atime == atime); - ASSERT(s->st_mtime == mtime); -#elif !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) - ASSERT(s->st_atimespec.tv_sec == atime); - ASSERT(s->st_mtimespec.tv_sec == mtime); -#else ASSERT(s->st_atim.tv_sec == atime); ASSERT(s->st_mtim.tv_sec == mtime); -#endif uv_fs_req_cleanup(&req); } @@ -906,7 +898,10 @@ TEST_IMPL(fs_fstat) { int r; uv_fs_t req; uv_file file; - struct stat* s; + uv_stat_t* s; +#ifndef _WIN32 + struct stat t; +#endif /* Setup. */ unlink("test_file"); @@ -930,6 +925,45 @@ TEST_IMPL(fs_fstat) { ASSERT(req.result == 0); s = req.ptr; ASSERT(s->st_size == sizeof(test_buf)); + +#ifndef _WIN32 + r = fstat(file, &t); + ASSERT(r == 0); + + ASSERT(s->st_dev == t.st_dev); + ASSERT(s->st_mode == t.st_mode); + ASSERT(s->st_nlink == t.st_nlink); + ASSERT(s->st_uid == t.st_uid); + ASSERT(s->st_gid == t.st_gid); + ASSERT(s->st_rdev == t.st_rdev); + ASSERT(s->st_ino == t.st_ino); + ASSERT(s->st_size == t.st_size); + ASSERT(s->st_blksize == t.st_blksize); + ASSERT(s->st_blocks == t.st_blocks); +#if defined(__APPLE__) + ASSERT(s->st_atim.tv_sec == t.st_atimespec.tv_sec); + ASSERT(s->st_atim.tv_nsec == t.st_atimespec.tv_nsec); + ASSERT(s->st_mtim.tv_sec == t.st_mtimespec.tv_sec); + ASSERT(s->st_mtim.tv_nsec == t.st_mtimespec.tv_nsec); + ASSERT(s->st_ctim.tv_sec == t.st_ctimespec.tv_sec); + ASSERT(s->st_ctim.tv_nsec == t.st_ctimespec.tv_nsec); +#elif defined(_BSD_SOURCE) || defined(_SVID_SOURCE) || defined(_XOPEN_SOURCE) + ASSERT(s->st_atim.tv_sec == t.st_atim.tv_sec); + ASSERT(s->st_atim.tv_nsec == t.st_atim.tv_nsec); + ASSERT(s->st_mtim.tv_sec == t.st_mtim.tv_sec); + ASSERT(s->st_mtim.tv_nsec == t.st_mtim.tv_nsec); + ASSERT(s->st_ctim.tv_sec == t.st_ctim.tv_sec); + ASSERT(s->st_ctim.tv_nsec == t.st_ctim.tv_nsec); +#else + ASSERT(s->st_atim.tv_sec == t.st_atime); + ASSERT(s->st_atim.tv_nsec == 0); + ASSERT(s->st_mtim.tv_sec == t.st_mtime); + ASSERT(s->st_mtim.tv_nsec == 0); + ASSERT(s->st_ctim.tv_sec == t.st_ctime); + ASSERT(s->st_ctim.tv_nsec == 0); +#endif +#endif + uv_fs_req_cleanup(&req); /* Now do the uv_fs_fstat call asynchronously */ @@ -1382,16 +1416,16 @@ TEST_IMPL(fs_symlink_dir) { r = uv_fs_stat(loop, &req, "test_dir_symlink", NULL); ASSERT(r == 0); - ASSERT(((struct stat*)req.ptr)->st_mode & S_IFDIR); + ASSERT(((uv_stat_t*)req.ptr)->st_mode & S_IFDIR); uv_fs_req_cleanup(&req); r = uv_fs_lstat(loop, &req, "test_dir_symlink", NULL); ASSERT(r == 0); - ASSERT(((struct stat*)req.ptr)->st_mode & S_IFLNK); + ASSERT(((uv_stat_t*)req.ptr)->st_mode & S_IFLNK); #ifdef _WIN32 - ASSERT(((struct stat*)req.ptr)->st_size == strlen(test_dir + 4)); + ASSERT(((uv_stat_t*)req.ptr)->st_size == strlen(test_dir + 4)); #else - ASSERT(((struct stat*)req.ptr)->st_size == strlen(test_dir)); + ASSERT(((uv_stat_t*)req.ptr)->st_size == strlen(test_dir)); #endif uv_fs_req_cleanup(&req);