-
Notifications
You must be signed in to change notification settings - Fork 29.6k
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
src: remap invalid file descriptors using dup2
#44461
Conversation
Review requested:
|
69293a1
to
b3c392e
Compare
“hoping” is doing a lot of work here 🙂 This was actually spec’d behavior in previous POSIX versions, and I was quite surprised to learn (through this PR) that the spec actually changed in this regard. I’d leave a comment in the source code about this, since others might be surprised by this as well. |
Got you. I'll do that in a little bit ✌️ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TBH, this change adds more failure paths and I don't think it's actually necessary.
The "open() returns the lowest available file descriptor" convention is so deeply codified in the UNIX ecosystem that it's never going away, no matter what POSIX says. There's simply too much software built around that assumption.
While I do agree with this, there still are specific cases where "available" means something different to what's expected. Case in point: #include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
int main(void) {
system("echo && fstat | grep a.out");
int fd = open("/dev/null", O_RDWR);
printf("\n/dev/null: %d\n", fd);
return 0;
} Running this on FreeBSD in a separate session with
(This is actually the issue nodejs/help#2411 had.) Here, |
da101fe
to
326a490
Compare
When checking for the validity of the stdio file descriptors (nodejs#875), ones which don't exist are intended to be remapped to /dev/null (and, if that doesn't work, we abort). This however doesn't work on all platforms and in all cases, and is not anymore required by POSIX; instead, use the `dup2` syscall as a more robust solution (conforms to POSIX.1). Fixes: nodejs/help#2411 Refs: nodejs#875
Ah okay, fair enough. Fd 0 points to a kind of zombie file description in your example, i.e., it's technically still open but not actually usable? |
AFAIU the file descriptor is never actually closed, so it isn't ever marked as unused ( |
Wait, but fstat() still fails with EBADF? How does that work? |
I don't know, there are plenty of places along the line where I could investigate further if you'd like an exact answer but I don't see how it's too relevant outside of the FreeBSD kernel :P |
"Zombie file descriptor" is good enough for me. :-) |
Is there anything left for me to do here? |
Landed in 0c8b141 |
When checking for the validity of the stdio file descriptors (#875), ones which don't exist are intended to be remapped to /dev/null (and, if that doesn't work, we abort). This however doesn't work on all platforms and in all cases, and is not anymore required by POSIX; instead, use the `dup2` syscall as a more robust solution (conforms to POSIX.1). Fixes: nodejs/help#2411 Refs: #875 PR-URL: #44461 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
When checking for the validity of the stdio file descriptors (#875), ones which don't exist are intended to be remapped to /dev/null (and, if that doesn't work, we abort). This however doesn't work on all platforms and in all cases, and is not anymore required by POSIX; instead, use the `dup2` syscall as a more robust solution (conforms to POSIX.1). Fixes: nodejs/help#2411 Refs: #875 PR-URL: #44461 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
When checking for the validity of the stdio file descriptors (#875), ones which don't exist are intended to be remapped to /dev/null (and, if that doesn't work, we abort). This however doesn't work on all platforms and in all cases, and is not anymore required by POSIX; instead, use the `dup2` syscall as a more robust solution (conforms to POSIX.1). Fixes: nodejs/help#2411 Refs: #875 PR-URL: #44461 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
When checking for the validity of the stdio file descriptors (#875), ones which don't exist are intended to be remapped to /dev/null (and, if that doesn't work, we abort). This however doesn't work on all platforms and in all cases, and is not anymore required by POSIX; instead, use the `dup2` syscall as a more robust solution (conforms to POSIX.1). Fixes: nodejs/help#2411 Refs: #875 PR-URL: #44461 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
When checking for the validity of the stdio file descriptors (#875), ones which don't exist are intended to be remapped to /dev/null (and, if that doesn't work, we abort). This however doesn't work on all platforms and in all cases, and is not anymore required by POSIX; instead, use the `dup2` syscall as a more robust solution (conforms to POSIX.1). Fixes: nodejs/help#2411 Refs: #875 PR-URL: #44461 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
When checking for the validity of the stdio file descriptors in
PlatformInit()
, this was the code previously used (as in #875):As I understand it, the intention behind this is to map file descriptors to
/dev/null
if they don't exist, by hoping the next file descriptor to be given will be the one which doesn't exist. This is imperfect as it is very platform dependent and breaks when/dev/null
has already been given a different file descriptor in the same process, but e.g.stdin
has disappeared in the meantime (as is the case with this issue on FreeBSD with thedaemon
tool when not passing-f
: nodejs/help#2411).Instead, this patch uses the
dup2(2)
syscall to properly remap the missing stdio file descriptor to what/dev/null
's file descriptor actually is.