Add test for uv_fs_fstat, implement on unix.
This commit is contained in:
parent
716e8eab39
commit
2e6035895c
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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;
|
||||
@ -546,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;
|
||||
}
|
||||
|
||||
@ -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…
Reference in New Issue
Block a user