Skip to content

Commit 676185c

Browse files
committed
Rewrite dup implementations to allow passing in RawFd
Signed-off-by: Alex Saveau <[email protected]>
1 parent ef375dc commit 676185c

File tree

1 file changed

+41
-21
lines changed

1 file changed

+41
-21
lines changed

src/unistd.rs

+41-21
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ use crate::errno::{self, Errno};
44
#[cfg(not(target_os = "redox"))]
55
#[cfg(feature = "fs")]
66
use crate::fcntl::AtFlags;
7-
#[cfg(feature = "fs")]
8-
use crate::fcntl::{fcntl, FcntlArg::F_SETFD, FdFlag, OFlag};
97
#[cfg(all(
108
feature = "fs",
119
any(
@@ -461,36 +459,58 @@ pub fn dup2<Fd: AsFd>(oldfd: Fd, newfd: &mut OwnedFd) -> Result<()> {
461459
Errno::result(res).map(drop)
462460
}
463461

462+
#[inline]
463+
pub fn dup2_raw<Fd1: AsFd, Fd2: AsRawFd + IntoRawFd>(
464+
oldfd: Fd1,
465+
newfd: Fd2,
466+
) -> Result<OwnedFd> {
467+
let res =
468+
unsafe { libc::dup2(oldfd.as_fd().as_raw_fd(), newfd.as_raw_fd()) };
469+
470+
Errno::result(res)
471+
.map(|_| unsafe { OwnedFd::from_raw_fd(newfd.into_raw_fd()) })
472+
}
473+
464474
/// Create a new copy of the specified file descriptor using the specified fd
465475
/// and flags (see [dup(2)](https://man7.org/linux/man-pages/man2/dup.2.html)).
466476
///
467477
/// This function behaves similar to `dup2()` but allows for flags to be
468478
/// specified.
479+
#[cfg(any(target_os = "android", target_os = "linux"))]
469480
pub fn dup3<Fd: AsFd>(
470481
oldfd: Fd,
471482
newfd: &mut OwnedFd,
472-
flags: OFlag,
483+
flags: crate::fcntl::OFlag,
473484
) -> Result<()> {
474-
dup3_polyfill(oldfd, newfd, flags)
475-
}
476-
477-
#[inline]
478-
fn dup3_polyfill<Fd: AsFd>(
479-
oldfd: Fd,
480-
newfd: &mut OwnedFd,
481-
flags: OFlag,
482-
) -> Result<()> {
483-
if oldfd.as_fd().as_raw_fd() == newfd.as_raw_fd() {
484-
return Err(Errno::EINVAL);
485-
}
485+
let res = unsafe {
486+
libc::syscall(
487+
libc::SYS_dup3,
488+
oldfd.as_fd().as_raw_fd(),
489+
newfd.as_raw_fd(),
490+
flags.bits(),
491+
)
492+
};
486493

487-
dup2(oldfd, newfd)?;
494+
Errno::result(res).map(drop)
495+
}
488496

489-
if flags.contains(OFlag::O_CLOEXEC) {
490-
fcntl(newfd.as_raw_fd(), F_SETFD(FdFlag::FD_CLOEXEC))?;
491-
}
497+
#[cfg(any(target_os = "android", target_os = "linux"))]
498+
pub fn dup3_raw<Fd1: AsFd, Fd2: AsRawFd + IntoRawFd>(
499+
oldfd: Fd1,
500+
newfd: Fd2,
501+
flags: crate::fcntl::OFlag,
502+
) -> Result<OwnedFd> {
503+
let res = unsafe {
504+
libc::syscall(
505+
libc::SYS_dup3,
506+
oldfd.as_fd().as_raw_fd(),
507+
newfd.as_raw_fd(),
508+
flags.bits(),
509+
)
510+
};
492511

493-
Ok(())
512+
Errno::result(res)
513+
.map(|_| unsafe { OwnedFd::from_raw_fd(newfd.into_raw_fd()) })
494514
}
495515

496516
/// Change the current working directory of the calling process (see
@@ -1267,7 +1287,7 @@ feature! {
12671287
target_os = "openbsd",
12681288
target_os = "solaris"
12691289
))]
1270-
pub fn pipe2(flags: OFlag) -> Result<(OwnedFd, OwnedFd)> {
1290+
pub fn pipe2(flags: crate::fcntl::OFlag) -> Result<(OwnedFd, OwnedFd)> {
12711291
let mut fds = mem::MaybeUninit::<[c_int; 2]>::uninit();
12721292

12731293
let res =

0 commit comments

Comments
 (0)