Skip to content

Commit

Permalink
win: make uv__get_osfhandle() public
Browse files Browse the repository at this point in the history
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: #1166
Refs: nodejs/node#6369
Fixes: #1291
PR-URL: #1323
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
Reviewed-By: Bartosz Sosnowski <bartosz@janeasystems.com>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
  • Loading branch information
Juan Cruz Viotti authored and cjihrig committed May 30, 2017
1 parent ce770a6 commit e133923
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 0 deletions.
12 changes: 12 additions & 0 deletions docs/src/fs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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 <https://msdn.microsoft.com/en-us/library/ks2530z6.aspx>`_.
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
1 change: 1 addition & 0 deletions include/uv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 5 additions & 0 deletions src/unix/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
5 changes: 5 additions & 0 deletions src/win/handle.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
39 changes: 39 additions & 0 deletions test/test-fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
2 changes: 2 additions & 0 deletions test/test-list.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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 */
Expand Down

0 comments on commit e133923

Please sign in to comment.