@@ -20,6 +20,8 @@ use nix::errno::Errno;
20
20
use nix:: pty:: openpty;
21
21
#[ cfg( unix) ]
22
22
use nix:: unistd:: { self , Gid , Pid , Uid , Whence } ;
23
+ #[ cfg( unix) ]
24
+ use std:: os:: unix:: io:: RawFd ;
23
25
24
26
use super :: errno:: errors;
25
27
use crate :: function:: { IntoPyNativeFunc , OptionalArg , PyFuncArgs } ;
@@ -925,6 +927,96 @@ fn os_chdir(path: PyStringRef, vm: &VirtualMachine) -> PyResult<()> {
925
927
env:: set_current_dir ( path. as_str ( ) ) . map_err ( |err| convert_io_error ( vm, err) )
926
928
}
927
929
930
+ #[ cfg( unix) ]
931
+ fn os_get_inheritable ( fd : RawFd , vm : & VirtualMachine ) -> PyResult < bool > {
932
+ use nix:: fcntl:: fcntl;
933
+ use nix:: fcntl:: FcntlArg ;
934
+ let flags = fcntl ( fd, FcntlArg :: F_GETFD ) ;
935
+ match flags {
936
+ Ok ( ret) => Ok ( ( ret & libc:: FD_CLOEXEC ) == 0 ) ,
937
+ Err ( err) => Err ( convert_nix_error ( vm, err) ) ,
938
+ }
939
+ }
940
+
941
+ #[ cfg( unix) ]
942
+ fn os_set_inheritable ( fd : RawFd , inheritable : bool , vm : & VirtualMachine ) -> PyResult < ( ) > {
943
+ let _set_flag = || {
944
+ use nix:: fcntl:: fcntl;
945
+ use nix:: fcntl:: FcntlArg ;
946
+ use nix:: fcntl:: FdFlag ;
947
+
948
+ let flags = FdFlag :: from_bits_truncate ( fcntl ( fd, FcntlArg :: F_GETFD ) ?) ;
949
+ let mut new_flags = flags;
950
+ new_flags. set ( FdFlag :: from_bits_truncate ( libc:: FD_CLOEXEC ) , !inheritable) ;
951
+ if flags != new_flags {
952
+ fcntl ( fd, FcntlArg :: F_SETFD ( new_flags) ) ?;
953
+ }
954
+ Ok ( ( ) )
955
+ } ;
956
+ _set_flag ( ) . or_else ( |err| Err ( convert_nix_error ( vm, err) ) )
957
+ }
958
+
959
+ #[ cfg( unix) ]
960
+ fn os_get_blocking ( fd : RawFd , vm : & VirtualMachine ) -> PyResult < bool > {
961
+ use nix:: fcntl:: fcntl;
962
+ use nix:: fcntl:: FcntlArg ;
963
+ let flags = fcntl ( fd, FcntlArg :: F_GETFL ) ;
964
+ match flags {
965
+ Ok ( ret) => Ok ( ( ret & libc:: O_NONBLOCK ) == 0 ) ,
966
+ Err ( err) => Err ( convert_nix_error ( vm, err) ) ,
967
+ }
968
+ }
969
+
970
+ #[ cfg( unix) ]
971
+ fn os_set_blocking ( fd : RawFd , blocking : bool , vm : & VirtualMachine ) -> PyResult < ( ) > {
972
+ let _set_flag = || {
973
+ use nix:: fcntl:: fcntl;
974
+ use nix:: fcntl:: FcntlArg ;
975
+ use nix:: fcntl:: OFlag ;
976
+
977
+ let flags = OFlag :: from_bits_truncate ( fcntl ( fd, FcntlArg :: F_GETFL ) ?) ;
978
+ let mut new_flags = flags;
979
+ new_flags. set ( OFlag :: from_bits_truncate ( libc:: O_NONBLOCK ) , !blocking) ;
980
+ if flags != new_flags {
981
+ fcntl ( fd, FcntlArg :: F_SETFL ( new_flags) ) ?;
982
+ }
983
+ Ok ( ( ) )
984
+ } ;
985
+ _set_flag ( ) . or_else ( |err| Err ( convert_nix_error ( vm, err) ) )
986
+ }
987
+
988
+ #[ cfg( unix) ]
989
+ fn os_pipe ( vm : & VirtualMachine ) -> PyResult < ( RawFd , RawFd ) > {
990
+ use nix:: unistd:: close;
991
+ use nix:: unistd:: pipe;
992
+ let ( rfd, wfd) = pipe ( ) . map_err ( |err| convert_nix_error ( vm, err) ) ?;
993
+ os_set_inheritable ( rfd, false , vm)
994
+ . and_then ( |_| os_set_inheritable ( wfd, false , vm) )
995
+ . or_else ( |err| {
996
+ let _ = close ( rfd) ;
997
+ let _ = close ( wfd) ;
998
+ Err ( err)
999
+ } ) ?;
1000
+ Ok ( ( rfd, wfd) )
1001
+ }
1002
+
1003
+ // cfg from nix
1004
+ #[ cfg( any(
1005
+ target_os = "android" ,
1006
+ target_os = "dragonfly" ,
1007
+ target_os = "emscripten" ,
1008
+ target_os = "freebsd" ,
1009
+ target_os = "linux" ,
1010
+ target_os = "netbsd" ,
1011
+ target_os = "openbsd"
1012
+ ) ) ]
1013
+ fn os_pipe2 ( flags : libc:: c_int , vm : & VirtualMachine ) -> PyResult < ( RawFd , RawFd ) > {
1014
+ use nix:: fcntl:: OFlag ;
1015
+ use nix:: unistd:: pipe2;
1016
+ let oflags = OFlag :: from_bits_truncate ( flags) ;
1017
+ pipe2 ( oflags) . map_err ( |err| convert_nix_error ( vm, err) )
1018
+ }
1019
+
928
1020
#[ cfg( unix) ]
929
1021
fn os_system ( command : PyStringRef , _vm : & VirtualMachine ) -> PyResult < i32 > {
930
1022
use libc:: system;
@@ -1277,12 +1369,17 @@ fn extend_module_platform_specific(vm: &VirtualMachine, module: PyObjectRef) ->
1277
1369
extend_module ! ( vm, module, {
1278
1370
"access" => ctx. new_rustfunc( os_access) ,
1279
1371
"chmod" => ctx. new_rustfunc( os_chmod) ,
1372
+ "get_inheritable" => ctx. new_rustfunc( os_get_inheritable) , // TODO: windows
1373
+ "get_blocking" => ctx. new_rustfunc( os_get_blocking) ,
1280
1374
"getppid" => ctx. new_rustfunc( os_getppid) ,
1281
1375
"getgid" => ctx. new_rustfunc( os_getgid) ,
1282
1376
"getegid" => ctx. new_rustfunc( os_getegid) ,
1283
1377
"getpgid" => ctx. new_rustfunc( os_getpgid) ,
1284
1378
"getuid" => ctx. new_rustfunc( os_getuid) ,
1285
1379
"geteuid" => ctx. new_rustfunc( os_geteuid) ,
1380
+ "pipe" => ctx. new_rustfunc( os_pipe) , //TODO: windows
1381
+ "set_inheritable" => ctx. new_rustfunc( os_set_inheritable) , // TODO: windows
1382
+ "set_blocking" => ctx. new_rustfunc( os_set_blocking) ,
1286
1383
"setgid" => ctx. new_rustfunc( os_setgid) ,
1287
1384
"setpgid" => ctx. new_rustfunc( os_setpgid) ,
1288
1385
"setuid" => ctx. new_rustfunc( os_setuid) ,
@@ -1305,6 +1402,7 @@ fn extend_module_platform_specific(vm: &VirtualMachine, module: PyObjectRef) ->
1305
1402
"EX_NOPERM" => ctx. new_int( exitcode:: NOPERM as i8 ) ,
1306
1403
"EX_CONFIG" => ctx. new_int( exitcode:: CONFIG as i8 ) ,
1307
1404
"O_DSYNC" => ctx. new_int( libc:: O_DSYNC ) ,
1405
+ "O_NONBLOCK" => ctx. new_int( libc:: O_NONBLOCK ) ,
1308
1406
"O_NDELAY" => ctx. new_int( libc:: O_NDELAY ) ,
1309
1407
"O_NOCTTY" => ctx. new_int( libc:: O_NOCTTY ) ,
1310
1408
"O_CLOEXEC" => ctx. new_int( libc:: O_CLOEXEC ) ,
@@ -1335,6 +1433,19 @@ fn extend_module_platform_specific(vm: &VirtualMachine, module: PyObjectRef) ->
1335
1433
"SEEK_DATA" => ctx. new_int( Whence :: SeekData as i8 ) ,
1336
1434
"SEEK_HOLE" => ctx. new_int( Whence :: SeekHole as i8 )
1337
1435
} ) ;
1436
+ // cfg from nix
1437
+ #[ cfg( any(
1438
+ target_os = "android" ,
1439
+ target_os = "dragonfly" ,
1440
+ target_os = "emscripten" ,
1441
+ target_os = "freebsd" ,
1442
+ target_os = "linux" ,
1443
+ target_os = "netbsd" ,
1444
+ target_os = "openbsd"
1445
+ ) ) ]
1446
+ extend_module ! ( vm, module, {
1447
+ "pipe2" => ctx. new_rustfunc( os_pipe2) ,
1448
+ } ) ;
1338
1449
1339
1450
module
1340
1451
}
0 commit comments