Skip to content

Commit e89b47a

Browse files
committed
Rewrite dup implementations to allow passing in RawFd
Signed-off-by: Alex Saveau <saveau.alexandre@gmail.com>
1 parent c6af957 commit e89b47a

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(
@@ -459,36 +457,58 @@ pub fn dup2<Fd: AsFd>(oldfd: Fd, newfd: &mut OwnedFd) -> Result<()> {
459457
Errno::result(res).map(drop)
460458
}
461459

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

485-
dup2(oldfd, newfd)?;
492+
Errno::result(res).map(drop)
493+
}
486494

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

491-
Ok(())
510+
Errno::result(res)
511+
.map(|_| unsafe { OwnedFd::from_raw_fd(newfd.into_raw_fd()) })
492512
}
493513

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

12701290
let res =

0 commit comments

Comments
 (0)