GeezerVison is showing github.com — src: remap invalid file descriptors using `dup2` · nodejs/node@325254c
File tree
Expand file treeCollapse file tree
Open diff view settings
Expand file treeCollapse file tree
Open diff view settings
Collapse file
Copy file name to clipboardExpand all lines: src/node.cc +23-2Lines changed: 23 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -469,11 +469,32 @@ static void PlatformInit(ProcessInitializationFlags::Flags flags) { |
469 | 469 | for (auto& s : stdio) { |
470 | 470 | const int fd = &s - stdio; |
471 | 471 | if (fstat(fd, &s.stat) == 0) continue; |
| 472 | + |
472 | 473 | // Anything but EBADF means something is seriously wrong. We don't |
473 | 474 | // have to special-case EINTR, fstat() is not interruptible. |
474 | 475 | if (errno != EBADF) ABORT(); |
475 | | - if (fd != open("/dev/null", O_RDWR)) ABORT(); |
476 | | - if (fstat(fd, &s.stat) != 0) ABORT(); |
| 476 | + |
| 477 | + // If EBADF (file descriptor doesn't exist), open /dev/null and duplicate |
| 478 | + // its file descriptor to the invalid file descriptor. Make sure *that* |
| 479 | + // file descriptor is valid. POSIX doesn't guarantee the next file |
| 480 | + // descriptor open(2) gives us is the lowest available number anymore in |
| 481 | + // POSIX.1-2017, which is why dup2(2) is needed. |
| 482 | + int null_fd; |
| 483 | + |
| 484 | + do { |
| 485 | + null_fd = open("/dev/null", O_RDWR); |
| 486 | + } while (null_fd < 0 && errno == EINTR); |
| 487 | + |
| 488 | + if (null_fd != fd) { |
| 489 | + int err; |
| 490 | + |
| 491 | + do { |
| 492 | + err = dup2(null_fd, fd); |
| 493 | + } while (err < 0 && errno == EINTR); |
| 494 | + CHECK_EQ(err, 0); |
| 495 | + } |
| 496 | + |
| 497 | + if (fstat(fd, &s.stat) < 0) ABORT(); |
477 | 498 | } |
478 | 499 | } |
479 | 500 |
|
|