@@ -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(
@@ -459,36 +457,58 @@ pub fn dup2<Fd: AsFd>(oldfd: Fd, newfd: &mut OwnedFd) -> Result<()> {
459
457
Errno :: result( res) . map( drop)
460
458
}
461
459
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
+
462
472
/// Create a new copy of the specified file descriptor using the specified fd
463
473
/// and flags (see [dup(2)](https://man7.org/linux/man-pages/man2/dup.2.html)).
464
474
///
465
475
/// This function behaves similar to `dup2()` but allows for flags to be
466
476
/// specified.
477
+ #[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
467
478
pub fn dup3<Fd : AsFd >(
468
479
oldfd: Fd ,
469
480
newfd: & mut OwnedFd ,
470
- flags: OFlag ,
481
+ flags: crate :: fcntl :: OFlag ,
471
482
) -> 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
+ } ;
484
491
485
- dup2( oldfd, newfd) ?;
492
+ Errno :: result( res) . map( drop)
493
+ }
486
494
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
+ } ;
490
509
491
- Ok ( ( ) )
510
+ Errno :: result( res)
511
+ . map( |_| unsafe { OwnedFd :: from_raw_fd( newfd. into_raw_fd( ) ) } )
492
512
}
493
513
494
514
/// Change the current working directory of the calling process (see
@@ -1264,7 +1284,7 @@ feature! {
1264
1284
target_os = "openbsd" ,
1265
1285
target_os = "solaris"
1266
1286
) ) ]
1267
- pub fn pipe2( flags: OFlag ) -> Result <( OwnedFd , OwnedFd ) > {
1287
+ pub fn pipe2( flags: crate :: fcntl :: OFlag ) -> Result <( OwnedFd , OwnedFd ) > {
1268
1288
let mut fds = mem:: MaybeUninit :: <[ c_int; 2 ] >:: uninit( ) ;
1269
1289
1270
1290
let res =
0 commit comments