aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe-php-shim/src/stream.rs
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-08-09 18:33:14 +0900
committernsfisis <nsfisis@gmail.com>2026-08-09 18:33:14 +0900
commit72cbecaec29cecc723ce29c87d10048114aeef5b (patch)
tree99ee7288595afbf1166503d603d7c5a7d08aaae0 /crates/shirabe-php-shim/src/stream.rs
parentf1215ade6e1d6e91a36c8b1c407f5a59a1c2ee0e (diff)
downloadphp-shirabe-72cbecaec29cecc723ce29c87d10048114aeef5b.tar.gz
php-shirabe-72cbecaec29cecc723ce29c87d10048114aeef5b.tar.zst
php-shirabe-72cbecaec29cecc723ce29c87d10048114aeef5b.zip
feat(symfony-filesystem): finish the Filesystem port and trim its API
doRemove() renames a directory to a random hidden name before emptying it, and undoes that rename when the final rmdir fails, so a concurrent process cannot recreate the path mid-removal. It also walks one level at a time through FilesystemIterator instead of flattening the whole tree, and lets an inner rmdir failure pass, both as upstream does. copy() keeps the mode fopen($targetFile, 'w') would have left rather than the origin's, symlink() and mirror() call readlink() and getLinkTarget() where upstream does, and a directory iterator that cannot be opened propagates its UnexpectedValueException instead of being swallowed or flattened into an IOException. Error message text is out of scope per docs/known-incompatibilities.md, so the three TODO(phase-c) markers that only tracked wording are gone, along with linkException()'s Windows-only branch. So are the arguments no caller varies -- symlink()'s copyOnWindows, mirror()'s iterator and options, copy()'s overwriteNewerFiles -- which removes the last TODO(phase-c) in the file. New shim functions: readlink, filesystem_iterator, stream_is_local, strrev and SplFileInfo::getLinkTarget. base64_encode takes bytes so random_bytes() can feed it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe-php-shim/src/stream.rs')
-rw-r--r--crates/shirabe-php-shim/src/stream.rs12
1 files changed, 12 insertions, 0 deletions
diff --git a/crates/shirabe-php-shim/src/stream.rs b/crates/shirabe-php-shim/src/stream.rs
index daf4c0af..b699b0ae 100644
--- a/crates/shirabe-php-shim/src/stream.rs
+++ b/crates/shirabe-php-shim/src/stream.rs
@@ -85,6 +85,18 @@ pub fn stream_isatty(stream: PhpResource) -> bool {
stream_isatty_resource(&stream)
}
+/// PHP `stream_is_local()`: true for plain paths and the `file://` wrapper, false for remote
+/// wrappers (`http://`, `ftp://`, ...).
+/// TODO(phase-c): PHP asks the wrapper registered for the path's scheme whether it is flagged
+/// `STREAM_IS_URL`; this classifies by the scheme itself, so a registered custom wrapper claiming to
+/// be local (or vice versa) comes out differently than in PHP.
+pub fn stream_is_local(path: &str) -> bool {
+ match crate::parse_url(path, crate::PHP_URL_SCHEME) {
+ PhpMixed::String(scheme) => scheme.eq_ignore_ascii_case("file"),
+ _ => true,
+ }
+}
+
pub fn stream_get_wrappers() -> Vec<String> {
// The full registered set depends on compiled-in extensions and runtime
// `stream_wrapper_register` calls, which are not modeled. We return the wrappers always