Skip to content

Commit 98166d2

Browse files
committed
pipe/pid
1 parent db95946 commit 98166d2

File tree

1 file changed

+108
-0
lines changed
  • crates/vm/src/stdlib

1 file changed

+108
-0
lines changed

crates/vm/src/stdlib/nt.rs

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -835,6 +835,7 @@ pub(crate) mod module {
835835
fn _umask(mask: i32) -> i32;
836836
fn _dup(fd: i32) -> i32;
837837
fn _dup2(fd: i32, fd2: i32) -> i32;
838+
fn _open_osfhandle(osfhandle: intptr_t, flags: i32) -> i32;
838839
}
839840

840841
/// Close fd and convert error to PyException (PEP 446 cleanup)
@@ -854,6 +855,113 @@ pub(crate) mod module {
854855
}
855856
}
856857

858+
#[pyfunction]
859+
fn pipe(vm: &VirtualMachine) -> PyResult<(i32, i32)> {
860+
use windows_sys::Win32::System::Pipes::CreatePipe;
861+
862+
let (read_handle, write_handle) = unsafe {
863+
let mut read = MaybeUninit::<isize>::uninit();
864+
let mut write = MaybeUninit::<isize>::uninit();
865+
let res = CreatePipe(
866+
read.as_mut_ptr() as *mut _,
867+
write.as_mut_ptr() as *mut _,
868+
std::ptr::null(),
869+
0,
870+
);
871+
if res == 0 {
872+
return Err(errno_err(vm));
873+
}
874+
(read.assume_init(), write.assume_init())
875+
};
876+
877+
// Convert handles to file descriptors
878+
// O_NOINHERIT = 0x80 (MSVC CRT)
879+
const O_NOINHERIT: i32 = 0x80;
880+
let read_fd = unsafe { _open_osfhandle(read_handle, O_NOINHERIT) };
881+
let write_fd = unsafe { _open_osfhandle(write_handle, libc::O_WRONLY | O_NOINHERIT) };
882+
883+
if read_fd == -1 || write_fd == -1 {
884+
unsafe {
885+
Foundation::CloseHandle(read_handle as _);
886+
Foundation::CloseHandle(write_handle as _);
887+
}
888+
return Err(errno_err(vm));
889+
}
890+
891+
Ok((read_fd, write_fd))
892+
}
893+
894+
#[pyfunction]
895+
fn getppid() -> u32 {
896+
use windows_sys::Win32::System::Threading::GetCurrentProcess;
897+
898+
#[repr(C)]
899+
struct ProcessBasicInformation {
900+
exit_status: isize,
901+
peb_base_address: *mut std::ffi::c_void,
902+
affinity_mask: usize,
903+
base_priority: i32,
904+
unique_process_id: usize,
905+
inherited_from_unique_process_id: usize,
906+
}
907+
908+
type NtQueryInformationProcessFn = unsafe extern "system" fn(
909+
process_handle: isize,
910+
process_information_class: u32,
911+
process_information: *mut std::ffi::c_void,
912+
process_information_length: u32,
913+
return_length: *mut u32,
914+
) -> i32;
915+
916+
let ntdll = unsafe {
917+
windows_sys::Win32::System::LibraryLoader::GetModuleHandleW(windows_sys::w!(
918+
"ntdll.dll"
919+
))
920+
};
921+
if ntdll.is_null() {
922+
return 0;
923+
}
924+
925+
let func = unsafe {
926+
windows_sys::Win32::System::LibraryLoader::GetProcAddress(
927+
ntdll,
928+
c"NtQueryInformationProcess".as_ptr() as *const u8,
929+
)
930+
};
931+
let Some(func) = func else {
932+
return 0;
933+
};
934+
let nt_query: NtQueryInformationProcessFn = unsafe { std::mem::transmute(func) };
935+
936+
let mut info = ProcessBasicInformation {
937+
exit_status: 0,
938+
peb_base_address: std::ptr::null_mut(),
939+
affinity_mask: 0,
940+
base_priority: 0,
941+
unique_process_id: 0,
942+
inherited_from_unique_process_id: 0,
943+
};
944+
945+
let status = unsafe {
946+
nt_query(
947+
GetCurrentProcess() as isize,
948+
0, // ProcessBasicInformation
949+
&mut info as *mut _ as *mut std::ffi::c_void,
950+
std::mem::size_of::<ProcessBasicInformation>() as u32,
951+
std::ptr::null_mut(),
952+
)
953+
};
954+
955+
if status >= 0
956+
&& info.inherited_from_unique_process_id != 0
957+
&& info.inherited_from_unique_process_id < u32::MAX as usize
958+
{
959+
info.inherited_from_unique_process_id as u32
960+
} else {
961+
0
962+
}
963+
}
964+
857965
#[pyfunction]
858966
fn dup(fd: i32, vm: &VirtualMachine) -> PyResult<i32> {
859967
let fd2 = unsafe { suppress_iph!(_dup(fd)) };

0 commit comments

Comments
 (0)