fn mknod()

in src/nodes/dir.rs [639:682]


    fn mknod(&self, name: &OsStr, uid: unistd::Uid, gid: unistd::Gid, mode: u32, rdev: u32,
        ids: &IdGenerator, cache: &dyn Cache) -> NodeResult<(ArcNode, fuse::FileAttr)> {
        let mut state = self.state.lock().unwrap();
        let path = Dir::get_writable_path(&mut state, name)?;

        if mode > u32::from(std::u16::MAX) {
            warn!("mknod got too-big mode {} (exceeds {})", mode, std::u16::MAX);
        }
        let mode = mode as sys::stat::mode_t;

        // We have to break apart the incoming mode into a separate file type flag and a permissions
        // set... only to have mknod() combine them later once again.  Doesn't make a lot of sense
        // but that the API we get from nix, hence ensure we are doing the right thing.
        let (sflag, perm) = {
            let sflag = sys::stat::SFlag::from_bits_truncate(mode);
            let perm = sys::stat::Mode::from_bits_truncate(mode);

            let truncated_mode = sflag.bits() | perm.bits();
            if truncated_mode != mode {
                warn!("mknod cannot only handle {} from mode {}", truncated_mode, mode);
            }

            (sflag, perm)
        };

        let exp_filetype = match sflag {
            sys::stat::SFlag::S_IFBLK => fuse::FileType::BlockDevice,
            sys::stat::SFlag::S_IFCHR => fuse::FileType::CharDevice,
            sys::stat::SFlag::S_IFIFO => fuse::FileType::NamedPipe,
            sys::stat::SFlag::S_IFREG => fuse::FileType::RegularFile,
            _ => {
                warn!("mknod received request to create {} with type {:?}, which is not supported",
                    path.display(), sflag);
                return Err(KernelError::from_errno(errno::Errno::EIO));
            },
        };

        #[allow(clippy::cast_lossless)]
        create_as(
            &path, uid, gid,
            |p| sys::stat::mknod(p, sflag, perm, rdev as sys::stat::dev_t),
            |p| unistd::unlink(p))?;
        Dir::post_create_lookup(self.writable, &mut state, &path, name, exp_filetype, ids, cache)
    }