From e133923e935acc3a0b6371372c4ec56f797c8cae Mon Sep 17 00:00:00 2001 From: Juan Cruz Viotti Date: Fri, 28 Apr 2017 10:58:35 -0400 Subject: [PATCH] win: make uv__get_osfhandle() public MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The uv__get_osfhandle() function is a private functio of the Windows subsystem, and its used to get a Windows HANDLE out of a file descriptor number. The motivation behind making this function public is to allow Node.js programs to pass file descriptors created using fs.open() to native Node.js C++ add-ons, and be able to successfully convert them to Windows HANDLEs. Refs: https://github.com/libuv/libuv/pull/1166 Refs: https://github.com/nodejs/node/issues/6369 Fixes: https://github.com/libuv/libuv/issues/1291 PR-URL: https://github.com/libuv/libuv/pull/1323 Reviewed-By: Santiago Gimeno Reviewed-By: Bartosz Sosnowski Reviewed-By: Saúl Ibarra Corretgé Reviewed-By: Colin Ihrig --- docs/src/fs.rst | 12 ++++++++++++ include/uv.h | 1 + src/unix/core.c | 5 +++++ src/win/handle.c | 5 +++++ test/test-fs.c | 39 +++++++++++++++++++++++++++++++++++++++ test/test-list.h | 2 ++ 6 files changed, 64 insertions(+) diff --git a/docs/src/fs.rst b/docs/src/fs.rst index 234713ecc..3f766e393 100644 --- a/docs/src/fs.rst +++ b/docs/src/fs.rst @@ -324,3 +324,15 @@ API These functions are not implemented on Windows. .. seealso:: The :c:type:`uv_req_t` API functions also apply. + +Helper functions +---------------- + +.. c:function:: uv_os_fd_t uv_get_osfhandle(int fd) + + For a file descriptor in the C runtime, get the OS-dependent handle. + On UNIX, returns the ``fd`` intact. On Windows, this calls `_get_osfhandle `_. + Note that the return value is still owned by the C runtime, + any attempts to close it or to use it after closing the fd may lead to malfunction. + + .. versionadded:: 1.12.0 diff --git a/include/uv.h b/include/uv.h index 40f5a4bd5..f076094cc 100644 --- a/include/uv.h +++ b/include/uv.h @@ -1034,6 +1034,7 @@ UV_EXTERN int uv_get_process_title(char* buffer, size_t size); UV_EXTERN int uv_set_process_title(const char* title); UV_EXTERN int uv_resident_set_memory(size_t* rss); UV_EXTERN int uv_uptime(double* uptime); +UV_EXTERN uv_os_fd_t uv_get_osfhandle(int fd); typedef struct { long tv_sec; diff --git a/src/unix/core.c b/src/unix/core.c index 30cdaef7b..8276c6041 100644 --- a/src/unix/core.c +++ b/src/unix/core.c @@ -1324,3 +1324,8 @@ int uv_os_gethostname(char* buffer, size_t* size) { *size = len; return 0; } + + +uv_os_fd_t uv_get_osfhandle(int fd) { + return fd; +} diff --git a/src/win/handle.c b/src/win/handle.c index 72b49d979..39150702d 100644 --- a/src/win/handle.c +++ b/src/win/handle.c @@ -152,3 +152,8 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) { int uv_is_closing(const uv_handle_t* handle) { return !!(handle->flags & (UV__HANDLE_CLOSING | UV_HANDLE_CLOSED)); } + + +uv_os_fd_t uv_get_osfhandle(int fd) { + return uv__get_osfhandle(fd); +} diff --git a/test/test-fs.c b/test/test-fs.c index ce39ebd43..c482ab5c7 100644 --- a/test/test-fs.c +++ b/test/test-fs.c @@ -2765,3 +2765,42 @@ TEST_IMPL(fs_read_write_null_arguments) { return 0; } + + +TEST_IMPL(get_osfhandle_valid_handle) { + int r; + uv_os_fd_t fd; + + /* Setup. */ + unlink("test_file"); + + loop = uv_default_loop(); + + r = uv_fs_open(NULL, + &open_req1, + "test_file", + O_RDWR | O_CREAT, + S_IWUSR | S_IRUSR, + NULL); + ASSERT(r >= 0); + ASSERT(open_req1.result >= 0); + uv_fs_req_cleanup(&open_req1); + + fd = uv_get_osfhandle(open_req1.result); +#ifdef _WIN32 + ASSERT(fd != INVALID_HANDLE_VALUE); +#else + ASSERT(fd >= 0); +#endif + + 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); + + /* Cleanup. */ + unlink("test_file"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/test/test-list.h b/test/test-list.h index 76cb71e16..3571aa230 100644 --- a/test/test-list.h +++ b/test/test-list.h @@ -305,6 +305,7 @@ TEST_DECLARE (fs_open_dir) TEST_DECLARE (fs_rename_to_existing_file) TEST_DECLARE (fs_write_multiple_bufs) 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 (threadpool_queue_work_simple) @@ -792,6 +793,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 (get_osfhandle_valid_handle) TEST_ENTRY (threadpool_queue_work_simple) TEST_ENTRY (threadpool_queue_work_einval) #if defined(__PPC__) || defined(__PPC64__) /* For linux PPC and AIX */