src: remap invalid file descriptors using dup2#44461
src: remap invalid file descriptors using dup2#44461nodejs-github-bot merged 1 commit intonodejs:mainfrom
dup2#44461Conversation
|
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 ✌️ |
bnoordhuis
left a comment
There was a problem hiding this comment.
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/nullif 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/nullhas already been given a different file descriptor in the same process, but e.g.stdinhas disappeared in the meantime (as is the case with this issue on FreeBSD with thedaemontool 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.