diff --git a/src/win/fs.c b/src/win/fs.c index 2d72cdc7..8223d6f6 100644 --- a/src/win/fs.c +++ b/src/win/fs.c @@ -556,9 +556,14 @@ void fs__read(uv_fs_t* req) { DWORD error; int result; unsigned int index; + LARGE_INTEGER original_position; + LARGE_INTEGER zero_offset; + int restore_position; VERIFY_FD(fd, req); + zero_offset.QuadPart = 0; + restore_position = 0; handle = uv__get_osfhandle(fd); if (handle == INVALID_HANDLE_VALUE) { @@ -569,6 +574,10 @@ void fs__read(uv_fs_t* req) { if (offset != -1) { memset(&overlapped, 0, sizeof overlapped); overlapped_ptr = &overlapped; + if (SetFilePointerEx(handle, zero_offset, &original_position, + FILE_CURRENT)) { + restore_position = 1; + } } else { overlapped_ptr = NULL; } @@ -593,6 +602,9 @@ void fs__read(uv_fs_t* req) { ++index; } while (result && index < req->fs.info.nbufs); + if (restore_position) + SetFilePointerEx(handle, original_position, NULL, FILE_BEGIN); + if (result || bytes > 0) { SET_REQ_RESULT(req, bytes); } else { @@ -615,9 +627,14 @@ void fs__write(uv_fs_t* req) { DWORD bytes; int result; unsigned int index; + LARGE_INTEGER original_position; + LARGE_INTEGER zero_offset; + int restore_position; VERIFY_FD(fd, req); + zero_offset.QuadPart = 0; + restore_position = 0; handle = uv__get_osfhandle(fd); if (handle == INVALID_HANDLE_VALUE) { SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE); @@ -627,6 +644,10 @@ void fs__write(uv_fs_t* req) { if (offset != -1) { memset(&overlapped, 0, sizeof overlapped); overlapped_ptr = &overlapped; + if (SetFilePointerEx(handle, zero_offset, &original_position, + FILE_CURRENT)) { + restore_position = 1; + } } else { overlapped_ptr = NULL; } @@ -651,6 +672,9 @@ void fs__write(uv_fs_t* req) { ++index; } while (result && index < req->fs.info.nbufs); + if (restore_position) + SetFilePointerEx(handle, original_position, NULL, FILE_BEGIN); + if (result || bytes > 0) { SET_REQ_RESULT(req, bytes); } else { diff --git a/test/test-fs.c b/test/test-fs.c index c482ab5c..404d0426 100644 --- a/test/test-fs.c +++ b/test/test-fs.c @@ -2804,3 +2804,43 @@ TEST_IMPL(get_osfhandle_valid_handle) { MAKE_VALGRIND_HAPPY(); return 0; } + +TEST_IMPL(fs_file_pos_after_op_with_offset) { + int r; + + /* Setup. */ + unlink("test_file"); + loop = uv_default_loop(); + + r = uv_fs_open(loop, + &open_req1, + "test_file", + O_RDWR | O_CREAT, + S_IWUSR | S_IRUSR, + NULL); + ASSERT(r > 0); + uv_fs_req_cleanup(&open_req1); + + iov = uv_buf_init(test_buf, sizeof(test_buf)); + r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, 0, NULL); + ASSERT(r == sizeof(test_buf)); + ASSERT(lseek(open_req1.result, 0, SEEK_CUR) == 0); + uv_fs_req_cleanup(&write_req); + + iov = uv_buf_init(buf, sizeof(buf)); + r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, 0, NULL); + ASSERT(r == sizeof(test_buf)); + ASSERT(strcmp(buf, test_buf) == 0); + ASSERT(lseek(open_req1.result, 0, SEEK_CUR) == 0); + uv_fs_req_cleanup(&read_req); + + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&close_req); + + /* Cleanup */ + unlink("test_file"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/test/test-list.h b/test/test-list.h index 3571aa23..9477e0de 100644 --- a/test/test-list.h +++ b/test/test-list.h @@ -308,6 +308,7 @@ TEST_DECLARE (fs_read_write_null_arguments) TEST_DECLARE (get_osfhandle_valid_handle) TEST_DECLARE (fs_write_alotof_bufs) TEST_DECLARE (fs_write_alotof_bufs_with_offset) +TEST_DECLARE (fs_file_pos_after_op_with_offset) TEST_DECLARE (threadpool_queue_work_simple) TEST_DECLARE (threadpool_queue_work_einval) TEST_DECLARE (threadpool_multiple_event_loops) @@ -793,6 +794,7 @@ TASK_LIST_START TEST_ENTRY (fs_write_alotof_bufs) TEST_ENTRY (fs_write_alotof_bufs_with_offset) TEST_ENTRY (fs_read_write_null_arguments) + TEST_ENTRY (fs_file_pos_after_op_with_offset) TEST_ENTRY (get_osfhandle_valid_handle) TEST_ENTRY (threadpool_queue_work_simple) TEST_ENTRY (threadpool_queue_work_einval)