@@ -4,8 +4,6 @@ use crate::errno::{self, Errno};
44#[ cfg( not( target_os = "redox" ) ) ]
55#[ cfg( feature = "fs" ) ]
66use 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" ) ) ]
469480pub 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