feature: add FileDescriptor type
This commit is contained in:
parent
0f48379e1a
commit
a695232926
@ -4,8 +4,8 @@ use crate::config::{ConfigKey, CONFIG};
|
||||
use crate::fs::{devfs, MemfsBlockAlloc};
|
||||
use crate::mem;
|
||||
use crate::proc::{elf, Process};
|
||||
use libsys::stat::{FileDescriptor, OpenFlags};
|
||||
use memfs::Ramfs;
|
||||
use libsys::stat::OpenFlags;
|
||||
use vfs::{Filesystem, Ioctx};
|
||||
|
||||
/// Kernel init process function
|
||||
@ -51,9 +51,9 @@ pub extern "C" fn init_fn(_arg: usize) -> ! {
|
||||
let stdout = tty_node.open(OpenFlags::O_WRONLY).unwrap();
|
||||
let stderr = stdout.clone();
|
||||
|
||||
io.set_file(0, stdin).unwrap();
|
||||
io.set_file(1, stdout).unwrap();
|
||||
io.set_file(2, stderr).unwrap();
|
||||
io.set_file(FileDescriptor::STDIN, stdin).unwrap();
|
||||
io.set_file(FileDescriptor::STDOUT, stdout).unwrap();
|
||||
io.set_file(FileDescriptor::STDERR, stderr).unwrap();
|
||||
}
|
||||
|
||||
drop(cfg);
|
||||
|
@ -1,12 +1,12 @@
|
||||
//! Process file descriptors and I/O context
|
||||
use alloc::collections::BTreeMap;
|
||||
use libsys::error::Errno;
|
||||
use libsys::{error::Errno, stat::FileDescriptor};
|
||||
use vfs::{FileRef, Ioctx};
|
||||
|
||||
/// Process I/O context. Contains file tables, root/cwd info etc.
|
||||
pub struct ProcessIo {
|
||||
ioctx: Option<Ioctx>,
|
||||
files: BTreeMap<usize, FileRef>,
|
||||
files: BTreeMap<u32, FileRef>,
|
||||
}
|
||||
|
||||
impl ProcessIo {
|
||||
@ -22,8 +22,8 @@ impl ProcessIo {
|
||||
}
|
||||
|
||||
/// Returns [File] struct referred to by file descriptor `idx`
|
||||
pub fn file(&mut self, idx: usize) -> Result<FileRef, Errno> {
|
||||
self.files.get(&idx).cloned().ok_or(Errno::InvalidFile)
|
||||
pub fn file(&mut self, fd: FileDescriptor) -> Result<FileRef, Errno> {
|
||||
self.files.get(&u32::from(fd)).cloned().ok_or(Errno::InvalidFile)
|
||||
}
|
||||
|
||||
/// Returns [Ioctx] structure reference of this I/O context
|
||||
@ -32,19 +32,19 @@ impl ProcessIo {
|
||||
}
|
||||
|
||||
/// Allocates a file descriptor and associates a [File] struct with it
|
||||
pub fn place_file(&mut self, file: FileRef) -> Result<usize, Errno> {
|
||||
pub fn place_file(&mut self, file: FileRef) -> Result<FileDescriptor, Errno> {
|
||||
for idx in 0..64 {
|
||||
if self.files.get(&idx).is_none() {
|
||||
self.files.insert(idx, file);
|
||||
return Ok(idx);
|
||||
return Ok(FileDescriptor::from(idx));
|
||||
}
|
||||
}
|
||||
Err(Errno::TooManyDescriptors)
|
||||
}
|
||||
|
||||
/// Performs [File] close and releases its associated file descriptor `idx`
|
||||
pub fn close_file(&mut self, idx: usize) -> Result<(), Errno> {
|
||||
let res = self.files.remove(&idx);
|
||||
pub fn close_file(&mut self, idx: FileDescriptor) -> Result<(), Errno> {
|
||||
let res = self.files.remove(&u32::from(idx));
|
||||
assert!(res.is_some());
|
||||
Ok(())
|
||||
}
|
||||
@ -59,7 +59,8 @@ impl ProcessIo {
|
||||
|
||||
/// Assigns a descriptor number to an open file. If the number is not available,
|
||||
/// returns [Errno::AlreadyExists].
|
||||
pub fn set_file(&mut self, idx: usize, file: FileRef) -> Result<(), Errno> {
|
||||
pub fn set_file(&mut self, idx: FileDescriptor, file: FileRef) -> Result<(), Errno> {
|
||||
let idx = u32::from(idx);
|
||||
if self.files.get(&idx).is_none() {
|
||||
self.files.insert(idx, file);
|
||||
Ok(())
|
||||
|
@ -9,7 +9,6 @@ use crate::proc::{wait::Wait, ProcessIo, PROCESSES, SCHED};
|
||||
use crate::sync::IrqSafeSpinLock;
|
||||
use alloc::rc::Rc;
|
||||
use core::cell::UnsafeCell;
|
||||
use core::fmt;
|
||||
use core::sync::atomic::{AtomicU32, Ordering};
|
||||
use libsys::{error::Errno, signal::Signal, proc::{ExitCode, Pid}};
|
||||
|
||||
|
@ -57,11 +57,10 @@ pub fn sleep(timeout: Duration, remaining: &mut Duration) -> Result<(), Errno> {
|
||||
|
||||
pub fn select(
|
||||
proc: ProcessRef,
|
||||
n: u32,
|
||||
mut rfds: Option<&mut FdSet>,
|
||||
mut wfds: Option<&mut FdSet>,
|
||||
timeout: Option<Duration>,
|
||||
) -> Result<u32, Errno> {
|
||||
) -> Result<usize, Errno> {
|
||||
// TODO support wfds
|
||||
if wfds.is_some() || rfds.is_none() {
|
||||
todo!();
|
||||
@ -77,7 +76,7 @@ pub fn select(
|
||||
loop {
|
||||
if let Some(read) = &read {
|
||||
for fd in read.iter() {
|
||||
let file = io.file(fd as usize)?;
|
||||
let file = io.file(fd)?;
|
||||
if file.borrow().is_ready(false)? {
|
||||
rfds.as_mut().unwrap().set(fd);
|
||||
return Ok(1);
|
||||
@ -86,7 +85,7 @@ pub fn select(
|
||||
}
|
||||
if let Some(write) = &write {
|
||||
for fd in write.iter() {
|
||||
let file = io.file(fd as usize)?;
|
||||
let file = io.file(fd)?;
|
||||
if file.borrow().is_ready(true)? {
|
||||
wfds.as_mut().unwrap().set(fd);
|
||||
return Ok(1);
|
||||
|
@ -3,7 +3,6 @@
|
||||
use crate::arch::platform::exception::ExceptionFrame;
|
||||
use crate::debug::Level;
|
||||
use crate::proc::{elf, wait, Process, ProcessIo};
|
||||
use core::cmp::Ordering;
|
||||
use core::mem::size_of;
|
||||
use core::ops::DerefMut;
|
||||
use core::time::Duration;
|
||||
@ -13,7 +12,7 @@ use libsys::{
|
||||
ioctl::IoctlCmd,
|
||||
proc::Pid,
|
||||
signal::{Signal, SignalDestination},
|
||||
stat::{FdSet, FileMode, OpenFlags, Stat, AT_EMPTY_PATH, AT_FDCWD},
|
||||
stat::{FdSet, FileDescriptor, FileMode, OpenFlags, Stat, AT_EMPTY_PATH},
|
||||
traits::{Read, Write},
|
||||
};
|
||||
use vfs::VnodeRef;
|
||||
@ -34,11 +33,11 @@ pub unsafe fn sys_fork(regs: &mut ExceptionFrame) -> Result<Pid, Errno> {
|
||||
|
||||
fn find_at_node<T: DerefMut<Target = ProcessIo>>(
|
||||
io: &mut T,
|
||||
at_fd: usize,
|
||||
at_fd: Option<FileDescriptor>,
|
||||
filename: &str,
|
||||
empty_path: bool,
|
||||
) -> Result<VnodeRef, Errno> {
|
||||
let at = if at_fd as i32 != AT_FDCWD {
|
||||
let at = if let Some(at_fd) = at_fd {
|
||||
io.file(at_fd)?.borrow().node()
|
||||
} else {
|
||||
None
|
||||
@ -62,7 +61,7 @@ pub fn syscall(num: usize, args: &[usize]) -> Result<usize, Errno> {
|
||||
|
||||
// I/O system calls
|
||||
abi::SYS_OPENAT => {
|
||||
let at_fd = args[0];
|
||||
let at_fd = FileDescriptor::from_i32(args[0] as i32)?;
|
||||
let path = validate_user_str(args[1], args[2])?;
|
||||
let mode = FileMode::from_bits(args[3] as u32).ok_or(Errno::InvalidArgument)?;
|
||||
let opts = OpenFlags::from_bits(args[4] as u32).ok_or(Errno::InvalidArgument)?;
|
||||
@ -70,31 +69,33 @@ pub fn syscall(num: usize, args: &[usize]) -> Result<usize, Errno> {
|
||||
let proc = Process::current();
|
||||
let mut io = proc.io.lock();
|
||||
|
||||
let at = if at_fd as i32 == AT_FDCWD {
|
||||
None
|
||||
let at = if let Some(fd) = at_fd {
|
||||
io.file(fd)?.borrow().node()
|
||||
} else {
|
||||
io.file(at_fd)?.borrow().node()
|
||||
None
|
||||
};
|
||||
|
||||
let file = io.ioctx().open(at, path, mode, opts)?;
|
||||
io.place_file(file)
|
||||
Ok(u32::from(io.place_file(file)?) as usize)
|
||||
}
|
||||
abi::SYS_READ => {
|
||||
let proc = Process::current();
|
||||
let fd = FileDescriptor::from(args[0] as u32);
|
||||
let mut io = proc.io.lock();
|
||||
let buf = validate_user_ptr(args[1], args[2])?;
|
||||
|
||||
io.file(args[0])?.borrow_mut().read(buf)
|
||||
io.file(fd)?.borrow_mut().read(buf)
|
||||
}
|
||||
abi::SYS_WRITE => {
|
||||
let proc = Process::current();
|
||||
let fd = FileDescriptor::from(args[0] as u32);
|
||||
let mut io = proc.io.lock();
|
||||
let buf = validate_user_ptr(args[1], args[2])?;
|
||||
|
||||
io.file(args[0])?.borrow_mut().write(buf)
|
||||
io.file(fd)?.borrow_mut().write(buf)
|
||||
}
|
||||
abi::SYS_FSTATAT => {
|
||||
let at_fd = args[0];
|
||||
let at_fd = FileDescriptor::from_i32(args[0] as i32)?;
|
||||
let filename = validate_user_str(args[1], args[2])?;
|
||||
let buf = validate_user_ptr_struct::<Stat>(args[3])?;
|
||||
let flags = args[4] as u32;
|
||||
@ -107,7 +108,7 @@ pub fn syscall(num: usize, args: &[usize]) -> Result<usize, Errno> {
|
||||
abi::SYS_CLOSE => {
|
||||
let proc = Process::current();
|
||||
let mut io = proc.io.lock();
|
||||
let fd = args[0];
|
||||
let fd = FileDescriptor::from(args[0] as u32);
|
||||
|
||||
io.close_file(fd)?;
|
||||
Ok(0)
|
||||
@ -140,7 +141,7 @@ pub fn syscall(num: usize, args: &[usize]) -> Result<usize, Errno> {
|
||||
}
|
||||
}
|
||||
abi::SYS_IOCTL => {
|
||||
let fd = args[0];
|
||||
let fd = FileDescriptor::from(args[0] as u32);
|
||||
let cmd = IoctlCmd::try_from(args[1] as u32)?;
|
||||
|
||||
let proc = Process::current();
|
||||
@ -197,18 +198,16 @@ pub fn syscall(num: usize, args: &[usize]) -> Result<usize, Errno> {
|
||||
}
|
||||
|
||||
abi::SYS_SELECT => {
|
||||
let n = args[0] as u32;
|
||||
let rfds = validate_user_ptr_struct_option::<FdSet>(args[1])?;
|
||||
let wfds = validate_user_ptr_struct_option::<FdSet>(args[2])?;
|
||||
let timeout = if args[3] == 0 {
|
||||
let rfds = validate_user_ptr_struct_option::<FdSet>(args[0])?;
|
||||
let wfds = validate_user_ptr_struct_option::<FdSet>(args[1])?;
|
||||
let timeout = if args[2] == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(Duration::from_nanos(args[3] as u64))
|
||||
Some(Duration::from_nanos(args[2] as u64))
|
||||
};
|
||||
|
||||
let proc = Process::current();
|
||||
let fd = wait::select(proc, n, rfds, wfds, timeout)?;
|
||||
Ok(fd as usize)
|
||||
wait::select(proc, rfds, wfds, timeout)
|
||||
}
|
||||
|
||||
_ => {
|
||||
|
@ -2,7 +2,7 @@ use crate::abi;
|
||||
use crate::{
|
||||
ioctl::IoctlCmd,
|
||||
signal::{Signal, SignalDestination},
|
||||
stat::{FdSet, FileMode, OpenFlags, Stat},
|
||||
stat::{FdSet, FileDescriptor, FileMode, OpenFlags, Stat},
|
||||
};
|
||||
|
||||
// TODO document the syscall ABI
|
||||
@ -80,8 +80,8 @@ pub unsafe fn sys_exit(status: i32) -> ! {
|
||||
///
|
||||
/// System call
|
||||
#[inline(always)]
|
||||
pub unsafe fn sys_close(fd: i32) -> i32 {
|
||||
syscall!(abi::SYS_CLOSE, argn!(fd)) as i32
|
||||
pub unsafe fn sys_close(fd: FileDescriptor) -> i32 {
|
||||
syscall!(abi::SYS_CLOSE, argn!(u32::from(fd))) as i32
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
@ -108,10 +108,15 @@ pub unsafe fn sys_ex_debug_trace(msg: &[u8]) -> usize {
|
||||
///
|
||||
/// System call
|
||||
#[inline(always)]
|
||||
pub unsafe fn sys_openat(at: i32, pathname: &str, mode: FileMode, flags: OpenFlags) -> i32 {
|
||||
pub unsafe fn sys_openat(
|
||||
at: Option<FileDescriptor>,
|
||||
pathname: &str,
|
||||
mode: FileMode,
|
||||
flags: OpenFlags,
|
||||
) -> i32 {
|
||||
syscall!(
|
||||
abi::SYS_OPENAT,
|
||||
argn!(at),
|
||||
argn!(FileDescriptor::into_i32(at)),
|
||||
argp!(pathname.as_ptr()),
|
||||
argn!(pathname.len()),
|
||||
argn!(mode.bits()),
|
||||
@ -123,10 +128,10 @@ pub unsafe fn sys_openat(at: i32, pathname: &str, mode: FileMode, flags: OpenFla
|
||||
///
|
||||
/// System call
|
||||
#[inline(always)]
|
||||
pub unsafe fn sys_read(fd: i32, data: &mut [u8]) -> isize {
|
||||
pub unsafe fn sys_read(fd: FileDescriptor, data: &mut [u8]) -> isize {
|
||||
syscall!(
|
||||
abi::SYS_READ,
|
||||
argn!(fd),
|
||||
argn!(u32::from(fd)),
|
||||
argp!(data.as_mut_ptr()),
|
||||
argn!(data.len())
|
||||
) as isize
|
||||
@ -136,10 +141,10 @@ pub unsafe fn sys_read(fd: i32, data: &mut [u8]) -> isize {
|
||||
///
|
||||
/// System call
|
||||
#[inline(always)]
|
||||
pub unsafe fn sys_write(fd: i32, data: &[u8]) -> isize {
|
||||
pub unsafe fn sys_write(fd: FileDescriptor, data: &[u8]) -> isize {
|
||||
syscall!(
|
||||
abi::SYS_WRITE,
|
||||
argn!(fd),
|
||||
argn!(u32::from(fd)),
|
||||
argp!(data.as_ptr()),
|
||||
argn!(data.len())
|
||||
) as isize
|
||||
@ -149,10 +154,15 @@ pub unsafe fn sys_write(fd: i32, data: &[u8]) -> isize {
|
||||
///
|
||||
/// System call
|
||||
#[inline(always)]
|
||||
pub unsafe fn sys_fstatat(at: i32, pathname: &str, statbuf: &mut Stat, flags: u32) -> i32 {
|
||||
pub unsafe fn sys_fstatat(
|
||||
at: Option<FileDescriptor>,
|
||||
pathname: &str,
|
||||
statbuf: &mut Stat,
|
||||
flags: u32,
|
||||
) -> i32 {
|
||||
syscall!(
|
||||
abi::SYS_FSTATAT,
|
||||
argn!(at),
|
||||
argn!(FileDescriptor::into_i32(at)),
|
||||
argp!(pathname.as_ptr()),
|
||||
argn!(pathname.len()),
|
||||
argp!(statbuf as *mut Stat),
|
||||
@ -192,10 +202,10 @@ pub unsafe fn sys_waitpid(pid: u32, status: &mut i32) -> i32 {
|
||||
///
|
||||
/// System call
|
||||
#[inline(always)]
|
||||
pub unsafe fn sys_ioctl(fd: u32, cmd: IoctlCmd, ptr: usize, len: usize) -> isize {
|
||||
pub unsafe fn sys_ioctl(fd: FileDescriptor, cmd: IoctlCmd, ptr: usize, len: usize) -> isize {
|
||||
syscall!(
|
||||
abi::SYS_IOCTL,
|
||||
argn!(fd),
|
||||
argn!(u32::from(fd)),
|
||||
argn!(cmd),
|
||||
argn!(ptr),
|
||||
argn!(len)
|
||||
@ -215,21 +225,27 @@ pub unsafe fn sys_ex_sigreturn() -> ! {
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn sys_ex_kill(pid: SignalDestination, signum: Signal) -> i32 {
|
||||
syscall!(abi::SYS_EX_KILL, argn!(isize::from(pid)), argn!(signum as u32)) as i32
|
||||
syscall!(
|
||||
abi::SYS_EX_KILL,
|
||||
argn!(isize::from(pid)),
|
||||
argn!(signum as u32)
|
||||
) as i32
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn sys_select(
|
||||
n: u32,
|
||||
read_fds: Option<&mut FdSet>,
|
||||
write_fds: Option<&mut FdSet>,
|
||||
timeout: u64,
|
||||
) -> i32 {
|
||||
syscall!(
|
||||
abi::SYS_SELECT,
|
||||
argn!(n),
|
||||
argp!(read_fds.map(|e| e as *mut _).unwrap_or(core::ptr::null_mut())),
|
||||
argp!(write_fds.map(|e| e as *mut _).unwrap_or(core::ptr::null_mut())),
|
||||
argp!(read_fds
|
||||
.map(|e| e as *mut _)
|
||||
.unwrap_or(core::ptr::null_mut())),
|
||||
argp!(write_fds
|
||||
.map(|e| e as *mut _)
|
||||
.unwrap_or(core::ptr::null_mut())),
|
||||
argn!(timeout)
|
||||
) as i32
|
||||
}
|
||||
|
@ -1,12 +1,9 @@
|
||||
use core::fmt;
|
||||
use crate::error::Errno;
|
||||
|
||||
pub const AT_FDCWD: i32 = -2;
|
||||
const AT_FDCWD: i32 = -2;
|
||||
pub const AT_EMPTY_PATH: u32 = 1 << 16;
|
||||
|
||||
pub const STDIN_FILENO: i32 = 0;
|
||||
pub const STDOUT_FILENO: i32 = 1;
|
||||
pub const STDERR_FILENO: i32 = 2;
|
||||
|
||||
bitflags! {
|
||||
pub struct OpenFlags: u32 {
|
||||
const O_RDONLY = 1;
|
||||
@ -39,6 +36,10 @@ pub struct FdSet {
|
||||
bits: [u64; 2]
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[repr(transparent)]
|
||||
pub struct FileDescriptor(u32);
|
||||
|
||||
struct FdSetIter<'a> {
|
||||
idx: u32,
|
||||
set: &'a FdSet
|
||||
@ -64,25 +65,25 @@ impl FdSet {
|
||||
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.bits.iter().find(|&&x| x != 0).is_some()
|
||||
self.bits.iter().any(|&x| x != 0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set(&mut self, fd: u32) {
|
||||
self.bits[(fd as usize) / 64] |= 1 << (fd % 64);
|
||||
pub fn set(&mut self, fd: FileDescriptor) {
|
||||
self.bits[(fd.0 as usize) / 64] |= 1 << (fd.0 % 64);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn clear(&mut self, fd: u32) {
|
||||
self.bits[(fd as usize) / 64] &= !(1 << (fd % 64));
|
||||
pub fn clear(&mut self, fd: FileDescriptor) {
|
||||
self.bits[(fd.0 as usize) / 64] &= !(1 << (fd.0 % 64));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_set(&self, fd: u32) -> bool {
|
||||
self.bits[(fd as usize) / 64] & (1 << (fd % 64)) != 0
|
||||
pub fn is_set(&self, fd: FileDescriptor) -> bool {
|
||||
self.bits[(fd.0 as usize) / 64] & (1 << (fd.0 % 64)) != 0
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item = u32> + '_ {
|
||||
pub fn iter(&self) -> impl Iterator<Item = FileDescriptor> + '_ {
|
||||
FdSetIter {
|
||||
idx: 0,
|
||||
set: self
|
||||
@ -91,14 +92,14 @@ impl FdSet {
|
||||
}
|
||||
|
||||
impl Iterator for FdSetIter<'_> {
|
||||
type Item = u32;
|
||||
type Item = FileDescriptor;
|
||||
|
||||
fn next(&mut self) -> Option<u32> {
|
||||
fn next(&mut self) -> Option<FileDescriptor> {
|
||||
while self.idx < 128 {
|
||||
if self.set.is_set(self.idx) {
|
||||
if self.set.is_set(FileDescriptor(self.idx)) {
|
||||
let res = self.idx;
|
||||
self.idx += 1;
|
||||
return Some(res);
|
||||
return Some(FileDescriptor::from(res));
|
||||
}
|
||||
self.idx += 1;
|
||||
}
|
||||
@ -109,13 +110,11 @@ impl Iterator for FdSetIter<'_> {
|
||||
impl fmt::Debug for FdSet {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "FdSet {{ ")?;
|
||||
let mut count = 0;
|
||||
for fd in self.iter() {
|
||||
for (count, fd) in self.iter().enumerate() {
|
||||
if count != 0 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
write!(f, "{}", fd)?;
|
||||
count += 1;
|
||||
write!(f, "{:?}", fd)?;
|
||||
}
|
||||
write!(f, " }}")
|
||||
}
|
||||
@ -132,3 +131,39 @@ impl FileMode {
|
||||
unsafe { Self::from_bits_unchecked(0o644) }
|
||||
}
|
||||
}
|
||||
|
||||
impl FileDescriptor {
|
||||
pub const STDIN: Self = Self(0);
|
||||
pub const STDOUT: Self = Self(1);
|
||||
pub const STDERR: Self = Self(2);
|
||||
|
||||
pub fn from_i32(u: i32) -> Result<Option<Self>, Errno> {
|
||||
if u >= 0 {
|
||||
Ok(Some(Self(u as u32)))
|
||||
} else if u == AT_FDCWD {
|
||||
Ok(None)
|
||||
} else {
|
||||
Err(Errno::InvalidArgument)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_i32(u: Option<Self>) -> i32 {
|
||||
if let Some(u) = u {
|
||||
u.0 as i32
|
||||
} else {
|
||||
AT_FDCWD
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u32> for FileDescriptor {
|
||||
fn from(u: u32) -> Self {
|
||||
Self(u)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FileDescriptor> for u32 {
|
||||
fn from(u: FileDescriptor) -> u32 {
|
||||
u.0
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use core::fmt;
|
||||
use libsys::{
|
||||
calls::{sys_fstatat, sys_write},
|
||||
stat::{Stat, AT_FDCWD},
|
||||
stat::{Stat, FileDescriptor},
|
||||
};
|
||||
|
||||
// TODO populate this type
|
||||
@ -9,7 +9,7 @@ pub struct Error;
|
||||
|
||||
pub fn stat(pathname: &str) -> Result<Stat, Error> {
|
||||
let mut buf = Stat::default();
|
||||
let res = unsafe { sys_fstatat(AT_FDCWD, pathname, &mut buf, 0) };
|
||||
let res = unsafe { sys_fstatat(None, pathname, &mut buf, 0) };
|
||||
if res != 0 {
|
||||
todo!();
|
||||
}
|
||||
@ -20,7 +20,7 @@ pub fn stat(pathname: &str) -> Result<Stat, Error> {
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! print {
|
||||
($($args:tt)+) => ($crate::io::_print($crate::sys::STDOUT_FILENO, format_args!($($args)+)))
|
||||
($($args:tt)+) => ($crate::io::_print($crate::sys::FileDescriptor::STDOUT, format_args!($($args)+)))
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
@ -30,7 +30,7 @@ macro_rules! println {
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! eprint {
|
||||
($($args:tt)+) => ($crate::io::_print($crate::sys::STDERR_FILENO, format_args!($($args)+)))
|
||||
($($args:tt)+) => ($crate::io::_print($crate::sys::FileDescriptor::STDERR, format_args!($($args)+)))
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
@ -53,7 +53,7 @@ impl fmt::Write for BufferWriter<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn _print(fd: i32, args: fmt::Arguments) {
|
||||
pub fn _print(fd: FileDescriptor, args: fmt::Arguments) {
|
||||
use core::fmt::Write;
|
||||
static mut BUFFER: [u8; 4096] = [0; 4096];
|
||||
let mut writer = BufferWriter {
|
||||
|
@ -10,7 +10,7 @@ pub mod sys {
|
||||
pub use libsys::signal::{Signal, SignalDestination};
|
||||
pub use libsys::termios;
|
||||
pub use libsys::calls::*;
|
||||
pub use libsys::stat::{self, STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO};
|
||||
pub use libsys::stat::{self, FileDescriptor};
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
|
@ -1,9 +1,9 @@
|
||||
use crate::sys;
|
||||
use core::fmt;
|
||||
use core::mem::{size_of, MaybeUninit};
|
||||
use libsys::{ioctl::IoctlCmd, termios::Termios};
|
||||
use libsys::{ioctl::IoctlCmd, stat::FileDescriptor, termios::Termios};
|
||||
|
||||
pub fn get_tty_attrs(fd: u32) -> Result<Termios, &'static str> {
|
||||
pub fn get_tty_attrs(fd: FileDescriptor) -> Result<Termios, &'static str> {
|
||||
let mut termios = MaybeUninit::<Termios>::uninit();
|
||||
let res = unsafe {
|
||||
sys::sys_ioctl(
|
||||
@ -19,7 +19,7 @@ pub fn get_tty_attrs(fd: u32) -> Result<Termios, &'static str> {
|
||||
Ok(unsafe { termios.assume_init() })
|
||||
}
|
||||
|
||||
pub fn set_tty_attrs(fd: u32, attrs: &Termios) -> Result<(), &'static str> {
|
||||
pub fn set_tty_attrs(fd: FileDescriptor, attrs: &Termios) -> Result<(), &'static str> {
|
||||
let res = unsafe {
|
||||
sys::sys_ioctl(
|
||||
fd,
|
||||
|
@ -4,22 +4,24 @@
|
||||
#[macro_use]
|
||||
extern crate libusr;
|
||||
|
||||
use libusr::sys::stat::{FdSet, FileDescriptor};
|
||||
use libusr::sys::{Signal, SignalDestination};
|
||||
use libusr::sys::stat::FdSet;
|
||||
|
||||
fn readline(fd: i32, buf: &mut [u8]) -> Result<&str, ()> {
|
||||
fn readline(fd: FileDescriptor, buf: &mut [u8]) -> Result<&str, ()> {
|
||||
// select() just for test
|
||||
loop {
|
||||
let mut rfds = FdSet::empty();
|
||||
rfds.set(fd as u32);
|
||||
let res = unsafe { libusr::sys::sys_select(fd as u32 + 1, Some(&mut rfds), None, 1_000_000_000) };
|
||||
rfds.set(fd);
|
||||
let res = unsafe {
|
||||
libusr::sys::sys_select(Some(&mut rfds), None, 1_000_000_000)
|
||||
};
|
||||
if res < 0 {
|
||||
return Err(());
|
||||
}
|
||||
if res == 0 {
|
||||
continue;
|
||||
}
|
||||
if !rfds.is_set(fd as u32) {
|
||||
if !rfds.is_set(fd) {
|
||||
panic!();
|
||||
}
|
||||
|
||||
@ -38,7 +40,7 @@ fn main() -> i32 {
|
||||
|
||||
loop {
|
||||
print!("> ");
|
||||
let line = readline(libusr::sys::STDIN_FILENO, &mut buf).unwrap();
|
||||
let line = readline(FileDescriptor::STDIN, &mut buf).unwrap();
|
||||
if line.is_empty() {
|
||||
break;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user