@@ -4,8 +4,6 @@ use crate::errno::{self, Errno};
4
4
#[ cfg( not( target_os = "redox" ) ) ]
5
5
#[ cfg( feature = "fs" ) ]
6
6
use crate :: fcntl:: AtFlags ;
7
- #[ cfg( feature = "fs" ) ]
8
- use crate :: fcntl:: { fcntl, FcntlArg :: F_SETFD , FdFlag , OFlag } ;
9
7
#[ cfg( all(
10
8
feature = "fs" ,
11
9
any(
@@ -461,36 +459,58 @@ pub fn dup2<Fd: AsFd>(oldfd: Fd, newfd: &mut OwnedFd) -> Result<()> {
461
459
Errno :: result( res) . map( drop)
462
460
}
463
461
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
+
464
474
/// Create a new copy of the specified file descriptor using the specified fd
465
475
/// and flags (see [dup(2)](https://man7.org/linux/man-pages/man2/dup.2.html)).
466
476
///
467
477
/// This function behaves similar to `dup2()` but allows for flags to be
468
478
/// specified.
479
+ #[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
469
480
pub fn dup3<Fd : AsFd >(
470
481
oldfd: Fd ,
471
482
newfd: & mut OwnedFd ,
472
- flags: OFlag ,
483
+ flags: crate :: fcntl :: OFlag ,
473
484
) -> 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
+ } ;
486
493
487
- dup2( oldfd, newfd) ?;
494
+ Errno :: result( res) . map( drop)
495
+ }
488
496
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
+ } ;
492
511
493
- Ok ( ( ) )
512
+ Errno :: result( res)
513
+ . map( |_| unsafe { OwnedFd :: from_raw_fd( newfd. into_raw_fd( ) ) } )
494
514
}
495
515
496
516
/// Change the current working directory of the calling process (see
@@ -1267,7 +1287,7 @@ feature! {
1267
1287
target_os = "openbsd" ,
1268
1288
target_os = "solaris"
1269
1289
) ) ]
1270
- pub fn pipe2( flags: OFlag ) -> Result <( OwnedFd , OwnedFd ) > {
1290
+ pub fn pipe2( flags: crate :: fcntl :: OFlag ) -> Result <( OwnedFd , OwnedFd ) > {
1271
1291
let mut fds = mem:: MaybeUninit :: <[ c_int; 2 ] >:: uninit( ) ;
1272
1292
1273
1293
let res =
0 commit comments