From ea501263588c0efbaa77b24feda20075a943271a Mon Sep 17 00:00:00 2001 From: Igor Zinkovsky Date: Thu, 5 Apr 2012 16:00:38 -0700 Subject: [PATCH] add 64bit offset fs functions --- include/uv.h | 9 ++++++ src/win/fs.c | 88 +++++++++++++++++++++++++++++++++++++++++--------- test/test-fs.c | 35 +++++++++++++++----- 3 files changed, 108 insertions(+), 24 deletions(-) diff --git a/include/uv.h b/include/uv.h index 49ce47a9..ed6100ae 100644 --- a/include/uv.h +++ b/include/uv.h @@ -1155,12 +1155,18 @@ UV_EXTERN int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, UV_EXTERN int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf, size_t length, off_t offset, uv_fs_cb cb); +int uv_fs_read64(uv_loop_t* loop, uv_fs_t* req, uv_file file, + void* buf, size_t length, int64_t offset, uv_fs_cb cb); + UV_EXTERN int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb); UV_EXTERN 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); +int uv_fs_write64(uv_loop_t* loop, uv_fs_t* req, uv_file file, + void* buf, size_t length, int64_t offset, uv_fs_cb cb); + UV_EXTERN int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb); @@ -1188,6 +1194,9 @@ UV_EXTERN int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, UV_EXTERN int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file file, off_t offset, uv_fs_cb cb); +int uv_fs_ftruncate64(uv_loop_t* loop, uv_fs_t* req, uv_file file, + int64_t offset, uv_fs_cb cb); + UV_EXTERN 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); diff --git a/src/win/fs.c b/src/win/fs.c index 507336ee..daa23ed1 100644 --- a/src/win/fs.c +++ b/src/win/fs.c @@ -33,12 +33,11 @@ #include "uv.h" #include "internal.h" -#define UV_FS_ASYNC_QUEUED 0x0001 -#define UV_FS_FREE_ARG0 0x0002 -#define UV_FS_FREE_ARG1 0x0004 -#define UV_FS_FREE_PTR 0x0008 -#define UV_FS_CLEANEDUP 0x0010 - +#define UV_FS_ASYNC_QUEUED 0x0001 +#define UV_FS_FREE_ARG0 0x0002 +#define UV_FS_FREE_ARG1 0x0004 +#define UV_FS_FREE_PTR 0x0008 +#define UV_FS_CLEANEDUP 0x0010 #define UTF8_TO_UTF16(s, t) \ size = uv_utf8_to_utf16(s, NULL, 0) * sizeof(wchar_t); \ @@ -289,7 +288,7 @@ void fs__close(uv_fs_t* req, uv_file file) { void fs__read(uv_fs_t* req, uv_file file, void *buf, size_t length, - off_t offset) { + int64_t offset) { HANDLE handle; OVERLAPPED overlapped, *overlapped_ptr; LARGE_INTEGER offset_; @@ -335,7 +334,7 @@ void fs__read(uv_fs_t* req, uv_file file, void *buf, size_t length, void fs__write(uv_fs_t* req, uv_file file, void *buf, size_t length, - off_t offset) { + int64_t offset) { HANDLE handle; OVERLAPPED overlapped, *overlapped_ptr; LARGE_INTEGER offset_; @@ -597,12 +596,12 @@ void fs__fsync(uv_fs_t* req, uv_file file) { } -void fs__ftruncate(uv_fs_t* req, uv_file file, off_t offset) { +void fs__ftruncate(uv_fs_t* req, uv_file file, int64_t offset) { int result; VERIFY_UV_FILE(file, req); - result = _chsize(file, offset); + result = _chsize_s(file, offset); SET_REQ_RESULT(req, result); } @@ -878,14 +877,14 @@ static DWORD WINAPI uv_fs_thread_proc(void* parameter) { (uv_file) req->arg0, req->arg1, (size_t) req->arg2, - (off_t) req->arg3); + req->stat.st_atime); break; case UV_FS_WRITE: fs__write(req, (uv_file)req->arg0, req->arg1, (size_t) req->arg2, - (off_t) req->arg3); + req->stat.st_atime); break; case UV_FS_UNLINK: fs__unlink(req, req->pathw); @@ -914,7 +913,7 @@ static DWORD WINAPI uv_fs_thread_proc(void* parameter) { fs__fsync(req, (uv_file)req->arg0); break; case UV_FS_FTRUNCATE: - fs__ftruncate(req, (uv_file)req->arg0, (off_t)req->arg1); + fs__ftruncate(req, (uv_file)req->arg0, (off_t)req->stat.st_atime); break; case UV_FS_SENDFILE: fs__sendfile(req, @@ -1002,7 +1001,26 @@ int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf, size_t length, off_t offset, uv_fs_cb cb) { if (cb) { uv_fs_req_init_async(loop, req, UV_FS_READ, NULL, NULL, cb); - WRAP_REQ_ARGS4(req, file, buf, length, offset); + WRAP_REQ_ARGS3(req, file, buf, length); + req->stat.st_atime = offset; + QUEUE_FS_TP_JOB(loop, req); + } else { + uv_fs_req_init_sync(loop, req, UV_FS_READ); + fs__read(req, file, buf, length, offset); + SET_UV_LAST_ERROR_FROM_REQ(req); + return req->result; + } + + return 0; +} + + +int uv_fs_read64(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf, + size_t length, int64_t offset, uv_fs_cb cb) { + if (cb) { + uv_fs_req_init_async(loop, req, UV_FS_READ, NULL, NULL, cb); + WRAP_REQ_ARGS3(req, file, buf, length); + req->stat.st_atime = offset; QUEUE_FS_TP_JOB(loop, req); } else { uv_fs_req_init_sync(loop, req, UV_FS_READ); @@ -1019,7 +1037,26 @@ 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) { if (cb) { uv_fs_req_init_async(loop, req, UV_FS_WRITE, NULL, NULL, cb); - WRAP_REQ_ARGS4(req, file, buf, length, offset); + WRAP_REQ_ARGS3(req, file, buf, length); + req->stat.st_atime = offset; + QUEUE_FS_TP_JOB(loop, req); + } else { + uv_fs_req_init_sync(loop, req, UV_FS_WRITE); + fs__write(req, file, buf, length, offset); + SET_UV_LAST_ERROR_FROM_REQ(req); + return req->result; + } + + return 0; +} + + +int uv_fs_write64(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf, + size_t length, int64_t offset, uv_fs_cb cb) { + if (cb) { + uv_fs_req_init_async(loop, req, UV_FS_WRITE, NULL, NULL, cb); + WRAP_REQ_ARGS3(req, file, buf, length); + req->stat.st_atime = offset; QUEUE_FS_TP_JOB(loop, req); } else { uv_fs_req_init_sync(loop, req, UV_FS_WRITE); @@ -1412,7 +1449,26 @@ int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file file, off_t offset, uv_fs_cb cb) { if (cb) { uv_fs_req_init_async(loop, req, UV_FS_FTRUNCATE, NULL, NULL, cb); - WRAP_REQ_ARGS2(req, file, offset); + WRAP_REQ_ARGS1(req, file); + req->stat.st_atime = offset; + QUEUE_FS_TP_JOB(loop, req); + } else { + uv_fs_req_init_sync(loop, req, UV_FS_FTRUNCATE); + fs__ftruncate(req, file, offset); + SET_UV_LAST_ERROR_FROM_REQ(req); + return req->result; + } + + return 0; +} + + +int uv_fs_ftruncate64(uv_loop_t* loop, uv_fs_t* req, uv_file file, + int64_t offset, uv_fs_cb cb) { + if (cb) { + uv_fs_req_init_async(loop, req, UV_FS_FTRUNCATE, NULL, NULL, cb); + WRAP_REQ_ARGS1(req, file); + req->stat.st_atime = offset; QUEUE_FS_TP_JOB(loop, req); } else { uv_fs_req_init_sync(loop, req, UV_FS_FTRUNCATE); diff --git a/test/test-fs.c b/test/test-fs.c index 8dc71473..73d01382 100644 --- a/test/test-fs.c +++ b/test/test-fs.c @@ -248,6 +248,11 @@ static void read_cb(uv_fs_t* req) { read_cb_count++; uv_fs_req_cleanup(req); if (read_cb_count == 1) { + ASSERT(strcmp(buf, test_buf) == 0); + memset(buf, 0, sizeof(buf)); + r = uv_fs_read64(loop, &read_req, open_req1.result, buf, sizeof(buf), 0, + read_cb); + } else if (read_cb_count == 2) { ASSERT(strcmp(buf, test_buf) == 0); r = uv_fs_ftruncate(loop, &ftruncate_req, open_req1.result, 7, ftruncate_cb); @@ -319,7 +324,13 @@ static void write_cb(uv_fs_t* req) { ASSERT(req->result != -1); write_cb_count++; uv_fs_req_cleanup(req); - r = uv_fs_fdatasync(loop, &fdatasync_req, open_req1.result, fdatasync_cb); + + if (write_cb_count == 1) { + r = uv_fs_write64(loop, &write_req, open_req1.result, test_buf, sizeof(test_buf), + -1, write_cb); + } else { + r = uv_fs_fdatasync(loop, &fdatasync_req, open_req1.result, fdatasync_cb); + } } @@ -596,7 +607,7 @@ TEST_IMPL(fs_file_async) { uv_run(loop); ASSERT(create_cb_count == 1); - ASSERT(write_cb_count == 1); + ASSERT(write_cb_count == 2); ASSERT(fsync_cb_count == 1); ASSERT(fdatasync_cb_count == 1); ASSERT(close_cb_count == 1); @@ -606,7 +617,7 @@ TEST_IMPL(fs_file_async) { uv_run(loop); ASSERT(create_cb_count == 1); - ASSERT(write_cb_count == 1); + ASSERT(write_cb_count == 2); ASSERT(close_cb_count == 1); ASSERT(rename_cb_count == 1); @@ -615,11 +626,11 @@ TEST_IMPL(fs_file_async) { uv_run(loop); ASSERT(open_cb_count == 1); - ASSERT(read_cb_count == 1); + ASSERT(read_cb_count == 2); ASSERT(close_cb_count == 2); ASSERT(rename_cb_count == 1); ASSERT(create_cb_count == 1); - ASSERT(write_cb_count == 1); + ASSERT(write_cb_count == 2); ASSERT(ftruncate_cb_count == 1); r = uv_fs_open(loop, &open_req1, "test_file2", O_RDONLY, 0, open_cb); @@ -627,12 +638,12 @@ TEST_IMPL(fs_file_async) { uv_run(loop); ASSERT(open_cb_count == 2); - ASSERT(read_cb_count == 2); + ASSERT(read_cb_count == 3); ASSERT(close_cb_count == 3); ASSERT(rename_cb_count == 1); ASSERT(unlink_cb_count == 1); ASSERT(create_cb_count == 1); - ASSERT(write_cb_count == 1); + ASSERT(write_cb_count == 2); ASSERT(ftruncate_cb_count == 1); /* Cleanup. */ @@ -681,6 +692,14 @@ TEST_IMPL(fs_file_sync) { ASSERT(strcmp(buf, test_buf) == 0); uv_fs_req_cleanup(&read_req); + memset(buf, 0, sizeof(buf)); + r = uv_fs_read64(loop, &read_req, open_req1.result, buf, sizeof(buf), 0, + NULL); + ASSERT(r != -1); + ASSERT(read_req.result != -1); + ASSERT(strcmp(buf, test_buf) == 0); + uv_fs_req_cleanup(&read_req); + r = uv_fs_ftruncate(loop, &ftruncate_req, open_req1.result, 7, NULL); ASSERT(r != -1); ASSERT(ftruncate_req.result != -1); @@ -899,7 +918,7 @@ TEST_IMPL(fs_fstat) { file = req.result; uv_fs_req_cleanup(&req); - r = uv_fs_write(loop, &req, file, test_buf, sizeof(test_buf), -1, NULL); + r = uv_fs_write64(loop, &req, file, test_buf, sizeof(test_buf), -1, NULL); ASSERT(r == sizeof(test_buf)); ASSERT(req.result == sizeof(test_buf)); uv_fs_req_cleanup(&req);