Skip to content
This repository was archived by the owner on May 4, 2018. It is now read-only.

unix, windows: add uv_fileno - #1435

Merged
saghul merged 2 commits into
joyent:masterfrom
saghul:uv_fileno
Aug 27, 2014
Merged

unix, windows: add uv_fileno#1435
saghul merged 2 commits into
joyent:masterfrom
saghul:uv_fileno

Conversation

@saghul

@saghul saghul commented Aug 22, 2014

Copy link
Copy Markdown
Contributor

Returns the platform specific file descriptor for handles that are
backed by one. The datatype is abstracted as uv_os_fd_t, which maps to
int on Unices and HANDLE on Windows.

Users can use this function to set specific socket options, for example,
in a non portable way.

This function is essentially a shotgun, you better be careful with
whatever you do with it, don't blame me if you used it to get the fd of
a stream, close it yourself and expect things to Just Work.

@saghul

saghul commented Aug 22, 2014

Copy link
Copy Markdown
Contributor Author

This patch is unifinished (Windows part and tests are missing), but I wanted to start a discussion about it. I can't think of a way which would please everyone while keeping our fds hidden, so I think it might not be that bad to expose them for those with legit use cases such as setting some socket options here and there, we can't possibly map all of them.

About the Windows side, HANDLE is just a void*, which means we wouldn't be able to cast it to int because of 64bit systems. However, reading around seems like only the lower 32 bits are used because a process can only have 2^24 handles in that handle table. Anyway, I went for the typedef, since this is a platform dependent thing and feels more future-proof.

Thoughts?

Calling the cavalry! @indutny, @bnoordhuis, @piscisaureus

@txdv

txdv commented Aug 22, 2014

Copy link
Copy Markdown

IMO this is a good idea.

Let the user do whatever he wants.

@txdv

txdv commented Aug 22, 2014

Copy link
Copy Markdown

This is such an easy fix, why didn't we have it earlier?

@saghul

saghul commented Aug 22, 2014

Copy link
Copy Markdown
Contributor Author

Just like with scotch, some things take time to become better, I guess :-P

Comment thread include/uv.h Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Maybe UV_EXTERN int uv_file(const uv_handle_t* handle, uv_os_fd_t* fd);? Libuv can't really return a meaningful error now.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

That crossed my mind, but in the end I thought that I'd just return -1 when there is no fd. We could give EINVAL if you pass an unsupported handle type, I guess.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

But how are you going to do that on Windows? HANDLE is a typedef for void*.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I guess the same way Windows does for INVALID_SOCKET :-P On a more serious note, I do like your proposal, I'll change this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

FWIW, Windows defines INVALID_SOCKET as SOCKET(~0).

@saghul

saghul commented Aug 22, 2014

Copy link
Copy Markdown
Contributor Author

Updated the API and Unix implementation as per Ben's suggestions. It returns EINVAL if the handle is not a stream, poll or udp and EBADF if the fd is -1.

Comment thread src/unix/core.c Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It's kind of bad style to return an error code but still mutate the out parameter, IMO.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

True that, will fix.

@saghul

saghul commented Aug 23, 2014

Copy link
Copy Markdown
Contributor Author

Added tests and Windows implementation. The TTY test fails, I need to open $conin it seems, like the TTY test does, will do.

Comment thread test/test-handle-fileno.c Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can't you filter on UV__HANDLE_CLOSING in uv_fileno()?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure what guarantees we make about it. The handle (libuv wise) is closing, but the actual Windows HANDLE might need to stick around for a bit more.

@saghul

saghul commented Aug 23, 2014

Copy link
Copy Markdown
Contributor Author

Tests pass on Windows now.

@saghul

saghul commented Aug 23, 2014

Copy link
Copy Markdown
Contributor Author

@bnoordhuis thanks, const-ified the handle now.

@saghul

saghul commented Aug 27, 2014

Copy link
Copy Markdown
Contributor Author

Any further comments on this?

@txdv

txdv commented Aug 27, 2014

Copy link
Copy Markdown

Why do we set it to invalid?

@saghul

saghul commented Aug 27, 2014

Copy link
Copy Markdown
Contributor Author

Why do we set it to invalid?

Because otherwise you get it with uv_fileno after you have closed it so it might belong to another handle that reused it. This wasn't a problem before, because it was not exposed, but now that people get access to file descriptors, we cannot give them stalled ones.

Another possibility might be to return EBADF if uv_is_closing(handle). That might actually simplify things a bit...

@saghul

saghul commented Aug 27, 2014

Copy link
Copy Markdown
Contributor Author

I'll give that a shot (I think that's what @bnoordhuis said before, but I didn't quite get it until now). I'd still leave the commit that sets handles to invalid, as a defense mechanism.

saghul added 2 commits August 27, 2014 10:53
Returns the platform specific file descriptor for handles that are
backed by one. The datatype is abstracted as uv_os_fd_t, which maps to
int on Unices and HANDLE on Windows.

Users can use this function to set specific socket options, for example,
in a non portable way.

This function is essentially a shotgun, you better be careful with
whatever you do with it, don't blame me if you used it to get the fd of
a stream, close it yourself and expect things to Just Work.
Set the socket to INVALID_SOCKET foir TCP and UDP handles and
the handle to INVALID_HANDLE_VALUE on TTY handles after closing them.
@saghul

saghul commented Aug 27, 2014

Copy link
Copy Markdown
Contributor Author

Updated with uv_is_closing check, now we no longer need any ifdef-ery on the tests \o/.

@bnoordhuis

Copy link
Copy Markdown
Contributor

LGTM. And yes, that was what I meant. :-)

@saghul
saghul merged commit fabafd6 into joyent:master Aug 27, 2014
@saghul

saghul commented Aug 27, 2014

Copy link
Copy Markdown
Contributor Author

Thanks folks, landed! Load your shotguns.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants