Upgrade libuv to 991f6ee
authorRyan Dahl <ry@tinyclouds.org>
Mon, 5 Sep 2011 01:16:33 +0000 (18:16 -0700)
committerRyan Dahl <ry@tinyclouds.org>
Mon, 5 Sep 2011 01:48:19 +0000 (18:48 -0700)
deps/uv/include/uv.h
deps/uv/src/unix/fs.c
deps/uv/src/win/fs.c
deps/uv/test/test-fs.c

index 894c98fbf0cfbd4abcde0d83ef2fb812c4100df2..bceb432d78b53fd3dd9c30f798d06ccf096b608a 100644 (file)
@@ -890,6 +890,7 @@ struct uv_fs_s {
   uv_fs_cb cb;
   ssize_t result;
   void* ptr;
+  char* path;
   int errorno;
   UV_FS_PRIVATE_FIELDS
 };
index aeeb2a83a162c39651085a411b3fdb9cb3c73414..7ca2275fc2d819b98a9043ccbca1140537f69993 100644 (file)
@@ -40,7 +40,7 @@
 #define ARGS4(a,b,c,d) (a), (b), (c), (d)
 
 #define WRAP_EIO(type, eiofunc, func, args) \
-  uv_fs_req_init(loop, req, type, cb); \
+  uv_fs_req_init(loop, req, type, path, cb); \
   if (cb) { \
     /* async */ \
     uv_ref(loop); \
@@ -61,7 +61,7 @@
 
 
 static void uv_fs_req_init(uv_loop_t* loop, uv_fs_t* req, uv_fs_type fs_type,
-    uv_fs_cb cb) {
+    char* path, uv_fs_cb cb) {
   /* Make sure the thread pool is initialized. */
   uv_eio_init(loop);
 
@@ -72,12 +72,16 @@ static void uv_fs_req_init(uv_loop_t* loop, uv_fs_t* req, uv_fs_type fs_type,
   req->cb = cb;
   req->result = 0;
   req->ptr = NULL;
+  req->path = path ? strdup(path) : NULL;
   req->errorno = 0;
   req->eio = NULL;
 }
 
 
 void uv_fs_req_cleanup(uv_fs_t* req) {
+  free(req->path);
+  req->path = NULL;
+
   switch (req->fs_type) {
     case UV_FS_READDIR:
       assert(req->ptr);
@@ -168,13 +172,14 @@ static int uv__fs_after(eio_req* eio) {
 
 
 int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
+  char* path = NULL;
   WRAP_EIO(UV_FS_CLOSE, eio_close, close, ARGS1(file));
 }
 
 
 int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
     int mode, uv_fs_cb cb) {
-  uv_fs_req_init(loop, req, UV_FS_OPEN, cb);
+  uv_fs_req_init(loop, req, UV_FS_OPEN, path, cb);
 
   if (cb) {
     /* async */
@@ -202,7 +207,7 @@ int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
 
 int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file fd, void* buf,
     size_t length, off_t offset, uv_fs_cb cb) {
-  uv_fs_req_init(loop, req, UV_FS_READ, cb);
+  uv_fs_req_init(loop, req, UV_FS_READ, NULL, cb);
 
   if (cb) {
     /* async */
@@ -238,7 +243,7 @@ int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
 
 int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf,
     size_t length, off_t offset, uv_fs_cb cb) {
-  uv_fs_req_init(loop, req, UV_FS_WRITE, cb);
+  uv_fs_req_init(loop, req, UV_FS_WRITE, NULL, cb);
 
   if (cb) {
     /* async */
@@ -284,7 +289,7 @@ int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
   size_t size = 0;
   size_t d_namlen = 0;
 
-  uv_fs_req_init(loop, req, UV_FS_READDIR, cb);
+  uv_fs_req_init(loop, req, UV_FS_READDIR, path, cb);
 
   if (cb) {
     /* async */
@@ -340,7 +345,7 @@ int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
   char* pathdup = path;
   int pathlen;
 
-  uv_fs_req_init(loop, req, UV_FS_STAT, cb);
+  uv_fs_req_init(loop, req, UV_FS_STAT, path, cb);
 
   /* TODO do this without duplicating the string. */
   /* TODO security */
@@ -383,7 +388,7 @@ int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
 
 
 int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
-  uv_fs_req_init(loop, req, UV_FS_FSTAT, cb);
+  uv_fs_req_init(loop, req, UV_FS_FSTAT, NULL, cb);
 
   if (cb) {
     /* async */
@@ -418,23 +423,27 @@ int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* ne
 
 
 int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
+  char* path = NULL;
   WRAP_EIO(UV_FS_FSYNC, eio_fsync, fsync, ARGS1(file))
 }
 
 
 int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
+  char* path = NULL;
   WRAP_EIO(UV_FS_FDATASYNC, eio_fdatasync, fdatasync, ARGS1(file))
 }
 
 
 int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file file, off_t offset,
     uv_fs_cb cb) {
+  char* path = NULL;
   WRAP_EIO(UV_FS_FTRUNCATE, eio_ftruncate, ftruncate, ARGS2(file, offset))
 }
 
 
 int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd, uv_file in_fd,
     off_t in_offset, size_t length, uv_fs_cb cb) {
+  char* path = NULL;
   WRAP_EIO(UV_FS_SENDFILE, eio_sendfile, eio_sendfile_sync,
       ARGS4(out_fd, in_fd, in_offset, length))
 }
@@ -471,7 +480,7 @@ int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
   char* pathdup = path;
   int pathlen;
 
-  uv_fs_req_init(loop, req, UV_FS_LSTAT, cb);
+  uv_fs_req_init(loop, req, UV_FS_LSTAT, path, cb);
 
   /* TODO do this without duplicating the string. */
   /* TODO security */
@@ -533,7 +542,7 @@ int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
 
   status = -1;
 
-  uv_fs_req_init(loop, req, UV_FS_READLINK, cb);
+  uv_fs_req_init(loop, req, UV_FS_READLINK, path, cb);
 
   if (cb) {
     if ((req->eio = eio_readlink(path, EIO_PRI_DEFAULT, uv__fs_after, req))) {
@@ -581,6 +590,7 @@ int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
 
 int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file file, int mode,
     uv_fs_cb cb) {
+  char* path = NULL;
   WRAP_EIO(UV_FS_FCHMOD, eio_fchmod, fchmod, ARGS2(file, mode))
 }
 
@@ -593,6 +603,7 @@ int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, int uid,
 
 int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file file, int uid, int gid,
     uv_fs_cb cb) {
+  char* path = NULL;
   WRAP_EIO(UV_FS_FCHOWN, eio_fchown, fchown, ARGS3(file, uid, gid))
 }
 
index 770b4df1fbfc2002b927d848c80bdaee928fe3b8..4cc597c39225dde22b6a4bf44d2de03e35c28c2b 100644 (file)
@@ -97,6 +97,7 @@ static void uv_fs_req_init_async(uv_loop_t* loop, uv_fs_t* req,
   req->cb = cb;
   req->result = 0;
   req->ptr = NULL;
+  req->path = NULL; /* TODO https://github.com/joyent/libuv/issues/177 */
   req->errorno = 0;
   req->last_error = 0;
   memset(&req->overlapped, 0, sizeof(req->overlapped));
@@ -115,13 +116,120 @@ static void uv_fs_req_init_sync(uv_loop_t* loop, uv_fs_t* req,
   req->errorno = 0;
 }
 
+/* this is where the CRT stores the current umask */
+extern int _umaskval;
 
 void fs__open(uv_fs_t* req, const char* path, int flags, int mode) {
-  int result = _open(path, flags, mode);
+  DWORD access;
+  DWORD share;
+  SECURITY_ATTRIBUTES sa;
+  DWORD disposition;
+  DWORD attributes;
+  HANDLE file;
+  int result;
+
+  /* convert flags and mode to CreateFile parameters */
+  switch (flags & (_O_RDONLY | _O_WRONLY | _O_RDWR)) {
+  case _O_RDONLY:
+    access = GENERIC_READ;
+    break;
+  case _O_WRONLY:
+    access = GENERIC_WRITE;
+    break;
+  case _O_RDWR:
+    access = GENERIC_READ | GENERIC_WRITE;
+    break;
+  default:
+    result  = -1;
+    goto end;
+  }
+
+  /*
+   * Here is where we deviate significantly from what CRT's _open()
+   * does. We indiscriminately use all the sharing modes, to match
+   * UNIX semantics. In particular, this ensures that the file can
+   * be deleted even whilst it's open, fixing issue #1449.
+   */
+  share = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
+
+  sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+  sa.lpSecurityDescriptor = NULL;
+  if (flags & _O_NOINHERIT) {
+    sa.bInheritHandle = FALSE;
+  } else {
+    sa.bInheritHandle = TRUE;
+  }
+
+  switch (flags & (_O_CREAT | _O_EXCL | _O_TRUNC)) {
+  case 0:
+  case _O_EXCL:
+    disposition = OPEN_EXISTING;
+    break;
+  case _O_CREAT:
+    disposition = OPEN_ALWAYS;
+    break;
+  case _O_CREAT | _O_EXCL:
+  case _O_CREAT | _O_TRUNC | _O_EXCL:
+    disposition = CREATE_NEW;
+    break;
+  case _O_TRUNC:
+  case _O_TRUNC | _O_EXCL:
+    disposition = TRUNCATE_EXISTING;
+    break;
+  case _O_CREAT | _O_TRUNC:
+    disposition = CREATE_ALWAYS;
+    break;
+  default:
+    result = -1;
+    goto end;
+  }
+
+  attributes = FILE_ATTRIBUTE_NORMAL;
+  if (flags & _O_CREAT) {
+    if (!((mode & ~_umaskval) & _S_IWRITE)) {
+      attributes |= FILE_ATTRIBUTE_READONLY;
+    }
+  }
+
+  if (flags & _O_TEMPORARY ) {
+    attributes |= FILE_FLAG_DELETE_ON_CLOSE | FILE_ATTRIBUTE_TEMPORARY;
+    access |= DELETE;
+  }
+
+  if (flags & _O_SHORT_LIVED) {
+    attributes |= FILE_ATTRIBUTE_TEMPORARY;
+  }
+
+  switch (flags & (_O_SEQUENTIAL | _O_RANDOM)) {
+  case 0:
+    break;
+  case _O_SEQUENTIAL:
+    attributes |= FILE_FLAG_SEQUENTIAL_SCAN;
+    break;
+  case _O_RANDOM:
+    attributes |= FILE_FLAG_RANDOM_ACCESS;
+    break;
+  default:
+    result = -1;
+    goto end;
+  }
+
+  file = CreateFileA(path,
+                     access,
+                     share,
+                     &sa,
+                     disposition,
+                     attributes,
+                     NULL);
+  if (file == INVALID_HANDLE_VALUE) {
+    result = -1;
+    goto end;
+  }
+  result = _open_osfhandle((intptr_t)file, flags);
+end:
   SET_REQ_RESULT(req, result);
 }
 
-
 void fs__close(uv_fs_t* req, uv_file file) {
   int result = _close(file);
   SET_REQ_RESULT(req, result);
index f9c65787ed93de195b9d93ece2902b238a5d208f..1e119b6aea235a5e4a606cdcf2579fdc895f45ab 100644 (file)
@@ -240,6 +240,8 @@ static void open_cb(uv_fs_t* req) {
     ASSERT(0);
   }
   open_cb_count++;
+  ASSERT(req->path);
+  ASSERT(memcmp(req->path, "test_file2\0", 11) == 0);
   uv_fs_req_cleanup(req);
   memset(buf, 0, sizeof(buf));
   r = uv_fs_read(loop, &read_req, open_req1.result, buf, sizeof(buf), -1,
@@ -306,6 +308,8 @@ static void mkdir_cb(uv_fs_t* req) {
   ASSERT(req->fs_type == UV_FS_MKDIR);
   ASSERT(req->result != -1);
   mkdir_cb_count++;
+  ASSERT(req->path);
+  ASSERT(memcmp(req->path, "test_dir\0", 9) == 0);
   uv_fs_req_cleanup(req);
 }
 
@@ -315,6 +319,8 @@ static void rmdir_cb(uv_fs_t* req) {
   ASSERT(req->fs_type == UV_FS_RMDIR);
   ASSERT(req->result != -1);
   rmdir_cb_count++;
+  ASSERT(req->path);
+  ASSERT(memcmp(req->path, "test_dir\0", 9) == 0);
   uv_fs_req_cleanup(req);
 }
 
@@ -327,6 +333,8 @@ static void readdir_cb(uv_fs_t* req) {
   ASSERT(memcmp(req->ptr, "file1\0file2\0", 12) == 0
       || memcmp(req->ptr, "file2\0file1\0", 12) == 0);
   readdir_cb_count++;
+  ASSERT(req->path);
+  ASSERT(memcmp(req->path, "test_dir\0", 9) == 0);
   uv_fs_req_cleanup(req);
   ASSERT(!req->ptr);
 }
@@ -544,6 +552,7 @@ TEST_IMPL(fs_async_dir) {
   r = uv_fs_readdir(loop, &readdir_req, "test_dir", 0, NULL);
   readdir_cb(&readdir_req);
 
+
   r = uv_fs_stat(loop, &stat_req, "test_dir", stat_cb);
   ASSERT(r == 0);
   uv_run(loop);