use crate::{fs::vfs, ipc::Message}; pub const OP_OPEN: u16 = 1; pub const OP_READ: u16 = 2; pub const OP_WRITE: u16 = 3; pub const OP_CLOSE: u16 = 4; pub const OP_OPENAT: u16 = 5; pub const OP_ACCESS: u16 = 6; pub const OP_FSTAT: u16 = 7; pub const OP_LSEEK: u16 = 8; pub const OP_DUP: u16 = 9; pub const OP_DUP_MIN: u16 = 10; pub const OP_DUP2: u16 = 11; pub const OP_GETCWD: u16 = 12; pub const OP_CHDIR: u16 = 13; pub const OP_MKDIR: u16 = 14; pub const OP_MKDIRAT: u16 = 15; pub const OP_TOUCH: u16 = 16; pub const OP_GETDENTS64: u16 = 17; pub const OP_STAT: u16 = 18; pub const OP_STATAT: u16 = 19; pub const OP_FTRUNCATE: u16 = 20; pub const OP_TRUNCATE: u16 = 21; pub fn dispatch(message: Message) -> isize { match message.opcode { OP_OPEN => vfs::open_user_path_with_flags(message.args[0] as *const u8, message.args[1]), OP_OPENAT => vfs::openat_user_path( message.args[0] as isize, message.args[1] as *const u8, message.args[2], ), OP_ACCESS => vfs::access_user_path(message.args[0] as *const u8), OP_READ => vfs::read(message.args[0], message.args[1] as *mut u8, message.args[2]), OP_WRITE => vfs::write( message.args[0], message.args[1] as *const u8, message.args[2], ), OP_CLOSE => vfs::close(message.args[0]), OP_FSTAT => vfs::fstat(message.args[0], message.args[1] as *mut u8), OP_LSEEK => vfs::lseek(message.args[0], message.args[1] as isize, message.args[2]), OP_DUP => vfs::dup(message.args[0]), OP_DUP_MIN => vfs::dup_min(message.args[0], message.args[1]), OP_DUP2 => vfs::dup2(message.args[0], message.args[1]), OP_GETCWD => vfs::getcwd(message.args[0] as *mut u8, message.args[1]), OP_CHDIR => vfs::chdir_user_path(message.args[0] as *const u8), OP_MKDIR => vfs::mkdir_user_path(message.args[0] as *const u8), OP_MKDIRAT => { vfs::mkdirat_user_path(message.args[0] as isize, message.args[1] as *const u8) } OP_TOUCH => vfs::touch_user_path(message.args[0] as isize, message.args[1] as *const u8), OP_GETDENTS64 => { vfs::getdents64(message.args[0], message.args[1] as *mut u8, message.args[2]) } OP_STAT => vfs::stat_user_path(message.args[0] as *const u8, message.args[1] as *mut u8), OP_STATAT => vfs::statat_user_path( message.args[0] as isize, message.args[1] as *const u8, message.args[2] as *mut u8, ), OP_FTRUNCATE => vfs::ftruncate(message.args[0], message.args[1]), OP_TRUNCATE => vfs::truncate_user_path(message.args[0] as *const u8, message.args[1]), _ => -38, } } pub const AT_FDCWD: isize = vfs::AT_FDCWD; pub unsafe fn init() { unsafe { vfs::init() } } pub fn open_user_path_with_flags(path: *const u8, flags: usize) -> isize { dispatch(message(OP_OPEN, [path as usize, flags, 0, 0, 0, 0])) } pub fn openat_user_path(dirfd: isize, path: *const u8, flags: usize) -> isize { dispatch(message( OP_OPENAT, [dirfd as usize, path as usize, flags, 0, 0, 0], )) } pub fn access_user_path(path: *const u8) -> isize { dispatch(message(OP_ACCESS, [path as usize, 0, 0, 0, 0, 0])) } pub fn is_tty(fd: usize) -> bool { vfs::is_tty(fd) } pub fn read(fd: usize, buffer: *mut u8, len: usize) -> isize { dispatch(message(OP_READ, [fd, buffer as usize, len, 0, 0, 0])) } pub fn write(fd: usize, buffer: *const u8, len: usize) -> isize { dispatch(message(OP_WRITE, [fd, buffer as usize, len, 0, 0, 0])) } pub fn poll(fd: usize, events: i16) -> Option { vfs::poll(fd, events) } pub fn close(fd: usize) -> isize { dispatch(message(OP_CLOSE, [fd, 0, 0, 0, 0, 0])) } pub fn fstat(fd: usize, stat: *mut u8) -> isize { dispatch(message(OP_FSTAT, [fd, stat as usize, 0, 0, 0, 0])) } pub fn ftruncate(fd: usize, size: usize) -> isize { dispatch(message(OP_FTRUNCATE, [fd, size, 0, 0, 0, 0])) } pub fn truncate_user_path(path: *const u8, size: usize) -> isize { dispatch(message(OP_TRUNCATE, [path as usize, size, 0, 0, 0, 0])) } pub fn lseek(fd: usize, offset: isize, whence: usize) -> isize { dispatch(message(OP_LSEEK, [fd, offset as usize, whence, 0, 0, 0])) } pub fn dup(fd: usize) -> isize { dispatch(message(OP_DUP, [fd, 0, 0, 0, 0, 0])) } pub fn dup_min(fd: usize, min_newfd: usize) -> isize { dispatch(message(OP_DUP_MIN, [fd, min_newfd, 0, 0, 0, 0])) } pub fn dup2(oldfd: usize, newfd: usize) -> isize { dispatch(message(OP_DUP2, [oldfd, newfd, 0, 0, 0, 0])) } pub fn exec_path_user(path: *const u8) -> Option<[u8; 256]> { vfs::exec_path_user(path) } pub fn getcwd(buffer: *mut u8, len: usize) -> isize { dispatch(message(OP_GETCWD, [buffer as usize, len, 0, 0, 0, 0])) } pub fn chdir_user_path(path: *const u8) -> isize { dispatch(message(OP_CHDIR, [path as usize, 0, 0, 0, 0, 0])) } pub fn mkdir_user_path(path: *const u8) -> isize { dispatch(message(OP_MKDIR, [path as usize, 0, 0, 0, 0, 0])) } pub fn mkdirat_user_path(dirfd: isize, path: *const u8) -> isize { dispatch(message( OP_MKDIRAT, [dirfd as usize, path as usize, 0, 0, 0, 0], )) } pub fn touch_user_path(dirfd: isize, path: *const u8) -> isize { dispatch(message( OP_TOUCH, [dirfd as usize, path as usize, 0, 0, 0, 0], )) } pub fn getdents64(fd: usize, buffer: *mut u8, len: usize) -> isize { dispatch(message(OP_GETDENTS64, [fd, buffer as usize, len, 0, 0, 0])) } pub fn stat_user_path(path: *const u8, stat: *mut u8) -> isize { dispatch(message(OP_STAT, [path as usize, stat as usize, 0, 0, 0, 0])) } pub fn statat_user_path(dirfd: isize, path: *const u8, stat: *mut u8) -> isize { dispatch(message( OP_STATAT, [dirfd as usize, path as usize, stat as usize, 0, 0, 0], )) } fn message(opcode: u16, args: [usize; 6]) -> Message { Message { sender: crate::task::current_pid(), opcode, args, } }