path_open_internal

Function path_open_internal 

Source
pub(crate) fn path_open_internal(
    env: &WasiEnv,
    dirfd: Fd,
    dirflags: LookupFlags,
    path: &str,
    o_flags: Oflags,
    fs_rights_base: Rights,
    fs_rights_inheriting: Rights,
    fs_flags: Fdflags,
    fd_flags: Fdflagsext,
    with_fd: Option<Fd>,
) -> Result<Result<Fd, Errno>, WasiError>
Expand description

Open or create a filesystem object in the WASIX POSIX guest namespace.

This function sits on top of WasiFs::get_inode_at_path(), so it must preserve that resolver’s guest-path contract: raw syscall paths are POSIX paths where / is the only separator, absolute paths start from VIRTUAL_ROOT_FD, and intermediate symlinks are always resolved. Host paths only enter after an inode has been resolved to a backing Kind::Dir or Kind::File.

dirflags control lookup, not file-open mode. In particular, __WASI_LOOKUP_SYMLINK_FOLLOW decides whether the final component may be followed if it is a symlink. This matches the usual openat/O_NOFOLLOW shape: a symlink in the middle of the path is still traversed, but a final symlink with lookup-follow disabled is not opened as a symlink object. WASIX has no “open the symlink itself as a file” mode here, so a terminal symlink with no follow returns Errno::Loop. With lookup-follow enabled, the symlink target is resolved and path_open_internal restarts against that target.

o_flags and fs_flags apply after lookup. They decide whether the target must already exist, whether a missing final component should be created, whether the opened object must be a directory, and whether the backing file should be truncated or appended. POSIX trailing-slash semantics still matter at this layer: opening file/ is Errno::Notdir, and creating new_file/ is rejected before the backing opener can normalize the slash away.

The create path resolves only the parent with the requested symlink policy, then appends the new final component under that resolved parent. That keeps creation through symlinked directories working while still letting the final component be genuinely new. If the backing filesystem reports AlreadyExists after the resolver reported Noent, this may indicate that a symlink escaped the sandbox, so the error is mapped to Errno::Perm.

File inodes are also the cache boundary for open handles. The resolver may materialize a Kind::File with no handle, and this function opens the backing file when a descriptor is requested. Regular file handles are shared per inode when possible, and reopened with stronger rights when a later open requires write/create/truncate access that the existing handle may not have.

The outer Result reports runtime faults such as memory or trap-style WASI errors. The inner Result<WasiFd, Errno> is the syscall result that should be returned to the guest.