From c241931303448f9449051ea2080c1b65561066f2 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 2 Aug 2026 09:39:04 +0900 Subject: feat(php-shim): implement syscall-backed functions via the nix crate Several shim functions were left as todo!() because the standard library exposes no equivalent and no syscall crate was available. Adding nix unblocks them: - proc_open now wires descriptors beyond stderr, creating the pipe itself and installing the child end with dup2(2) from pre_exec - proc_terminate and posix_kill deliver arbitrary signals via kill(2) - get_current_user reports the owner of the running executable - php_uname answers every mode from uname(2) instead of only "s" and "r" It also closes gaps that were previously approximated: - fstat stats the stdio streams and pipes rather than reporting failure - touch stamps mtime/atime on an existing path, including directories - is_writable/is_executable use access(2) instead of permission bits - umask falls back to the read-modify-write umask(2) off Linux The hand-written repr(C) structs and extern "C" declarations for getpwuid, utime, statvfs, fcntl and select are replaced by their nix wrappers, which in turn lets disk_free_space drop its Linux-only cfg. cli_set_process_title, setproctitle and the pcntl_signal pair stay as todo!(): the first two need access to the process's own argv block, and the latter two depend on the signal-handling subsystem rather than on sigaction(2) itself. Co-Authored-By: Claude Opus 5 (1M context) --- crates/shirabe-php-shim/src/runtime.rs | 44 ++++++++++++++++------------------ 1 file changed, 21 insertions(+), 23 deletions(-) (limited to 'crates/shirabe-php-shim/src/runtime.rs') diff --git a/crates/shirabe-php-shim/src/runtime.rs b/crates/shirabe-php-shim/src/runtime.rs index 00104051..71bb4530 100644 --- a/crates/shirabe-php-shim/src/runtime.rs +++ b/crates/shirabe-php-shim/src/runtime.rs @@ -293,31 +293,29 @@ pub fn spl_object_hash_process(_object: &T) -> String { format!("{:032x}", _object as *const T as usize) } +// TODO(phase-c): the Windows branch of php_uname is missing. There PHP reports "Windows NT" as the +// sysname and derives release/version from the OS version APIs rather than uname(2). pub fn php_uname(mode: &str) -> String { + let Ok(utsname) = nix::sys::utsname::uname() else { + return String::new(); + }; + let field = |value: &std::ffi::OsStr| value.to_string_lossy().into_owned(); match mode { - // sysname, as reported by uname(2). On Windows PHP returns "Windows NT", - // which differs from PHP_OS. - "s" => match std::env::consts::OS { - "linux" => "Linux", - "macos" => "Darwin", - "windows" => "Windows NT", - "freebsd" => "FreeBSD", - "netbsd" => "NetBSD", - "openbsd" => "OpenBSD", - "dragonfly" => "DragonFly", - "solaris" => "SunOS", - other => other, - } - .to_string(), - // TODO(phase-c): use libc? - // release, as reported by uname(2). On Linux this matches the contents - // of /proc/sys/kernel/osrelease. - "r" => std::fs::read_to_string("/proc/sys/kernel/osrelease") - .map(|s| s.trim_end().to_string()) - .unwrap_or_default(), - // TODO(phase-d): the remaining php_uname() modes ("n", "v", "m", "a") need uname(2) fields - // (nodename/version/machine) that are not reachable without a libc/syscall crate. - _ => todo!(), + "s" => field(utsname.sysname()), + "n" => field(utsname.nodename()), + "r" => field(utsname.release()), + "v" => field(utsname.version()), + "m" => field(utsname.machine()), + // "a" is the default and any other mode falls back to it: every field in the order + // sysname, nodename, release, version, machine. + _ => format!( + "{} {} {} {} {}", + field(utsname.sysname()), + field(utsname.nodename()), + field(utsname.release()), + field(utsname.version()), + field(utsname.machine()), + ), } } -- cgit v1.3.1