@@ -6,6 +6,10 @@ use std::time::{Duration, SystemTime};
66use std:: { env, fs} ;
77
88use bitflags:: bitflags;
9+ #[ cfg( unix) ]
10+ use nix:: errno:: Errno ;
11+ #[ cfg( unix) ]
12+ use nix:: unistd:: { self , Gid , Pid , Uid } ;
913use num_traits:: cast:: ToPrimitive ;
1014
1115use crate :: function:: { IntoPyNativeFunc , PyFuncArgs } ;
@@ -174,6 +178,43 @@ fn convert_io_error(vm: &VirtualMachine, err: io::Error) -> PyObjectRef {
174178 os_error
175179}
176180
181+ #[ cfg( unix) ]
182+ fn convert_nix_error ( vm : & VirtualMachine , err : nix:: Error ) -> PyObjectRef {
183+ let nix_error = match err {
184+ nix:: Error :: InvalidPath => {
185+ let exc_type = vm. ctx . exceptions . file_not_found_error . clone ( ) ;
186+ vm. new_exception ( exc_type, err. to_string ( ) )
187+ }
188+ nix:: Error :: InvalidUtf8 => {
189+ let exc_type = vm. ctx . exceptions . unicode_error . clone ( ) ;
190+ vm. new_exception ( exc_type, err. to_string ( ) )
191+ }
192+ nix:: Error :: UnsupportedOperation => {
193+ let exc_type = vm. ctx . exceptions . runtime_error . clone ( ) ;
194+ vm. new_exception ( exc_type, err. to_string ( ) )
195+ }
196+ nix:: Error :: Sys ( errno) => {
197+ let exc_type = convert_nix_errno ( vm, errno) ;
198+ vm. new_exception ( exc_type, err. to_string ( ) )
199+ }
200+ } ;
201+
202+ if let nix:: Error :: Sys ( errno) = err {
203+ vm. set_attr ( & nix_error, "errno" , vm. ctx . new_int ( errno as i32 ) )
204+ . unwrap ( ) ;
205+ }
206+
207+ nix_error
208+ }
209+
210+ #[ cfg( unix) ]
211+ fn convert_nix_errno ( vm : & VirtualMachine , errno : Errno ) -> PyClassRef {
212+ match errno {
213+ Errno :: EPERM => vm. ctx . exceptions . permission_error . clone ( ) ,
214+ _ => vm. ctx . exceptions . os_error . clone ( ) ,
215+ }
216+ }
217+
177218fn os_error ( vm : & VirtualMachine , args : PyFuncArgs ) -> PyResult {
178219 arg_check ! (
179220 vm,
@@ -709,6 +750,105 @@ fn os_rename(src: PyStringRef, dst: PyStringRef, vm: &VirtualMachine) -> PyResul
709750 fs:: rename ( & src. value , & dst. value ) . map_err ( |err| convert_io_error ( vm, err) )
710751}
711752
753+ fn os_getpid ( vm : & VirtualMachine ) -> PyObjectRef {
754+ let pid = std:: process:: id ( ) ;
755+ vm. new_int ( pid)
756+ }
757+
758+ #[ cfg( unix) ]
759+ fn os_getppid ( vm : & VirtualMachine ) -> PyObjectRef {
760+ let ppid = unistd:: getppid ( ) . as_raw ( ) ;
761+ vm. new_int ( ppid)
762+ }
763+
764+ #[ cfg( unix) ]
765+ fn os_getgid ( vm : & VirtualMachine ) -> PyObjectRef {
766+ let gid = unistd:: getgid ( ) . as_raw ( ) ;
767+ vm. new_int ( gid)
768+ }
769+
770+ #[ cfg( unix) ]
771+ fn os_getegid ( vm : & VirtualMachine ) -> PyObjectRef {
772+ let egid = unistd:: getegid ( ) . as_raw ( ) ;
773+ vm. new_int ( egid)
774+ }
775+
776+ #[ cfg( unix) ]
777+ fn os_getpgid ( pid : PyIntRef , vm : & VirtualMachine ) -> PyObjectRef {
778+ let pid = pid. as_bigint ( ) . to_u32 ( ) . unwrap ( ) ;
779+
780+ match unistd:: getpgid ( Some ( Pid :: from_raw ( pid as i32 ) ) ) {
781+ Ok ( pgid) => vm. new_int ( pgid. as_raw ( ) ) ,
782+ Err ( err) => convert_nix_error ( vm, err) ,
783+ }
784+ }
785+
786+ #[ cfg( unix) ]
787+ fn os_getsid ( pid : PyIntRef , vm : & VirtualMachine ) -> PyObjectRef {
788+ let pid = pid. as_bigint ( ) . to_u32 ( ) . unwrap ( ) ;
789+
790+ match unistd:: getsid ( Some ( Pid :: from_raw ( pid as i32 ) ) ) {
791+ Ok ( sid) => vm. new_int ( sid. as_raw ( ) ) ,
792+ Err ( err) => convert_nix_error ( vm, err) ,
793+ }
794+ }
795+
796+ #[ cfg( unix) ]
797+ fn os_getuid ( vm : & VirtualMachine ) -> PyObjectRef {
798+ let uid = unistd:: getuid ( ) . as_raw ( ) ;
799+ vm. new_int ( uid)
800+ }
801+
802+ #[ cfg( unix) ]
803+ fn os_geteuid ( vm : & VirtualMachine ) -> PyObjectRef {
804+ let euid = unistd:: geteuid ( ) . as_raw ( ) ;
805+ vm. new_int ( euid)
806+ }
807+
808+ #[ cfg( unix) ]
809+ fn os_setgid ( gid : PyIntRef , vm : & VirtualMachine ) -> PyResult < ( ) > {
810+ let gid = gid. as_bigint ( ) . to_u32 ( ) . unwrap ( ) ;
811+
812+ unistd:: setgid ( Gid :: from_raw ( gid) ) . map_err ( |err| convert_nix_error ( vm, err) )
813+ }
814+
815+ #[ cfg( unix) ]
816+ fn os_setegid ( egid : PyIntRef , vm : & VirtualMachine ) -> PyResult < ( ) > {
817+ let egid = egid. as_bigint ( ) . to_u32 ( ) . unwrap ( ) ;
818+
819+ unistd:: setegid ( Gid :: from_raw ( egid) ) . map_err ( |err| convert_nix_error ( vm, err) )
820+ }
821+
822+ #[ cfg( unix) ]
823+ fn os_setpgid ( pid : PyIntRef , pgid : PyIntRef , vm : & VirtualMachine ) -> PyResult < ( ) > {
824+ let pid = pid. as_bigint ( ) . to_u32 ( ) . unwrap ( ) ;
825+ let pgid = pgid. as_bigint ( ) . to_u32 ( ) . unwrap ( ) ;
826+
827+ unistd:: setpgid ( Pid :: from_raw ( pid as i32 ) , Pid :: from_raw ( pgid as i32 ) )
828+ . map_err ( |err| convert_nix_error ( vm, err) )
829+ }
830+
831+ #[ cfg( unix) ]
832+ fn os_setsid ( vm : & VirtualMachine ) -> PyResult < ( ) > {
833+ unistd:: setsid ( )
834+ . map ( |_ok| ( ) )
835+ . map_err ( |err| convert_nix_error ( vm, err) )
836+ }
837+
838+ #[ cfg( unix) ]
839+ fn os_setuid ( uid : PyIntRef , vm : & VirtualMachine ) -> PyResult < ( ) > {
840+ let uid = uid. as_bigint ( ) . to_u32 ( ) . unwrap ( ) ;
841+
842+ unistd:: setuid ( Uid :: from_raw ( uid) ) . map_err ( |err| convert_nix_error ( vm, err) )
843+ }
844+
845+ #[ cfg( unix) ]
846+ fn os_seteuid ( euid : PyIntRef , vm : & VirtualMachine ) -> PyResult < ( ) > {
847+ let euid = euid. as_bigint ( ) . to_u32 ( ) . unwrap ( ) ;
848+
849+ unistd:: seteuid ( Uid :: from_raw ( euid) ) . map_err ( |err| convert_nix_error ( vm, err) )
850+ }
851+
712852pub fn make_module ( vm : & VirtualMachine ) -> PyObjectRef {
713853 let ctx = & vm. ctx ;
714854
@@ -832,6 +972,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
832972 "R_OK" => ctx. new_int( 4 ) ,
833973 "W_OK" => ctx. new_int( 2 ) ,
834974 "X_OK" => ctx. new_int( 1 ) ,
975+ "getpid" => ctx. new_rustfunc( os_getpid)
835976 } ) ;
836977
837978 for support in support_funcs {
@@ -863,5 +1004,33 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
8631004 "supports_follow_symlinks" => supports_follow_symlinks. into_object( ) ,
8641005 } ) ;
8651006
1007+ extend_module_platform_specific ( & vm, module)
1008+ }
1009+
1010+ #[ cfg( unix) ]
1011+ fn extend_module_platform_specific ( vm : & VirtualMachine , module : PyObjectRef ) -> PyObjectRef {
1012+ let ctx = & vm. ctx ;
1013+
1014+ extend_module ! ( vm, module, {
1015+ "getppid" => ctx. new_rustfunc( os_getppid) ,
1016+ "getgid" => ctx. new_rustfunc( os_getgid) ,
1017+ "getegid" => ctx. new_rustfunc( os_getegid) ,
1018+ "getpgid" => ctx. new_rustfunc( os_getpgid) ,
1019+ "getsid" => ctx. new_rustfunc( os_getsid) ,
1020+ "getuid" => ctx. new_rustfunc( os_getuid) ,
1021+ "geteuid" => ctx. new_rustfunc( os_geteuid) ,
1022+ "setgid" => ctx. new_rustfunc( os_setgid) ,
1023+ "setegid" => ctx. new_rustfunc( os_setegid) ,
1024+ "setpgid" => ctx. new_rustfunc( os_setpgid) ,
1025+ "setsid" => ctx. new_rustfunc( os_setsid) ,
1026+ "setuid" => ctx. new_rustfunc( os_setuid) ,
1027+ "seteuid" => ctx. new_rustfunc( os_seteuid) ,
1028+ } ) ;
1029+
1030+ module
1031+ }
1032+
1033+ #[ cfg( not( unix) ) ]
1034+ fn extend_module_platform_specific ( _vm : & VirtualMachine , module : PyObjectRef ) -> PyObjectRef {
8661035 module
8671036}
0 commit comments