Skip to content
This repository has been archived by the owner on May 4, 2018. It is now read-only.

Commit

Permalink
Add test for uv_fs_fstat, implement on unix.
Browse files Browse the repository at this point in the history
  • Loading branch information
ry committed Sep 1, 2011
1 parent 716e8ea commit 2e60358
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 24 deletions.
79 changes: 55 additions & 24 deletions src/unix/fs.c
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}


Expand Down
65 changes: 65 additions & 0 deletions test/test-fs.c
Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
2 changes: 2 additions & 0 deletions test/test-list.h
Expand Up @@ -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)
Expand Down Expand Up @@ -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)

Expand Down

0 comments on commit 2e60358

Please sign in to comment.