Skip to content
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

unistd::dup3 never uses the dup3 syscall (even if it might be available) #939

Closed
tbu- opened this issue Sep 2, 2018 · 1 comment · Fixed by #2268
Closed

unistd::dup3 never uses the dup3 syscall (even if it might be available) #939

tbu- opened this issue Sep 2, 2018 · 1 comment · Fixed by #2268

Comments

@tbu-
Copy link
Contributor

tbu- commented Sep 2, 2018

nix/src/unistd.rs

Lines 381 to 397 in 70cce1a

#[inline]
fn dup3_polyfill(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result<RawFd> {
if oldfd == newfd {
return Err(Error::Sys(Errno::EINVAL));
}
let fd = try!(dup2(oldfd, newfd));
if flags.contains(OFlag::O_CLOEXEC) {
if let Err(e) = fcntl(fd, F_SETFD(FdFlag::FD_CLOEXEC)) {
let _ = close(fd);
return Err(e);
}
}
Ok(fd)
}

This means that using it in multithreaded applications results in races even on platforms where a proper dup3 is supported.

I think it would be best if it used dup3 if it is available and only falls back to dup2 if dup3 is not available.

@asomers
Copy link
Member

asomers commented Sep 2, 2018

Indeed. It looks like the actual dup3 syscall was removed in 9e93533 . But I would go further than you suggest. Our usual convention in Nix is to not even attempt to emulate nonexistent syscalls. Of course, we don't want to remove things that people may be using. See pipe2 in src/unistd.rs. Would you be willing to try fixing this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants