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);