From c695605af4d8eb256dc03e1f26d06ac07d2d8c68 Mon Sep 17 00:00:00 2001 From: "Jeong, YunWon" Date: Mon, 21 Sep 2026 21:06:56 +0900 Subject: [PATCH 1/2] host_env: export ctypes, chflags, SIG_DFL Publish ctypes FUNCFLAG/TYPEFLAG/DICTFLAG and CTYPES_MAX_ARGCOUNT, BSD chflags bits libc does not bind, AT_FDCWD, and SIG_DFL/IGN/ERR. Assisted-by: Claude --- crates/host_env/src/ctypes.rs | 12 ++++++++++++ crates/host_env/src/os.rs | 25 +++++++++++++++++++++++++ crates/host_env/src/signal.rs | 10 ++++++++++ 3 files changed, 47 insertions(+) diff --git a/crates/host_env/src/ctypes.rs b/crates/host_env/src/ctypes.rs index db30a22abe4..4f3799a6133 100644 --- a/crates/host_env/src/ctypes.rs +++ b/crates/host_env/src/ctypes.rs @@ -372,6 +372,18 @@ pub const RTLD_LOCAL: i32 = 0; pub const RTLD_GLOBAL: i32 = 0; pub const SIZEOF_TIME_T: usize = core::mem::size_of::(); +/// `_ctypes` call flags (`_flags_` on a function pointer). +pub const FUNCFLAG_STDCALL: u32 = 0x0; +pub const FUNCFLAG_CDECL: u32 = 0x1; +pub const FUNCFLAG_HRESULT: u32 = 0x2; +pub const FUNCFLAG_PYTHONAPI: u32 = 0x4; +pub const FUNCFLAG_USE_ERRNO: u32 = 0x8; +pub const FUNCFLAG_USE_LASTERROR: u32 = 0x10; +pub const TYPEFLAG_ISPOINTER: u32 = 0x100; +pub const TYPEFLAG_HASPOINTER: u32 = 0x200; +pub const DICTFLAG_FINAL: u32 = 0x1000; +pub const CTYPES_MAX_ARGCOUNT: usize = 1024; + #[cfg(all(unix, not(target_os = "wasi")))] pub fn dlopen_mode(load_flags: Option) -> i32 { load_flags.unwrap_or(libc::RTLD_NOW | libc::RTLD_LOCAL) | libc::RTLD_NOW diff --git a/crates/host_env/src/os.rs b/crates/host_env/src/os.rs index 58245c97710..cdfced96cad 100644 --- a/crates/host_env/src/os.rs +++ b/crates/host_env/src/os.rs @@ -35,6 +35,31 @@ pub const R_OK: u8 = 4; pub const W_OK: u8 = 2; pub const X_OK: u8 = 1; +#[cfg(any(unix, target_os = "wasi"))] +pub use libc::AT_FDCWD; +#[cfg(not(any(unix, target_os = "wasi")))] +pub const AT_FDCWD: i32 = -100; + +/// BSD `chflags` bits the `libc` crate does not bind. Published by `_stat` +/// on every platform. +pub const UF_SETTABLE: u32 = 0x0000ffff; +pub const UF_NOUNLINK: u32 = 0x00000010; +pub const UF_TRACKED: u32 = 0x00000040; +pub const UF_DATAVAULT: u32 = 0x00000080; +pub const SF_NOUNLINK: u32 = 0x00100000; +pub const SF_SNAPSHOT: u32 = 0x00200000; +pub const SF_FIRMLINK: u32 = 0x00800000; +pub const SF_DATALESS: u32 = 0x40000000; +pub const SF_SETTABLE: u32 = if cfg!(target_os = "macos") { + 0x3fff0000 +} else { + 0xffff0000 +}; +#[cfg(target_os = "macos")] +pub const SF_SUPPORTED: u32 = 0x009f0000; +#[cfg(target_os = "macos")] +pub const SF_SYNTHETIC: u32 = 0xc0000000; + #[cfg(not(any(unix, windows, target_os = "wasi")))] pub fn rename( from: impl AsRef, diff --git a/crates/host_env/src/signal.rs b/crates/host_env/src/signal.rs index dc6e93123e7..b1db3012ef1 100644 --- a/crates/host_env/src/signal.rs +++ b/crates/host_env/src/signal.rs @@ -10,6 +10,16 @@ use crate::os::CheckLibcZero; #[cfg(any(unix, windows))] pub use libc::sighandler_t; +#[cfg(unix)] +pub use libc::{SIG_DFL, SIG_ERR, SIG_IGN}; + +#[cfg(not(unix))] +pub const SIG_DFL: libc::sighandler_t = 0; +#[cfg(not(unix))] +pub const SIG_IGN: libc::sighandler_t = 1; +#[cfg(not(unix))] +pub const SIG_ERR: libc::sighandler_t = -1 as _; + #[cfg(all(unix, not(target_os = "android")))] pub use libc::{ITIMER_PROF, ITIMER_REAL, ITIMER_VIRTUAL}; From b91bffcec80185b47c2bb023d7b067767f8485aa Mon Sep 17 00:00:00 2001 From: "Jeong, YunWon" Date: Mon, 21 Sep 2026 21:06:58 +0900 Subject: [PATCH 2/2] stdlib: take ctypes, chflags, SIG_DFL from host_env _ctypes, _stat, os.AT_FDCWD, and Windows SIG_DFL/IGN/ERR now re-export the host_env names. Wasm keeps local SIG_* literals. Assisted-by: Claude --- crates/vm/src/stdlib/_ctypes.rs | 27 +++++------------------ crates/vm/src/stdlib/_signal.rs | 14 ++++++------ crates/vm/src/stdlib/_stat.rs | 39 ++++----------------------------- crates/vm/src/stdlib/os.rs | 9 +------- 4 files changed, 17 insertions(+), 72 deletions(-) diff --git a/crates/vm/src/stdlib/_ctypes.rs b/crates/vm/src/stdlib/_ctypes.rs index 0cab54e6e93..2cffd8c8a28 100644 --- a/crates/vm/src/stdlib/_ctypes.rs +++ b/crates/vm/src/stdlib/_ctypes.rs @@ -248,28 +248,11 @@ pub(crate) mod _ctypes { const SIZEOF_TIME_T: usize = rustpython_host_env::ctypes::SIZEOF_TIME_T; #[pyattr] - const CTYPES_MAX_ARGCOUNT: usize = 1024; - - #[pyattr] - const FUNCFLAG_STDCALL: u32 = 0x0; - #[pyattr] - const FUNCFLAG_CDECL: u32 = 0x1; - #[pyattr] - const FUNCFLAG_HRESULT: u32 = 0x2; - #[pyattr] - const FUNCFLAG_PYTHONAPI: u32 = 0x4; - #[pyattr] - const FUNCFLAG_USE_ERRNO: u32 = 0x8; - #[pyattr] - const FUNCFLAG_USE_LASTERROR: u32 = 0x10; - - #[pyattr] - const TYPEFLAG_ISPOINTER: u32 = 0x100; - #[pyattr] - const TYPEFLAG_HASPOINTER: u32 = 0x200; - - #[pyattr] - const DICTFLAG_FINAL: u32 = 0x1000; + use rustpython_host_env::ctypes::{ + CTYPES_MAX_ARGCOUNT, DICTFLAG_FINAL, FUNCFLAG_CDECL, FUNCFLAG_HRESULT, FUNCFLAG_PYTHONAPI, + FUNCFLAG_STDCALL, FUNCFLAG_USE_ERRNO, FUNCFLAG_USE_LASTERROR, TYPEFLAG_HASPOINTER, + TYPEFLAG_ISPOINTER, + }; #[pyattr(name = "ArgumentError", once)] fn argument_error(vm: &VirtualMachine) -> PyTypeRef { diff --git a/crates/vm/src/stdlib/_signal.rs b/crates/vm/src/stdlib/_signal.rs index 1a91df9bd80..e0a636c9464 100644 --- a/crates/vm/src/stdlib/_signal.rs +++ b/crates/vm/src/stdlib/_signal.rs @@ -73,28 +73,28 @@ pub(crate) mod _signal { } } - #[cfg(unix)] + #[cfg(any(unix, windows))] #[allow(unused_imports)] - pub use libc::SIG_ERR; + pub use host_signal::SIG_ERR; - #[cfg(unix)] + #[cfg(any(unix, windows))] #[pyattr] - pub use libc::{SIG_DFL, SIG_IGN}; + pub use host_signal::{SIG_DFL, SIG_IGN}; // pthread_sigmask 'how' constants #[cfg(unix)] #[pyattr] use libc::{SIG_BLOCK, SIG_SETMASK, SIG_UNBLOCK}; - #[cfg(not(unix))] + #[cfg(not(any(unix, windows)))] #[pyattr] pub const SIG_DFL: sighandler_t = 0; - #[cfg(not(unix))] + #[cfg(not(any(unix, windows)))] #[pyattr] pub const SIG_IGN: sighandler_t = 1; - #[cfg(not(unix))] + #[cfg(not(any(unix, windows)))] #[allow(dead_code)] pub const SIG_ERR: sighandler_t = -1 as _; diff --git a/crates/vm/src/stdlib/_stat.rs b/crates/vm/src/stdlib/_stat.rs index 0bc2c4dbd9a..f105aad947b 100644 --- a/crates/vm/src/stdlib/_stat.rs +++ b/crates/vm/src/stdlib/_stat.rs @@ -319,45 +319,14 @@ mod _stat { ); #[pyattr] - pub const SF_SETTABLE: u32 = if cfg!(target_os = "macos") { - 0x3fff0000 - } else { - 0xffff0000 + pub use rustpython_host_env::os::{ + SF_DATALESS, SF_FIRMLINK, SF_NOUNLINK, SF_SETTABLE, SF_SNAPSHOT, UF_DATAVAULT, UF_NOUNLINK, + UF_SETTABLE, UF_TRACKED, }; - #[pyattr] - pub const UF_SETTABLE: u32 = 0x0000ffff; - - #[pyattr] - pub const UF_NOUNLINK: u32 = 0x00000010; - - #[pyattr] - pub const UF_TRACKED: u32 = 0x00000040; - - #[pyattr] - pub const UF_DATAVAULT: u32 = 0x00000080; - - #[pyattr] - pub const SF_NOUNLINK: u32 = 0x00100000; - - #[pyattr] - pub const SF_SNAPSHOT: u32 = 0x00200000; - - #[pyattr] - pub const SF_FIRMLINK: u32 = 0x00800000; - - #[pyattr] - pub const SF_DATALESS: u32 = 0x40000000; - - // MacOS specific - - #[cfg(target_os = "macos")] - #[pyattr] - pub const SF_SUPPORTED: u32 = 0x009f0000; - #[cfg(target_os = "macos")] #[pyattr] - pub const SF_SYNTHETIC: u32 = 0xc0000000; + pub use rustpython_host_env::os::{SF_SUPPORTED, SF_SYNTHETIC}; // Stat result indices diff --git a/crates/vm/src/stdlib/os.rs b/crates/vm/src/stdlib/os.rs index 05c4a4b2f3e..00bf7b979af 100644 --- a/crates/vm/src/stdlib/os.rs +++ b/crates/vm/src/stdlib/os.rs @@ -30,14 +30,7 @@ pub struct TargetIsDirectory { pub(crate) target_is_directory: bool, } -cfg_select! { - any(unix, target_os = "wasi") => { - use libc::AT_FDCWD; - } - _ => { - const AT_FDCWD: i32 = -100; - } -} +use crate::host_env::os::AT_FDCWD; const DEFAULT_DIR_FD: crt_fd::Borrowed<'static> = unsafe { crt_fd::Borrowed::borrow_raw(AT_FDCWD) };