diff --git a/redox-rt/src/sys.rs b/redox-rt/src/sys.rs index f54fba8f86..249f45bcf5 100644 --- a/redox-rt/src/sys.rs +++ b/redox-rt/src/sys.rs @@ -589,32 +589,20 @@ pub fn getns() -> Result { pub fn open>(path: T, flags: usize) -> Result { let _siglock = tmp_disable_signals(); - let fcntl_flags = flags & syscall::O_FCNTL_MASK; - let redox_path = RedoxPath::from_absolute(path.as_ref()).ok_or(Error::new(EINVAL))?; - let (_, reference) = redox_path.as_parts().ok_or(Error::new(EINVAL))?; let ns_fd = crate::current_namespace_fd()?; - // Open the scheme root using raw SYS_OPENAT (auto-assigned POSIX fd). - // This bypasses FILETABLE.insert_upper, which could collide with the - // namespace fd (ns_fd) that is not always tracked in the UPPER table. - let root_fd = syscall::openat( + // Single SYS_OPENAT call: the kernel resolves the full path through the + // namespace scheme, which handles OtherScheme redirection internally. + // The previous two-step approach (open scheme root, then open reference) + // failed when the namespace returned OtherScheme, because the target + // scheme did not implement kopenat for the reference path. + let posix_fd = syscall::openat( ns_fd, path.as_ref(), - syscall::O_DIRECTORY | O_CLOEXEC, + flags, 0, )?; - register_external_fd(root_fd)?; - - let posix_fd = syscall::openat( - root_fd, - reference.as_ref(), - flags, - fcntl_flags, - )?; - - // Close root_fd and remove from FILETABLE, then register posix_fd. - close(root_fd)?; register_external_fd(posix_fd)?; Ok(posix_fd)