win: restore file pos after positional read/write
File read or write from specified position will move file pointer on Windows but not on POSIX. This makes Windows behave as other supported platforms. Ref: https://github.com/nodejs/node/issues/9671 PR-URL: https://github.com/libuv/libuv/pull/1357 Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com> Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
This commit is contained in:
parent
57f4180cf3
commit
0bd8f5bf36
24
src/win/fs.c
24
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 {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user