@@ -850,8 +850,6 @@ pub(crate) mod module {
850850
851851 unsafe extern "C" {
852852 fn _umask ( mask : i32 ) -> i32 ;
853- fn _dup ( fd : i32 ) -> i32 ;
854- fn _dup2 ( fd : i32 , fd2 : i32 ) -> i32 ;
855853 }
856854
857855 /// Close fd and convert error to PyException (PEP 446 cleanup)
@@ -871,9 +869,116 @@ pub(crate) mod module {
871869 }
872870 }
873871
872+ #[ pyfunction]
873+ fn pipe ( vm : & VirtualMachine ) -> PyResult < ( i32 , i32 ) > {
874+ use windows_sys:: Win32 :: System :: Pipes :: CreatePipe ;
875+
876+ let ( read_handle, write_handle) = unsafe {
877+ let mut read = MaybeUninit :: < isize > :: uninit ( ) ;
878+ let mut write = MaybeUninit :: < isize > :: uninit ( ) ;
879+ let res = CreatePipe (
880+ read. as_mut_ptr ( ) as * mut _ ,
881+ write. as_mut_ptr ( ) as * mut _ ,
882+ std:: ptr:: null ( ) ,
883+ 0 ,
884+ ) ;
885+ if res == 0 {
886+ return Err ( errno_err ( vm) ) ;
887+ }
888+ ( read. assume_init ( ) , write. assume_init ( ) )
889+ } ;
890+
891+ // Convert handles to file descriptors
892+ // O_NOINHERIT = 0x80 (MSVC CRT)
893+ const O_NOINHERIT : i32 = 0x80 ;
894+ let read_fd = unsafe { libc:: open_osfhandle ( read_handle, O_NOINHERIT ) } ;
895+ let write_fd = unsafe { libc:: open_osfhandle ( write_handle, libc:: O_WRONLY | O_NOINHERIT ) } ;
896+
897+ if read_fd == -1 || write_fd == -1 {
898+ unsafe {
899+ Foundation :: CloseHandle ( read_handle as _ ) ;
900+ Foundation :: CloseHandle ( write_handle as _ ) ;
901+ }
902+ return Err ( errno_err ( vm) ) ;
903+ }
904+
905+ Ok ( ( read_fd, write_fd) )
906+ }
907+
908+ #[ pyfunction]
909+ fn getppid ( ) -> u32 {
910+ use windows_sys:: Win32 :: System :: Threading :: GetCurrentProcess ;
911+
912+ #[ repr( C ) ]
913+ struct ProcessBasicInformation {
914+ exit_status : isize ,
915+ peb_base_address : * mut std:: ffi:: c_void ,
916+ affinity_mask : usize ,
917+ base_priority : i32 ,
918+ unique_process_id : usize ,
919+ inherited_from_unique_process_id : usize ,
920+ }
921+
922+ type NtQueryInformationProcessFn = unsafe extern "system" fn (
923+ process_handle : isize ,
924+ process_information_class : u32 ,
925+ process_information : * mut std:: ffi:: c_void ,
926+ process_information_length : u32 ,
927+ return_length : * mut u32 ,
928+ ) -> i32 ;
929+
930+ let ntdll = unsafe {
931+ windows_sys:: Win32 :: System :: LibraryLoader :: GetModuleHandleW ( windows_sys:: w!(
932+ "ntdll.dll"
933+ ) )
934+ } ;
935+ if ntdll. is_null ( ) {
936+ return 0 ;
937+ }
938+
939+ let func = unsafe {
940+ windows_sys:: Win32 :: System :: LibraryLoader :: GetProcAddress (
941+ ntdll,
942+ c"NtQueryInformationProcess" . as_ptr ( ) as * const u8 ,
943+ )
944+ } ;
945+ let Some ( func) = func else {
946+ return 0 ;
947+ } ;
948+ let nt_query: NtQueryInformationProcessFn = unsafe { std:: mem:: transmute ( func) } ;
949+
950+ let mut info = ProcessBasicInformation {
951+ exit_status : 0 ,
952+ peb_base_address : std:: ptr:: null_mut ( ) ,
953+ affinity_mask : 0 ,
954+ base_priority : 0 ,
955+ unique_process_id : 0 ,
956+ inherited_from_unique_process_id : 0 ,
957+ } ;
958+
959+ let status = unsafe {
960+ nt_query (
961+ GetCurrentProcess ( ) as isize ,
962+ 0 , // ProcessBasicInformation
963+ & mut info as * mut _ as * mut std:: ffi:: c_void ,
964+ std:: mem:: size_of :: < ProcessBasicInformation > ( ) as u32 ,
965+ std:: ptr:: null_mut ( ) ,
966+ )
967+ } ;
968+
969+ if status >= 0
970+ && info. inherited_from_unique_process_id != 0
971+ && info. inherited_from_unique_process_id < u32:: MAX as usize
972+ {
973+ info. inherited_from_unique_process_id as u32
974+ } else {
975+ 0
976+ }
977+ }
978+
874979 #[ pyfunction]
875980 fn dup ( fd : i32 , vm : & VirtualMachine ) -> PyResult < i32 > {
876- let fd2 = unsafe { suppress_iph ! ( _dup ( fd) ) } ;
981+ let fd2 = unsafe { suppress_iph ! ( libc :: dup ( fd) ) } ;
877982 if fd2 < 0 {
878983 return Err ( errno_err ( vm) ) ;
879984 }
@@ -896,7 +1001,7 @@ pub(crate) mod module {
8961001
8971002 #[ pyfunction]
8981003 fn dup2 ( args : Dup2Args , vm : & VirtualMachine ) -> PyResult < i32 > {
899- let result = unsafe { suppress_iph ! ( _dup2 ( args. fd, args. fd2) ) } ;
1004+ let result = unsafe { suppress_iph ! ( libc :: dup2 ( args. fd, args. fd2) ) } ;
9001005 if result < 0 {
9011006 return Err ( errno_err ( vm) ) ;
9021007 }
0 commit comments