use core::ffi::{c_char, c_int}; use yggdrasil_rt::io::{FileAttr, FileMode, FileType}; use crate::{ error::CIntZeroResult, util::{self, PointerStrExt}, }; use super::{ fcntl::{AT_FDCWD, AT_SYMLINK_NOFOLLOW}, sys_time::__ygg_timespec_t, sys_types::{blkcnt_t, blksize_t, dev_t, gid_t, ino_t, mode_t, nlink_t, off_t, uid_t}, }; #[derive(Clone, Copy, PartialEq, Eq, Debug, Default)] #[repr(C)] pub struct stat { pub st_dev: dev_t, pub st_ino: ino_t, pub st_mode: mode_t, pub st_nlink: nlink_t, pub st_uid: uid_t, pub st_gid: gid_t, pub st_rdev: dev_t, pub st_size: off_t, pub st_atim: __ygg_timespec_t, pub st_mtim: __ygg_timespec_t, pub st_ctim: __ygg_timespec_t, pub st_blksize: blksize_t, pub st_blocks: blkcnt_t, } pub const S_IFMT: c_int = 0xF << 16; pub const S_IFBLK: c_int = 1 << 16; pub const S_IFCHR: c_int = 2 << 16; pub const S_IFIFO: c_int = 3 << 16; pub const S_IFREG: c_int = 4 << 16; pub const S_IFDIR: c_int = 5 << 16; pub const S_IFLNK: c_int = 6 << 16; pub const S_IFSOCK: c_int = 7 << 16; pub const S_IRWXU: c_int = 0x7 << 6; pub const S_IRUSR: c_int = 0x4 << 6; pub const S_IWUSR: c_int = 0x2 << 6; pub const S_IXUSR: c_int = 0x1 << 6; pub const S_IRWXG: c_int = 0x7 << 3; pub const S_IRGRP: c_int = 0x4 << 3; pub const S_IWGRP: c_int = 0x2 << 3; pub const S_IXGRP: c_int = 0x1 << 3; pub const S_IRWXO: c_int = 0x7 << 0; pub const S_IROTH: c_int = 0x4 << 0; pub const S_IWOTH: c_int = 0x2 << 0; pub const S_IXOTH: c_int = 0x1 << 0; pub const S_ISUID: c_int = 1 << 11; pub const S_ISGID: c_int = 1 << 10; pub const S_ISVTX: c_int = 1 << 9; impl From for stat { fn from(value: FileAttr) -> Self { // TODO no translation for st_dev/st_rdev/st_ino/etc let mut st = Self::default(); st.st_mode = (value.mode.bits() & 0o777) as _; match value.ty { FileType::Block => st.st_mode |= S_IFBLK, FileType::Char => st.st_mode |= S_IFCHR, FileType::File => st.st_mode |= S_IFREG, FileType::Directory => st.st_mode |= S_IFDIR, FileType::Symlink => st.st_mode |= S_IFLNK, } st.st_size = value.size.try_into().unwrap(); // TODO st.st_uid = u32::from(value.uid).try_into().unwrap(); st.st_gid = u32::from(value.gid).try_into().unwrap(); // TODO st.st_blksize = 512; st.st_blocks = (st.st_size + 511) / 512; // TODO st.st_nlink = 1; st } } #[no_mangle] unsafe extern "C" fn chmod(_pathname: *const c_char, _mode: mode_t) -> c_int { todo!() } #[no_mangle] unsafe extern "C" fn fchmod(_fd: c_int, _mode: mode_t) -> c_int { todo!() } #[no_mangle] unsafe extern "C" fn fchmodat( _fd: c_int, _pathname: *const c_char, _mode: mode_t, _opt: c_int, ) -> c_int { todo!() } #[no_mangle] unsafe extern "C" fn umask(_mode: mode_t) -> mode_t { todo!() // let new = FileMode::new((mode as u32) & 0o777); // let old = process::update_umask(new); // old.bits() as mode_t } // Create stuff #[no_mangle] unsafe extern "C" fn mkdir(pathname: *const c_char, mode: mode_t) -> CIntZeroResult { mkdirat(AT_FDCWD, pathname, mode) } #[no_mangle] unsafe extern "C" fn mkdirat(atfd: c_int, pathname: *const c_char, mode: mode_t) -> CIntZeroResult { let _pathname = pathname.ensure_str(); let _atfd = util::at_fd(atfd)?; let _mode = FileMode::new((mode & 0o777) as u32); todo!() // io::create_directory(atfd, pathname, mode)?; // CIntZeroResult::OK } #[no_mangle] unsafe extern "C" fn mkfifo(_pathname: *const c_char, _mode: mode_t) -> c_int { unimplemented!() } #[no_mangle] unsafe extern "C" fn mkfifoat(_atfd: c_int, _pathname: *const c_char, _mode: mode_t) -> c_int { unimplemented!() } #[no_mangle] unsafe extern "C" fn mknod(_pathname: *const c_char, _mode: mode_t, _dev: dev_t) -> c_int { unimplemented!() } #[no_mangle] unsafe extern "C" fn mknodat( _atfd: c_int, _pathname: *const c_char, _mode: mode_t, _dev: dev_t, ) -> c_int { unimplemented!() } // File status #[no_mangle] unsafe extern "C" fn fstat(_fd: c_int, _statbuf: *mut stat) -> CIntZeroResult { todo!() // let fd = RawFd::e_try_from(fd)?; // let attr = io::get_metadata(Some(fd), "", false)?; // if let Some(statbuf) = statbuf.as_mut() { // *statbuf = attr.into(); // } // CIntZeroResult::OK } #[no_mangle] unsafe extern "C" fn fstatat( atfd: c_int, pathname: *const c_char, _statbuf: *mut stat, opt: c_int, ) -> CIntZeroResult { let _pathname = pathname.ensure_str(); let _atfd = util::at_fd(atfd)?; let _follow = opt & AT_SYMLINK_NOFOLLOW == 0; todo!() // let attr = io::get_metadata(atfd, pathname, follow)?; // if let Some(statbuf) = statbuf.as_mut() { // *statbuf = attr.into(); // } // CIntZeroResult::OK } #[no_mangle] unsafe extern "C" fn lstat(pathname: *const c_char, statbuf: *mut stat) -> CIntZeroResult { fstatat(AT_FDCWD, pathname, statbuf, AT_SYMLINK_NOFOLLOW) } #[no_mangle] unsafe extern "C" fn stat(pathname: *const c_char, statbuf: *mut stat) -> CIntZeroResult { fstatat(AT_FDCWD, pathname, statbuf, 0) } // File time updates #[no_mangle] unsafe extern "C" fn futimens(_fd: c_int, _times: *const __ygg_timespec_t) -> c_int { todo!() } #[no_mangle] unsafe extern "C" fn utimensat( _atfd: c_int, _pathname: *const c_char, _times: *const __ygg_timespec_t, _opt: c_int, ) -> c_int { todo!() }