parent
cf24f561a3
commit
3efcbadf6b
2
deps/uv/include/uv-private/uv-win.h
vendored
2
deps/uv/include/uv-private/uv-win.h
vendored
@ -28,6 +28,7 @@
|
||||
#include <mswsock.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <windows.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "tree.h"
|
||||
|
||||
@ -246,6 +247,7 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
|
||||
|
||||
#define UV_FS_PRIVATE_FIELDS \
|
||||
int flags; \
|
||||
struct _stat stat; \
|
||||
void* arg0; \
|
||||
union { \
|
||||
struct { \
|
||||
|
79
deps/uv/src/unix/fs.c
vendored
79
deps/uv/src/unix/fs.c
vendored
@ -81,28 +81,36 @@ static int uv__fs_after(eio_req* eio) {
|
||||
req->result = req->eio->result;
|
||||
req->errorno = req->eio->errorno;
|
||||
|
||||
if (req->fs_type == UV_FS_READDIR) {
|
||||
/*
|
||||
* XXX This is pretty bad.
|
||||
* We alloc and copy the large null termiated string list from libeio.
|
||||
* This is done because libeio is going to free eio->ptr2 after this
|
||||
* callback. We must keep it until uv_fs_req_cleanup. If we get rid of
|
||||
* libeio this can be avoided.
|
||||
*/
|
||||
buflen = 0;
|
||||
name = req->eio->ptr2;
|
||||
for (i = 0; i < req->result; i++) {
|
||||
namelen = strlen(name);
|
||||
buflen += namelen + 1;
|
||||
/* TODO check ENOMEM */
|
||||
name += namelen;
|
||||
assert(*name == '\0');
|
||||
name++;
|
||||
}
|
||||
req->ptr = malloc(buflen);
|
||||
memcpy(req->ptr, req->eio->ptr2, buflen);
|
||||
} else if (req->fs_type == UV_FS_STAT || req->fs_type == UV_FS_LSTAT) {
|
||||
req->ptr = req->eio->ptr2;
|
||||
switch (req->fs_type) {
|
||||
case UV_FS_READDIR:
|
||||
/*
|
||||
* XXX This is pretty bad.
|
||||
* We alloc and copy the large null termiated string list from libeio.
|
||||
* This is done because libeio is going to free eio->ptr2 after this
|
||||
* callback. We must keep it until uv_fs_req_cleanup. If we get rid of
|
||||
* libeio this can be avoided.
|
||||
*/
|
||||
buflen = 0;
|
||||
name = req->eio->ptr2;
|
||||
for (i = 0; i < req->result; i++) {
|
||||
namelen = strlen(name);
|
||||
buflen += namelen + 1;
|
||||
/* TODO check ENOMEM */
|
||||
name += namelen;
|
||||
assert(*name == '\0');
|
||||
name++;
|
||||
}
|
||||
req->ptr = malloc(buflen);
|
||||
memcpy(req->ptr, req->eio->ptr2, buflen);
|
||||
break;
|
||||
case UV_FS_STAT:
|
||||
case UV_FS_LSTAT:
|
||||
case UV_FS_FSTAT:
|
||||
req->ptr = req->eio->ptr2;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
uv_unref(req->loop);
|
||||
@ -398,8 +406,31 @@ 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) {
|
||||
assert(0 && "implement me");
|
||||
return -1;
|
||||
uv_fs_req_init(loop, req, UV_FS_FSTAT, cb);
|
||||
|
||||
if (cb) {
|
||||
/* async */
|
||||
uv_ref(loop);
|
||||
req->eio = eio_fstat(file, EIO_PRI_DEFAULT, uv__fs_after, req);
|
||||
|
||||
if (!req->eio) {
|
||||
uv_err_new(loop, ENOMEM);
|
||||
return -1;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* sync */
|
||||
req->result = fstat(file, &req->statbuf);
|
||||
|
||||
if (req->result < 0) {
|
||||
uv_err_new(loop, errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
req->ptr = &req->statbuf;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
23
deps/uv/src/win/fs.c
vendored
23
deps/uv/src/win/fs.c
vendored
@ -234,17 +234,11 @@ done:
|
||||
void fs__stat(uv_fs_t* req, const char* path) {
|
||||
int result;
|
||||
|
||||
req->ptr = malloc(sizeof(struct _stat));
|
||||
if (!req->ptr) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
||||
}
|
||||
|
||||
result = _stat(path, (struct _stat*)req->ptr);
|
||||
result = _stat(path, &req->stat);
|
||||
if (result == -1) {
|
||||
free(req->ptr);
|
||||
req->ptr = NULL;
|
||||
} else {
|
||||
req->flags |= UV_FS_FREE_PTR;
|
||||
req->ptr = &req->stat;
|
||||
}
|
||||
|
||||
SET_REQ_RESULT(req, result);
|
||||
@ -254,17 +248,11 @@ void fs__stat(uv_fs_t* req, const char* path) {
|
||||
void fs__fstat(uv_fs_t* req, uv_file file) {
|
||||
int result;
|
||||
|
||||
req->ptr = malloc(sizeof(struct _stat));
|
||||
if (!req->ptr) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
||||
}
|
||||
|
||||
result = _fstat(file, (struct _stat*)req->ptr);
|
||||
result = _fstat(file, &req->stat);
|
||||
if (result == -1) {
|
||||
free(req->ptr);
|
||||
req->ptr = NULL;
|
||||
} else {
|
||||
req->flags |= UV_FS_FREE_PTR;
|
||||
req->ptr = &req->stat;
|
||||
}
|
||||
|
||||
SET_REQ_RESULT(req, result);
|
||||
@ -807,9 +795,10 @@ void uv_fs_req_cleanup(uv_fs_t* req) {
|
||||
|
||||
if (req->flags & UV_FS_FREE_PTR && req->ptr) {
|
||||
free(req->ptr);
|
||||
req->ptr = NULL;
|
||||
}
|
||||
|
||||
req->ptr = NULL;
|
||||
|
||||
if (req->flags & UV_FS_ASYNC_QUEUED) {
|
||||
uv_unref(loop);
|
||||
}
|
||||
|
6
deps/uv/src/win/tcp.c
vendored
6
deps/uv/src/win/tcp.c
vendored
@ -75,14 +75,14 @@ static int uv_tcp_set_socket(uv_loop_t* loop, uv_tcp_t* handle,
|
||||
}
|
||||
|
||||
if (pSetFileCompletionNotificationModes) {
|
||||
if (!pSetFileCompletionNotificationModes((HANDLE) socket,
|
||||
if (pSetFileCompletionNotificationModes((HANDLE) socket,
|
||||
FILE_SKIP_SET_EVENT_ON_HANDLE |
|
||||
FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)) {
|
||||
handle->flags |= UV_HANDLE_SYNC_BYPASS_IOCP;
|
||||
} else if (GetLastError() != ERROR_INVALID_FUNCTION) {
|
||||
uv_set_sys_error(loop, GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
handle->flags |= UV_HANDLE_SYNC_BYPASS_IOCP;
|
||||
}
|
||||
|
||||
handle->socket = socket;
|
||||
|
70
deps/uv/test/test-fs.c
vendored
70
deps/uv/test/test-fs.c
vendored
@ -57,6 +57,7 @@ static int fsync_cb_count;
|
||||
static int fdatasync_cb_count;
|
||||
static int ftruncate_cb_count;
|
||||
static int sendfile_cb_count;
|
||||
static int fstat_cb_count;
|
||||
|
||||
static uv_loop_t* loop;
|
||||
|
||||
@ -88,6 +89,15 @@ static void unlink_cb(uv_fs_t* req) {
|
||||
uv_fs_req_cleanup(req);
|
||||
}
|
||||
|
||||
static void fstat_cb(uv_fs_t* req) {
|
||||
struct stat* s = req->ptr;
|
||||
ASSERT(req->fs_type == UV_FS_FSTAT);
|
||||
ASSERT(req->result == 0);
|
||||
ASSERT(s->st_size == sizeof(test_buf));
|
||||
uv_fs_req_cleanup(req);
|
||||
fstat_cb_count++;
|
||||
}
|
||||
|
||||
|
||||
static void close_cb(uv_fs_t* req) {
|
||||
int r;
|
||||
@ -486,10 +496,10 @@ TEST_IMPL(fs_async_dir) {
|
||||
|
||||
TEST_IMPL(fs_async_sendfile) {
|
||||
int f, r;
|
||||
|
||||
/* Setup. */
|
||||
struct stat s1, s2;
|
||||
|
||||
/* Setup. */
|
||||
uv_init();
|
||||
unlink("test_file");
|
||||
unlink("test_file2");
|
||||
|
||||
@ -509,7 +519,6 @@ TEST_IMPL(fs_async_sendfile) {
|
||||
ASSERT(r == 0);
|
||||
|
||||
/* Test starts here. */
|
||||
uv_init();
|
||||
loop = uv_default_loop();
|
||||
|
||||
r = uv_fs_open(loop, &open_req1, "test_file", O_RDWR, 0, NULL);
|
||||
@ -547,3 +556,58 @@ TEST_IMPL(fs_async_sendfile) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_fstat) {
|
||||
int r;
|
||||
uv_fs_t req;
|
||||
uv_file file;
|
||||
|
||||
/* Setup. */
|
||||
unlink("test_file");
|
||||
|
||||
uv_init();
|
||||
|
||||
loop = uv_default_loop();
|
||||
|
||||
r = uv_fs_open(loop, &req, "test_file", O_RDWR | O_CREAT, 0, NULL);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(req.result != -1);
|
||||
file = req.result;
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
r = uv_fs_write(loop, &req, file, test_buf, sizeof(test_buf), -1, NULL);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(req.result == sizeof(test_buf));
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
r = uv_fs_fstat(loop, &req, file, NULL);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(req.result == 0);
|
||||
struct stat* s = req.ptr;
|
||||
ASSERT(s->st_size == sizeof(test_buf));
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
/* Now do the uv_fs_fstat call asynchronously */
|
||||
r = uv_fs_fstat(loop, &req, file, fstat_cb);
|
||||
ASSERT(r == 0);
|
||||
uv_run(loop);
|
||||
ASSERT(fstat_cb_count == 1);
|
||||
|
||||
|
||||
r = uv_fs_close(loop, &req, file, NULL);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(req.result == 0);
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
/*
|
||||
* Run the loop just to check we don't have make any extranious uv_ref()
|
||||
* calls. This should drop out immediately.
|
||||
*/
|
||||
uv_run(loop);
|
||||
|
||||
/* Cleanup. */
|
||||
unlink("test_file");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
2
deps/uv/test/test-list.h
vendored
2
deps/uv/test/test-list.h
vendored
@ -76,6 +76,7 @@ TEST_DECLARE (fs_file_async)
|
||||
TEST_DECLARE (fs_file_sync)
|
||||
TEST_DECLARE (fs_async_dir)
|
||||
TEST_DECLARE (fs_async_sendfile)
|
||||
TEST_DECLARE (fs_fstat)
|
||||
TEST_DECLARE (threadpool_queue_work_simple)
|
||||
#ifdef _WIN32
|
||||
TEST_DECLARE (spawn_detect_pipe_name_collisions_on_windows)
|
||||
@ -179,6 +180,7 @@ TASK_LIST_START
|
||||
TEST_ENTRY (fs_file_sync)
|
||||
TEST_ENTRY (fs_async_dir)
|
||||
TEST_ENTRY (fs_async_sendfile)
|
||||
TEST_ENTRY (fs_fstat)
|
||||
|
||||
TEST_ENTRY (threadpool_queue_work_simple)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user