win: map UV_FS_O_EXLOCK to a share mode of 0
This is necessary to enable writing past the MBR of a raw block device. Fixes: https://github.com/libuv/libuv/issues/1605 PR-URL: https://github.com/libuv/libuv/pull/1613 Reviewed-By: Bartosz Sosnowski <bartosz@janeasystems.com>
This commit is contained in:
parent
7ef23d9e85
commit
1c4de1916e
@ -409,7 +409,9 @@ File open constants
|
||||
Atomically obtain an exclusive lock.
|
||||
|
||||
.. note::
|
||||
`UV_FS_O_EXLOCK` is only supported on macOS.
|
||||
`UV_FS_O_EXLOCK` is only supported on macOS and Windows.
|
||||
|
||||
.. versionchanged:: 1.17.0 support is added for Windows.
|
||||
|
||||
.. c:macro:: UV_FS_O_NOATIME
|
||||
|
||||
|
||||
@ -664,13 +664,13 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
|
||||
#define UV_FS_O_WRONLY _O_WRONLY
|
||||
|
||||
/* fs open() flags supported on other platforms (or mapped on this platform): */
|
||||
#define UV_FS_O_DIRECT 0x2000000 /* FILE_FLAG_NO_BUFFERING */
|
||||
#define UV_FS_O_DIRECT 0x02000000 /* FILE_FLAG_NO_BUFFERING */
|
||||
#define UV_FS_O_DIRECTORY 0
|
||||
#define UV_FS_O_DSYNC 0x4000000 /* FILE_FLAG_WRITE_THROUGH */
|
||||
#define UV_FS_O_EXLOCK 0
|
||||
#define UV_FS_O_DSYNC 0x04000000 /* FILE_FLAG_WRITE_THROUGH */
|
||||
#define UV_FS_O_EXLOCK 0x10000000 /* EXCLUSIVE SHARING MODE */
|
||||
#define UV_FS_O_NOATIME 0
|
||||
#define UV_FS_O_NOCTTY 0
|
||||
#define UV_FS_O_NOFOLLOW 0
|
||||
#define UV_FS_O_NONBLOCK 0
|
||||
#define UV_FS_O_SYMLINK 0
|
||||
#define UV_FS_O_SYNC 0x8000000 /* FILE_FLAG_WRITE_THROUGH */
|
||||
#define UV_FS_O_SYNC 0x08000000 /* FILE_FLAG_WRITE_THROUGH */
|
||||
|
||||
@ -439,8 +439,15 @@ void fs__open(uv_fs_t* req) {
|
||||
* does. We indiscriminately use all the sharing modes, to match
|
||||
* UNIX semantics. In particular, this ensures that the file can
|
||||
* be deleted even whilst it's open, fixing issue #1449.
|
||||
* We still support exclusive sharing mode, since it is necessary
|
||||
* for opening raw block devices, otherwise Windows will prevent
|
||||
* any attempt to write past the master boot record.
|
||||
*/
|
||||
share = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
|
||||
if (flags & UV_FS_O_EXLOCK) {
|
||||
share = 0;
|
||||
} else {
|
||||
share = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
|
||||
}
|
||||
|
||||
switch (flags & (UV_FS_O_CREAT | UV_FS_O_EXCL | UV_FS_O_TRUNC)) {
|
||||
case 0:
|
||||
|
||||
@ -3061,3 +3061,60 @@ TEST_IMPL(fs_null_req) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
TEST_IMPL(fs_exclusive_sharing_mode) {
|
||||
int r;
|
||||
|
||||
/* Setup. */
|
||||
unlink("test_file");
|
||||
|
||||
ASSERT(UV_FS_O_EXLOCK > 0);
|
||||
|
||||
r = uv_fs_open(NULL,
|
||||
&open_req1,
|
||||
"test_file",
|
||||
O_RDWR | O_CREAT | UV_FS_O_EXLOCK,
|
||||
S_IWUSR | S_IRUSR,
|
||||
NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(open_req1.result >= 0);
|
||||
uv_fs_req_cleanup(&open_req1);
|
||||
|
||||
r = uv_fs_open(NULL,
|
||||
&open_req2,
|
||||
"test_file",
|
||||
O_RDONLY | UV_FS_O_EXLOCK,
|
||||
S_IWUSR | S_IRUSR,
|
||||
NULL);
|
||||
ASSERT(r < 0);
|
||||
ASSERT(open_req2.result < 0);
|
||||
uv_fs_req_cleanup(&open_req2);
|
||||
|
||||
r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(close_req.result == 0);
|
||||
uv_fs_req_cleanup(&close_req);
|
||||
|
||||
r = uv_fs_open(NULL,
|
||||
&open_req2,
|
||||
"test_file",
|
||||
O_RDONLY | UV_FS_O_EXLOCK,
|
||||
S_IWUSR | S_IRUSR,
|
||||
NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(open_req2.result >= 0);
|
||||
uv_fs_req_cleanup(&open_req2);
|
||||
|
||||
r = uv_fs_close(NULL, &close_req, open_req2.result, NULL);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(close_req.result == 0);
|
||||
uv_fs_req_cleanup(&close_req);
|
||||
|
||||
/* Cleanup */
|
||||
unlink("test_file");
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -321,6 +321,9 @@ 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 (fs_null_req)
|
||||
#ifdef _WIN32
|
||||
TEST_DECLARE (fs_exclusive_sharing_mode)
|
||||
#endif
|
||||
TEST_DECLARE (threadpool_queue_work_simple)
|
||||
TEST_DECLARE (threadpool_queue_work_einval)
|
||||
TEST_DECLARE (threadpool_multiple_event_loops)
|
||||
@ -832,6 +835,9 @@ TASK_LIST_START
|
||||
TEST_ENTRY (fs_read_write_null_arguments)
|
||||
TEST_ENTRY (fs_file_pos_after_op_with_offset)
|
||||
TEST_ENTRY (fs_null_req)
|
||||
#ifdef _WIN32
|
||||
TEST_ENTRY (fs_exclusive_sharing_mode)
|
||||
#endif
|
||||
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