From d2a28f8c07b0aa713be338005c6153011d70f24b Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 9 Aug 2026 09:25:37 +0900 Subject: feat(symfony-filesystem): append the failure reason to IOExceptions Symfony wraps its native filesystem calls in box(), which captures the warning text of a failed call into self::$lastError and appends it to the IOException message. The port dropped that text because the shim's mkdir, rmdir, unlink and symlink only return PHP's bare false. Give each of those a Result-returning variant carrying the io::Error, and use it to restore the appended reason. That also makes two conditions portable: doRemove()'s "Permission denied" test, and linkException()'s Windows error code 1314 special case. Co-Authored-By: Claude Opus 5 (1M context) --- crates/shirabe-php-shim/src/fs.rs | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) (limited to 'crates/shirabe-php-shim') diff --git a/crates/shirabe-php-shim/src/fs.rs b/crates/shirabe-php-shim/src/fs.rs index b4010bb0..eae41dda 100644 --- a/crates/shirabe-php-shim/src/fs.rs +++ b/crates/shirabe-php-shim/src/fs.rs @@ -835,7 +835,11 @@ pub fn filemtime(_filename: impl AsRef) -> Option { } pub fn unlink(path: impl AsRef) -> bool { - std::fs::remove_file(path).is_ok() + unlink_result(path).is_ok() +} + +pub fn unlink_result(path: impl AsRef) -> Result<(), std::io::Error> { + std::fs::remove_file(path) } pub fn unlink_silent(_path: impl AsRef) -> bool { @@ -965,15 +969,27 @@ pub fn umask() -> u32 { } pub fn mkdir(_pathname: impl AsRef, _mode: u32, _recursive: bool) -> bool { + mkdir_result(_pathname, _mode, _recursive).is_ok() +} + +pub fn mkdir_result( + pathname: impl AsRef, + mode: u32, + recursive: bool, +) -> Result<(), std::io::Error> { use std::os::unix::fs::DirBuilderExt; // DirBuilder::mode passes the mode to mkdir(2), which applies the process umask, matching PHP. let mut builder = std::fs::DirBuilder::new(); - builder.mode(_mode).recursive(_recursive); - builder.create(_pathname.as_ref()).is_ok() + builder.mode(mode).recursive(recursive); + builder.create(pathname.as_ref()) } pub fn rmdir(dir: impl AsRef) -> bool { - std::fs::remove_dir(dir).is_ok() + rmdir_result(dir).is_ok() +} + +pub fn rmdir_result(dir: impl AsRef) -> Result<(), std::io::Error> { + std::fs::remove_dir(dir) } pub fn rename( @@ -1014,7 +1030,14 @@ pub fn ftruncate(stream: &PhpResource, size: i64) -> bool { } pub fn symlink(_target: impl AsRef, _link: impl AsRef) -> bool { - std::os::unix::fs::symlink(_target.as_ref(), _link.as_ref()).is_ok() + symlink_result(_target, _link).is_ok() +} + +pub fn symlink_result( + target: impl AsRef, + link: impl AsRef, +) -> Result<(), std::io::Error> { + std::os::unix::fs::symlink(target.as_ref(), link.as_ref()) } pub fn sys_get_temp_dir() -> String { -- cgit v1.3.1-4-g156e