Skip to content

Commit aeea7cf

Browse files
authored
refactor: make dup3 wrapper call the real dup3 (#2268)
* refactor: make dup3 wrapper call the real dup3 * fix imports * respond to review
1 parent 3195d9e commit aeea7cf

File tree

3 files changed

+24
-20
lines changed

3 files changed

+24
-20
lines changed

changelog/2268.fixed.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Changed the `dup3` wrapper to perform a real call to `dup3` instead of emulating it via `dup2` and `fcntl` to get rid of race condition

changelog/2268.removed.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Removed the `dup3` wrapper on macOS, which was emulated via `dup2` and `fcntl` and could cause a race condition. The `dup3` system call is not supported on macOS.

src/unistd.rs

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,17 @@ use crate::fcntl::at_rawfd;
1212
use crate::fcntl::AtFlags;
1313

1414
#[cfg(feature = "fs")]
15-
use crate::fcntl::{fcntl, FcntlArg::F_SETFD, FdFlag, OFlag};
15+
#[cfg(any(
16+
linux_android,
17+
freebsdlike,
18+
solarish,
19+
netbsdlike,
20+
target_os = "emscripten",
21+
target_os = "fuchsia",
22+
target_os = "hurd",
23+
target_os = "redox",
24+
))]
25+
use crate::fcntl::OFlag;
1626
#[cfg(all(feature = "fs", bsd))]
1727
use crate::sys::stat::FileFlag;
1828
#[cfg(feature = "fs")]
@@ -426,30 +436,22 @@ pub fn dup2(oldfd: RawFd, newfd: RawFd) -> Result<RawFd> {
426436
}
427437

428438
/// Create a new copy of the specified file descriptor using the specified fd
429-
/// and flags (see [dup(2)](https://man7.org/linux/man-pages/man2/dup.2.html)).
439+
/// and flags (see [`dup(2)`](https://man7.org/linux/man-pages/man2/dup.2.html)).
430440
///
431441
/// This function behaves similar to `dup2()` but allows for flags to be
432442
/// specified.
443+
#[cfg(any(
444+
netbsdlike,
445+
solarish,
446+
target_os = "freebsd",
447+
target_os = "fuchsia",
448+
target_os = "hurd",
449+
target_os = "linux"
450+
))]
433451
pub fn dup3(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result<RawFd> {
434-
dup3_polyfill(oldfd, newfd, flags)
435-
}
452+
let res = unsafe { libc::dup3(oldfd, newfd, flags.bits()) };
436453

437-
#[inline]
438-
fn dup3_polyfill(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result<RawFd> {
439-
if oldfd == newfd {
440-
return Err(Errno::EINVAL);
441-
}
442-
443-
let fd = dup2(oldfd, newfd)?;
444-
445-
if flags.contains(OFlag::O_CLOEXEC) {
446-
if let Err(e) = fcntl(fd, F_SETFD(FdFlag::FD_CLOEXEC)) {
447-
let _ = close(fd);
448-
return Err(e);
449-
}
450-
}
451-
452-
Ok(fd)
454+
Errno::result(res)
453455
}
454456

455457
/// Change the current working directory of the calling process (see

0 commit comments

Comments
 (0)