From b4f74e24d99cd02cd4f0d2ab109b85219c04fa9c Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Thu, 17 Apr 2025 15:26:47 +0000 Subject: [PATCH] [wasm] Fallback to emulated realpath on wasi-libc realpath `ENOTSUP` wasi-libc 22 and later support realpath(3) (https://github.com/WebAssembly/wasi-libc/pull/463) but the underlying host syscall may return ENOTSUP. This is typically the case when using incomplete WASI polyfills on web browsers. For such cases, we should fallback to the emulated realpath. --- file.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/file.c b/file.c index 3c71f3303d..0ba6622479 100644 --- a/file.c +++ b/file.c @@ -4574,12 +4574,16 @@ rb_check_realpath_internal(VALUE basedir, VALUE path, rb_encoding *origenc, enum if (origenc) unresolved_path = TO_OSPATH(unresolved_path); if ((resolved_ptr = realpath(RSTRING_PTR(unresolved_path), resolved_buffer)) == NULL) { - /* glibc realpath(3) does not allow /path/to/file.rb/../other_file.rb, + /* + wasi-libc 22 and later support realpath(3) but return ENOTSUP + when the underlying host syscall returns it. + glibc realpath(3) does not allow /path/to/file.rb/../other_file.rb, returning ENOTDIR in that case. glibc realpath(3) can also return ENOENT for paths that exist, such as /dev/fd/5. Fallback to the emulated approach in either of those cases. */ - if (errno == ENOTDIR || + if (errno == ENOTSUP || + errno == ENOTDIR || (errno == ENOENT && rb_file_exist_p(0, unresolved_path))) { return rb_check_realpath_emulate(basedir, path, origenc, mode);