src: remap invalid file descriptors using `dup2`
When checking for the validity of the stdio file descriptors in PlatformInit()
, this was the code previously used (as in #875):
// Make sure file descriptors 0-2 are valid before we start logging anything.
for (int fd = STDIN_FILENO; fd <= STDERR_FILENO; fd += 1) {
struct stat ignored;
if (fstat(fd, &ignored) == 0)
continue;
// Anything but EBADF means something is seriously wrong. We don't
// have to special-case EINTR, fstat() is not interruptible.
if (errno != EBADF)
abort();
if (fd != open("/dev/null", O_RDWR))
abort();
}
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 the daemon
tool when not passing -f
: https://github.com/nodejs/help/issues/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.