/// Resolves a path for open.
///
/// If the final path component points to a symlink, the symlink is followed (as long as
/// the symlink traversal limit has not been reached).
///
/// If the final path component (after following any symlinks, if enabled) does not exist,
/// and `flags` contains `OpenFlags::CREAT`, a new node is created at the location of the
/// final path component.
Resolves a path for open.
If the final path component points to a symlink, the symlink is followed (as long as
the symlink traversal limit has not been reached).

If the final path component (after following any symlinks, if enabled) does not exist,
and `flags` contains `OpenFlags::CREAT`, a new node is created at the location of the
final path component.
Resolves a path for open . If the final path component points to a symlink the symlink is followed ( as long as the symlink traversal limit has not been reached ) . If the final path component ( after following any symlinks if enabled ) does not exist and ` flags ` contains ` OpenFlags :: CREAT ` a new node is created at the location of the final path component .
fn resolve_open_path(
        &self,
        context: &mut LookupContext,
        dir: NamespaceNode,
        path: &FsStr,
        mode: FileMode,
        flags: OpenFlags,
    ) -> Result<NamespaceNode, Errno> {
        let path = context.update_for_path(&path);
        let mut parent_content = context.with(SymlinkMode::Follow);
        let (parent, basename) = self.lookup_parent(&mut parent_content, dir.clone(), path)?;
        context.remaining_follows = parent_content.remaining_follows;
        let must_create = flags.contains(OpenFlags::CREAT) && flags.contains(OpenFlags::EXCL);
        let mut child_context = context.with(SymlinkMode::NoFollow);
        match parent.lookup_child(&mut child_context, self, basename) {
            Ok(name) => {
                if name.entry.node.info().mode.is_lnk() {
                    if context.symlink_mode == SymlinkMode::NoFollow
                        || context.remaining_follows == 0
                    {
                        if must_create {
                            // Since `must_create` is set, and a node was found, this returns EEXIST
                            // instead of ELOOP.
                            return error!(EEXIST);
                        }
                        // A symlink was found, but too many symlink traversals have been
                        // attempted.
                        return error!(ELOOP);
                    }
                    context.remaining_follows -= 1;
                    match name.entry.node.readlink(self)? {
                        SymlinkTarget::Path(path) => {
                            let dir = if path[0] == b'/' { self.fs.root.clone() } else { parent };
                            self.resolve_open_path(context, dir, &path, mode, flags)
                        }
                        SymlinkTarget::Node(node) => Ok(node),
                    }
                } else {
                    if must_create {
                        return error!(EEXIST);
                    }
                    Ok(name)
                }
            }
            Err(e) if e == errno!(ENOENT) && flags.contains(OpenFlags::CREAT) => {
                if context.must_be_directory {
                    return error!(EISDIR);
                }
                let access = self.fs.apply_umask(mode & FileMode::ALLOW_ALL);
                parent.create_node(&basename, FileMode::IFREG | access, DeviceType::NONE)
            }
            error => error,
        }
    }
fn resolve_open_path ( & self , context : & mut LookupContext , dir : NamespaceNode , path : & FsStr , mode : FileMode , flags : OpenFlags , ) -> Result < NamespaceNode , Errno > { let path = context . update_for_path ( & path ) ; let mut parent_content = context . with ( SymlinkMode :: Follow ) ; let ( parent , basename ) = self . lookup_parent ( & mut parent_content , dir . clone ( ) , path ) ? ; context . remaining_follows = parent_content . remaining_follows ; let must_create = flags . contains ( OpenFlags :: CREAT ) && flags . contains ( OpenFlags :: EXCL ) ; let mut child_context = context . with ( SymlinkMode :: NoFollow ) ; match parent . lookup_child ( & mut child_context , self , basename ) { Ok ( name ) => { if name . entry . node . info ( ) . mode . is_lnk ( ) { if context . symlink_mode == SymlinkMode :: NoFollow || context . remaining_follows == 0 { if must_create { // Since `must_create` is set, and a node was found, this returns EEXIST // instead of ELOOP. return error ! ( EEXIST ) ; } // A symlink was found, but too many symlink traversals have been // attempted. return error ! ( ELOOP ) ; } context . remaining_follows -= 1 ; match name . entry . node . readlink ( self ) ? { SymlinkTarget :: Path ( path ) => { let dir = if path [ 0 ] == b'/' { self . fs . root . clone ( ) } else { parent } ; self . resolve_open_path ( context , dir , & path , mode , flags ) } SymlinkTarget :: Node ( node ) => Ok ( node ) , } } else { if must_create { return error ! ( EEXIST ) ; } Ok ( name ) } } Err ( e ) if e == errno ! ( ENOENT ) && flags . contains ( OpenFlags :: CREAT ) => { if context . must_be_directory { return error ! ( EISDIR ) ; } let access = self . fs . apply_umask ( mode & FileMode :: ALLOW_ALL ) ; parent . create_node ( & basename , FileMode :: IFREG | access , DeviceType :: NONE ) } error => error , } }
Resolves a path for open.
Resolves a path for open .
&self
context
&mut LookupContext
dir
NamespaceNode
path
&FsStr
mode
FileMode
flags
OpenFlags