Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

win: make uv__get_osfhandle public #1323

Closed
wants to merge 1 commit into from
Closed

win: make uv__get_osfhandle public #1323

wants to merge 1 commit into from

Conversation

jviotti
Copy link
Contributor

@jviotti jviotti commented Apr 26, 2017

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.

This commit implements uv_get_osfhandle() in both src/win/handle.c
and src/unix/fs.c, and returns uv_os_fd_t, which is typedef'd to
HANDLE on Windows, and to int otherwise. If called on UNIX based
operating systems, the function will simply return back the file
descriptor number.

The function is then made public on include/uv.h.

This work is based on #1166

Fixes: #1291
See: nodejs/node#6369
Signed-off-by: Juan Cruz Viotti jviotti@openmailbox.org

docs/src/fs.rst Outdated
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:: 2.0.0 replace uv_file with uv_os_fd_t
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please adjust the version number. The next release will be 1.12.0

@saghul
Copy link
Member

saghul commented Apr 27, 2017

Also please double check uv_os_fd_t is what we want here.

@vtjnash can you please review this?

@vtjnash
Copy link
Member

vtjnash commented Apr 27, 2017

This is valid, but specifically doesn't fix #1291 (in particular, the comment about 'static inline' at https://github.com/libuv/libuv/pull/1323/files#diff-56343bd7ad8bf449c2693082fb3e4081R447 is the exact opposite of the functionality needed by that issue).

I would recommend dropping most of these changes and adding a simple wrapper function somewhere in the src/win/handle.c file:

uv_os_fd_t uv_get_osfhandle(int fd) {
  return uv__get_osfhandle(fd);
}

and then just add the corresponding prototype to the uv.h header:

UV_EXTERN uv_os_fd_t uv_get_osfhandle(int fd);

@jviotti
Copy link
Contributor Author

jviotti commented Apr 28, 2017

@vtjnash Sounds good to me! I'll update the PR in a minute. Just a couple of questions:

  • Should I still preserve the pre-processor conditional that makes uv_get_osfhandle simply return back fd on unix? Given uv_get_osfhandle lives inside src/win, should I create its unix counterpart instead?

  • Should we prefix the public function with fs? E.g: uv_fs_get_osfhandle?

@jviotti
Copy link
Contributor Author

jviotti commented Apr 28, 2017

Updated!

@vtjnash
Copy link
Member

vtjnash commented Apr 28, 2017

This looks correct to me. I can't comment on the naming or formatting of APIs though.

Copy link
Member

@santigimeno santigimeno left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we have a test?

@mafintosh
Copy link

Any chance of getting this in an upcoming release? Using windows specific file apis are tricky without this.

@jviotti
Copy link
Contributor Author

jviotti commented May 2, 2017

I'll try to add a test for this.

@jviotti
Copy link
Contributor Author

jviotti commented May 2, 2017

I added a test case that opens a file, writes a test buffer to it, uses uv_get_osfhandle to get a uv_os_fd_t, and then uses the uv_os_fd_t to read back from the file (ensuring that its really valid), and compare the result with the initial buffer. Let me know what you think. I'm sure the test case can be improved!

I wrote the case on macOS, but I'll give it a go on Windows in a minute.

Copy link
Member

@saghul saghul left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are still some required changes here.

docs/src/fs.rst Outdated
.. 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 ``fd``. On Windows, this calls ``_get_osfhandle``.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please mention the fd is returned unchanged on unix.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also add a link to the relevant MSDN page.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

src/unix/fs.c Outdated
@@ -1367,3 +1367,8 @@ void uv_fs_req_cleanup(uv_fs_t* req) {
uv__free(req->ptr);
req->ptr = NULL;
}


uv_os_fd_t uv_get_osfhandle(int fd) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not the right place for this function, please move it to core.c

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

test/test-fs.c Outdated
#endif

iovs[0] = uv_buf_init(buf, sizeof(test_buf));
r = uv_fs_read(NULL, &read_req, fd, iovs, 1, 0, NULL);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this won't work on Windows, you must pass the fd, not the handle, use open_req1.result instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, yeah, I just realized that, in which case my whole test case doesn't make sense anymore. Can you think of any uv function that interacts with files that could accept a uv_os_fd_t, to ensure its validity? Otherwise, I can reduce the test case to just check that the fd is greater than zero on UNIX, and not an invalid handle on Windows. What do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That should be fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll update the test name though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

test/test-fs.c Outdated
/* Cleanup. */
unlink("test_file");

return 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use MAKE_VALGRIND_HAPPY here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

@addaleax
Copy link
Contributor

@jviotti I think you might need to rebase this :)

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.

This commit implements `uv_get_osfhandle()` in both `src/win/handle.c`
and `src/unix/fs.c`, and returns `uv_os_fd_t`, which is typedef'd to
`HANDLE` on Windows, and to `int` otherwise. If called on UNIX based
operating systems, the function will simply return back the file
descriptor number.

The function is then made public on `include/uv.h`.

This work is based on #1166

Fixes: #1291
See: nodejs/node#6369
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
@jviotti
Copy link
Contributor Author

jviotti commented May 28, 2017

Thanks for the heads up @addaleax. The conflicts are now resolved.

Copy link
Member

@saghul saghul left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@saghul
Copy link
Member

saghul commented May 29, 2017

cjihrig pushed a commit that referenced this pull request May 30, 2017
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>
@cjihrig
Copy link
Contributor

cjihrig commented May 30, 2017

Landed in e133923. Thanks!

@cjihrig cjihrig closed this May 30, 2017
@jviotti jviotti deleted the expose-uv-get-osfhandle branch May 30, 2017 16:15
@davedoesdev
Copy link

Thanks for this fix, works well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants