feature: simple ls(1p)

This commit is contained in:
2021-11-23 17:55:58 +02:00
parent a7d89158cb
commit 564d10e1be
15 changed files with 380 additions and 82 deletions
+1
View File
@@ -12,6 +12,7 @@ pub enum SystemCall {
Ioctl = 6,
Select = 7,
Access = 8,
ReadDirectory = 9,
// Process manipulation
Fork = 32,
Clone = 33,
+16 -2
View File
@@ -4,7 +4,7 @@ use crate::{
ioctl::IoctlCmd,
proc::{ExitCode, Pid},
signal::{Signal, SignalDestination},
stat::{AccessMode, FdSet, FileDescriptor, FileMode, OpenFlags, Stat},
stat::{AccessMode, DirectoryEntry, FdSet, FileDescriptor, FileMode, OpenFlags, Stat},
};
use core::time::Duration;
@@ -366,6 +366,20 @@ pub fn sys_getpgid(pid: Pid) -> Result<Pid, Errno> {
#[inline(always)]
pub fn sys_setpgid(pid: Pid, pgid: Pid) -> Result<Pid, Errno> {
Errno::from_syscall(unsafe { syscall!(SystemCall::SetPgid, argn!(pid.value()), argn!(pgid.value())) }).map(|e| unsafe { Pid::from_raw(e as u32) })
Errno::from_syscall(unsafe {
syscall!(SystemCall::SetPgid, argn!(pid.value()), argn!(pgid.value()))
})
.map(|e| unsafe { Pid::from_raw(e as u32) })
}
#[inline(always)]
pub fn sys_readdir(fd: FileDescriptor, buf: &mut [DirectoryEntry]) -> Result<usize, Errno> {
Errno::from_syscall(unsafe {
syscall!(
SystemCall::ReadDirectory,
argn!(u32::from(fd)),
argp!(buf.as_mut_ptr()),
argn!(buf.len())
)
})
}
+83 -12
View File
@@ -1,5 +1,5 @@
use core::fmt;
use crate::error::Errno;
use core::fmt;
const AT_FDCWD: i32 = -2;
pub const AT_EMPTY_PATH: u32 = 1 << 16;
@@ -14,11 +14,16 @@ bitflags! {
const O_CREAT = 1 << 4;
const O_EXEC = 1 << 5;
const O_CLOEXEC = 1 << 6;
const O_DIRECTORY = 1 << 7;
}
}
bitflags! {
pub struct FileMode: u32 {
const FILE_TYPE = 0xF << 12;
const S_IFREG = 0x8 << 12;
const S_IFDIR = 0x4 << 12;
const USER_READ = 1 << 8;
const USER_WRITE = 1 << 7;
const USER_EXEC = 1 << 6;
@@ -42,26 +47,57 @@ bitflags! {
#[derive(Clone, Default)]
pub struct FdSet {
bits: [u64; 2]
bits: [u64; 2],
}
#[derive(Clone, Copy, Debug)]
#[repr(transparent)]
pub struct FileDescriptor(u32);
#[derive(Clone, Copy)]
pub struct DirectoryEntry {
name: [u8; 64],
}
struct FdSetIter<'a> {
idx: u32,
set: &'a FdSet
set: &'a FdSet,
}
#[derive(Clone, Copy, Debug, Default)]
#[repr(C)]
pub struct Stat {
pub mode: u32,
pub mode: FileMode,
pub size: u64,
pub blksize: u32,
}
impl DirectoryEntry {
pub const fn empty() -> Self {
Self { name: [0; 64] }
}
pub fn from_str(i: &str) -> DirectoryEntry {
let mut res = DirectoryEntry { name: [0; 64] };
let bytes = i.as_bytes();
res.name[..bytes.len()].copy_from_slice(bytes);
res
}
pub fn as_str(&self) -> &str {
let zero = self.name.iter().position(|&c| c == 0).unwrap();
core::str::from_utf8(&self.name[..zero]).unwrap()
}
}
impl fmt::Debug for DirectoryEntry {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("DirectoryEntry")
.field("name", &self.as_str())
.finish()
}
}
impl FdSet {
pub const fn empty() -> Self {
Self { bits: [0; 2] }
@@ -93,10 +129,7 @@ impl FdSet {
}
pub fn iter(&self) -> impl Iterator<Item = FileDescriptor> + '_ {
FdSetIter {
idx: 0,
set: self
}
FdSetIter { idx: 0, set: self }
}
}
@@ -131,13 +164,51 @@ impl fmt::Debug for FdSet {
impl FileMode {
/// Returns default permission set for directories
pub const fn default_dir() -> Self {
unsafe { Self::from_bits_unchecked(0o755) }
pub fn default_dir() -> Self {
unsafe { Self::from_bits_unchecked(0o755) | Self::S_IFDIR }
}
/// Returns default permission set for regular files
pub const fn default_reg() -> Self {
unsafe { Self::from_bits_unchecked(0o644) }
pub fn default_reg() -> Self {
unsafe { Self::from_bits_unchecked(0o644) | Self::S_IFREG }
}
}
fn choose<T>(q: bool, a: T, b: T) -> T {
if q { a } else { b }
}
impl Default for FileMode {
fn default() -> Self {
unsafe { Self::from_bits_unchecked(0) }
}
}
impl fmt::Display for FileMode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{}{}{}{}{}{}{}{}{}{}",
// File type
match *self & Self::FILE_TYPE {
Self::S_IFDIR => 'd',
Self::S_IFREG => '-',
_ => '?'
},
// User
choose(self.contains(Self::USER_READ), 'r', '-'),
choose(self.contains(Self::USER_WRITE), 'w', '-'),
choose(self.contains(Self::USER_EXEC), 'x', '-'),
// Group
choose(self.contains(Self::GROUP_READ), 'r', '-'),
choose(self.contains(Self::GROUP_WRITE), 'w', '-'),
choose(self.contains(Self::GROUP_EXEC), 'x', '-'),
// Other
choose(self.contains(Self::OTHER_READ), 'r', '-'),
choose(self.contains(Self::OTHER_WRITE), 'w', '-'),
choose(self.contains(Self::OTHER_EXEC), 'x', '-'),
);
Ok(())
}
}