Add sys scheme to allow inspection of processes. WIP: Signals.
This commit is contained in:
parent
224c43f761
commit
d18bf07f3e
3
Makefile
3
Makefile
|
@ -267,6 +267,7 @@ coreutils: \
|
|||
filesystem/bin/mkdir \
|
||||
filesystem/bin/mv \
|
||||
filesystem/bin/printenv \
|
||||
filesystem/bin/ps \
|
||||
filesystem/bin/pwd \
|
||||
filesystem/bin/realpath \
|
||||
filesystem/bin/reset \
|
||||
|
@ -280,7 +281,7 @@ coreutils: \
|
|||
filesystem/bin/true \
|
||||
filesystem/bin/wc \
|
||||
filesystem/bin/yes
|
||||
#filesystem/bin/free filesystem/bin/ps filesystem/bin/shutdown filesystem/bin/test
|
||||
#filesystem/bin/free filesystem/bin/shutdown filesystem/bin/test
|
||||
|
||||
extrautils: \
|
||||
filesystem/bin/calc \
|
||||
|
|
|
@ -55,6 +55,8 @@ pub struct Context {
|
|||
pub stack: Option<Memory>,
|
||||
/// User grants
|
||||
pub grants: Arc<Mutex<Vec<Grant>>>,
|
||||
/// The name of the context
|
||||
pub name: Arc<Mutex<Vec<u8>>>,
|
||||
/// The current working directory
|
||||
pub cwd: Arc<Mutex<Vec<u8>>>,
|
||||
/// Kernel events
|
||||
|
@ -87,6 +89,7 @@ impl Context {
|
|||
heap: None,
|
||||
stack: None,
|
||||
grants: Arc::new(Mutex::new(Vec::new())),
|
||||
name: Arc::new(Mutex::new(Vec::new())),
|
||||
cwd: Arc::new(Mutex::new(Vec::new())),
|
||||
events: Arc::new(WaitQueue::new()),
|
||||
env: Arc::new(Mutex::new(BTreeMap::new())),
|
||||
|
|
|
@ -22,6 +22,7 @@ use self::initfs::InitFsScheme;
|
|||
use self::irq::{IRQ_SCHEME_ID, IrqScheme};
|
||||
use self::pipe::{PIPE_SCHEME_ID, PipeScheme};
|
||||
use self::root::{ROOT_SCHEME_ID, RootScheme};
|
||||
use self::sys::SysScheme;
|
||||
|
||||
/// Debug scheme
|
||||
pub mod debug;
|
||||
|
@ -44,6 +45,9 @@ pub mod pipe;
|
|||
/// Root scheme
|
||||
pub mod root;
|
||||
|
||||
/// System information
|
||||
pub mod sys;
|
||||
|
||||
/// Userspace schemes
|
||||
pub mod user;
|
||||
|
||||
|
@ -121,6 +125,7 @@ fn init_schemes() -> RwLock<SchemeList> {
|
|||
list.insert(Box::new(*b"initfs"), Arc::new(Box::new(InitFsScheme::new()))).expect("failed to insert initfs scheme");
|
||||
IRQ_SCHEME_ID.store(list.insert(Box::new(*b"irq"), Arc::new(Box::new(IrqScheme))).expect("failed to insert irq scheme"), Ordering::SeqCst);
|
||||
PIPE_SCHEME_ID.store(list.insert(Box::new(*b"pipe"), Arc::new(Box::new(PipeScheme))).expect("failed to insert pipe scheme"), Ordering::SeqCst);
|
||||
list.insert(Box::new(*b"sys"), Arc::new(Box::new(SysScheme::new()))).expect("failed to insert sys scheme");
|
||||
RwLock::new(list)
|
||||
}
|
||||
|
||||
|
|
90
kernel/scheme/sys/context.rs
Normal file
90
kernel/scheme/sys/context.rs
Normal file
|
@ -0,0 +1,90 @@
|
|||
use collections::{String, Vec};
|
||||
use core::str;
|
||||
|
||||
use context;
|
||||
use syscall::error::Result;
|
||||
|
||||
pub fn resource() -> Result<Vec<u8>> {
|
||||
let mut string = format!("{:<6}{:<6}{:<6}{:<6}{:<6}{:<8}{}\n",
|
||||
"PID",
|
||||
"PPID",
|
||||
"UID",
|
||||
"GID",
|
||||
"STAT",
|
||||
"MEM",
|
||||
"NAME");
|
||||
{
|
||||
let contexts = context::contexts();
|
||||
for (_id, context_lock) in contexts.iter() {
|
||||
let context = context_lock.read();
|
||||
|
||||
let mut memory = 0;
|
||||
if let Some(ref kfx) = context.kstack {
|
||||
memory += kfx.len();
|
||||
}
|
||||
if let Some(ref kstack) = context.kstack {
|
||||
memory += kstack.len();
|
||||
}
|
||||
for shared_mem in context.image.iter() {
|
||||
shared_mem.with(|mem| {
|
||||
memory += mem.size();
|
||||
});
|
||||
}
|
||||
if let Some(ref heap) = context.heap {
|
||||
heap.with(|heap| {
|
||||
memory += heap.size();
|
||||
});
|
||||
}
|
||||
if let Some(ref stack) = context.stack {
|
||||
memory += stack.size();
|
||||
}
|
||||
|
||||
let memory_string = if memory >= 1024 * 1024 * 1024 {
|
||||
format!("{} GB", memory / 1024 / 1024 / 1024)
|
||||
} else if memory >= 1024 * 1024 {
|
||||
format!("{} MB", memory / 1024 / 1024)
|
||||
} else if memory >= 1024 {
|
||||
format!("{} KB", memory / 1024)
|
||||
} else {
|
||||
format!("{} B", memory)
|
||||
};
|
||||
|
||||
let mut stat_string = String::new();
|
||||
if context.stack.is_some() {
|
||||
stat_string.push('U');
|
||||
} else {
|
||||
stat_string.push('K');
|
||||
}
|
||||
match context.status {
|
||||
context::Status::Runnable => {
|
||||
stat_string.push('R');
|
||||
},
|
||||
context::Status::Blocked => if context.wake.is_some() {
|
||||
stat_string.push('S');
|
||||
} else {
|
||||
stat_string.push('B');
|
||||
},
|
||||
context::Status::Exited(_status) => {
|
||||
stat_string.push('Z');
|
||||
}
|
||||
}
|
||||
if context.running {
|
||||
stat_string.push('+');
|
||||
}
|
||||
|
||||
let name_bytes = context.name.lock();
|
||||
let name = str::from_utf8(&name_bytes).unwrap_or("");
|
||||
|
||||
string.push_str(&format!("{:<6}{:<6}{:<6}{:<6}{:<6}{:<8}{}\n",
|
||||
context.id,
|
||||
context.ppid,
|
||||
context.euid,
|
||||
context.egid,
|
||||
stat_string,
|
||||
memory_string,
|
||||
name));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(string.into_bytes())
|
||||
}
|
162
kernel/scheme/sys/mod.rs
Normal file
162
kernel/scheme/sys/mod.rs
Normal file
|
@ -0,0 +1,162 @@
|
|||
use alloc::boxed::Box;
|
||||
use collections::{BTreeMap, Vec};
|
||||
use core::{cmp, str};
|
||||
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||
use spin::RwLock;
|
||||
|
||||
use syscall::data::Stat;
|
||||
use syscall::error::{Error, EBADF, EINVAL, ENOENT, Result};
|
||||
use syscall::flag::{MODE_FILE, SEEK_CUR, SEEK_END, SEEK_SET};
|
||||
use syscall::scheme::Scheme;
|
||||
|
||||
mod context;
|
||||
//mod interrupt;
|
||||
//mod log;
|
||||
//mod memory;
|
||||
//mod test;
|
||||
|
||||
struct Handle {
|
||||
path: &'static [u8],
|
||||
data: Vec<u8>,
|
||||
mode: u16,
|
||||
seek: usize
|
||||
}
|
||||
|
||||
type SysFn = Fn() -> Result<Vec<u8>> + Send + Sync;
|
||||
|
||||
/// System information scheme
|
||||
pub struct SysScheme {
|
||||
next_id: AtomicUsize,
|
||||
files: BTreeMap<&'static [u8], Box<SysFn>>,
|
||||
handles: RwLock<BTreeMap<usize, Handle>>
|
||||
}
|
||||
|
||||
impl SysScheme {
|
||||
pub fn new() -> SysScheme {
|
||||
let mut files: BTreeMap<&'static [u8], Box<SysFn>> = BTreeMap::new();
|
||||
|
||||
files.insert(b"context", Box::new(move || context::resource()));
|
||||
//files.insert(b"interrupt", Box::new(move || interrupt::resource()));
|
||||
//files.insert(b"log", Box::new(move || log::resource()));
|
||||
//files.insert(b"memory", Box::new(move || memory::resource()));
|
||||
//files.insert(b"test", Box::new(move || test::resource()));
|
||||
|
||||
SysScheme {
|
||||
next_id: AtomicUsize::new(0),
|
||||
files: files,
|
||||
handles: RwLock::new(BTreeMap::new())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Scheme for SysScheme {
|
||||
fn open(&self, path: &[u8], _flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
|
||||
let path_utf8 = str::from_utf8(path).map_err(|_err| Error::new(ENOENT))?;
|
||||
let path_trimmed = path_utf8.trim_matches('/');
|
||||
|
||||
//Have to iterate to get the path without allocation
|
||||
for entry in self.files.iter() {
|
||||
if entry.0 == &path_trimmed.as_bytes() {
|
||||
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
|
||||
self.handles.write().insert(id, Handle {
|
||||
path: entry.0,
|
||||
data: entry.1()?,
|
||||
mode: MODE_FILE | 0o444,
|
||||
seek: 0
|
||||
});
|
||||
|
||||
return Ok(id)
|
||||
}
|
||||
}
|
||||
|
||||
Err(Error::new(ENOENT))
|
||||
}
|
||||
|
||||
fn dup(&self, id: usize) -> Result<usize> {
|
||||
let (path, data, mode, seek) = {
|
||||
let handles = self.handles.read();
|
||||
let handle = handles.get(&id).ok_or(Error::new(EBADF))?;
|
||||
(handle.path, handle.data.clone(), handle.mode, handle.seek)
|
||||
};
|
||||
|
||||
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
|
||||
self.handles.write().insert(id, Handle {
|
||||
path: path,
|
||||
data: data,
|
||||
mode: mode,
|
||||
seek: seek
|
||||
});
|
||||
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
fn read(&self, id: usize, buffer: &mut [u8]) -> Result<usize> {
|
||||
let mut handles = self.handles.write();
|
||||
let mut handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?;
|
||||
|
||||
let mut i = 0;
|
||||
while i < buffer.len() && handle.seek < handle.data.len() {
|
||||
buffer[i] = handle.data[handle.seek];
|
||||
i += 1;
|
||||
handle.seek += 1;
|
||||
}
|
||||
|
||||
Ok(i)
|
||||
}
|
||||
|
||||
fn seek(&self, id: usize, pos: usize, whence: usize) -> Result<usize> {
|
||||
let mut handles = self.handles.write();
|
||||
let mut handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?;
|
||||
|
||||
handle.seek = match whence {
|
||||
SEEK_SET => cmp::min(handle.data.len(), pos),
|
||||
SEEK_CUR => cmp::max(0, cmp::min(handle.data.len() as isize, handle.seek as isize + pos as isize)) as usize,
|
||||
SEEK_END => cmp::max(0, cmp::min(handle.data.len() as isize, handle.data.len() as isize + pos as isize)) as usize,
|
||||
_ => return Err(Error::new(EINVAL))
|
||||
};
|
||||
|
||||
Ok(handle.seek)
|
||||
}
|
||||
|
||||
fn fpath(&self, id: usize, buf: &mut [u8]) -> Result<usize> {
|
||||
let handles = self.handles.read();
|
||||
let handle = handles.get(&id).ok_or(Error::new(EBADF))?;
|
||||
|
||||
//TODO: Copy scheme part in kernel
|
||||
let mut i = 0;
|
||||
let scheme_path = b"initfs:";
|
||||
while i < buf.len() && i < scheme_path.len() {
|
||||
buf[i] = scheme_path[i];
|
||||
i += 1;
|
||||
}
|
||||
|
||||
let mut j = 0;
|
||||
while i < buf.len() && j < handle.path.len() {
|
||||
buf[i] = handle.path[j];
|
||||
i += 1;
|
||||
j += 1;
|
||||
}
|
||||
|
||||
Ok(i)
|
||||
}
|
||||
|
||||
fn fstat(&self, id: usize, stat: &mut Stat) -> Result<usize> {
|
||||
let handles = self.handles.read();
|
||||
let handle = handles.get(&id).ok_or(Error::new(EBADF))?;
|
||||
|
||||
stat.st_mode = handle.mode;
|
||||
stat.st_uid = 0;
|
||||
stat.st_gid = 0;
|
||||
stat.st_size = handle.data.len() as u64;
|
||||
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn fsync(&self, _id: usize) -> Result<usize> {
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn close(&self, id: usize) -> Result<usize> {
|
||||
self.handles.write().remove(&id).ok_or(Error::new(EBADF)).and(Ok(0))
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@ use alloc::boxed::Box;
|
|||
use collections::{BTreeMap, Vec};
|
||||
use core::{mem, str};
|
||||
use core::ops::DerefMut;
|
||||
use spin::Mutex;
|
||||
use spin::{Mutex, RwLock};
|
||||
|
||||
use arch;
|
||||
use arch::externs::memcpy;
|
||||
|
@ -71,6 +71,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> {
|
|||
let mut heap_option = None;
|
||||
let mut stack_option = None;
|
||||
let grants;
|
||||
let name;
|
||||
let cwd;
|
||||
let env;
|
||||
let files;
|
||||
|
@ -186,6 +187,12 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> {
|
|||
grants = Arc::new(Mutex::new(Vec::new()));
|
||||
}
|
||||
|
||||
if flags & CLONE_VM == CLONE_VM {
|
||||
name = context.name.clone();
|
||||
} else {
|
||||
name = Arc::new(Mutex::new(context.name.lock().clone()));
|
||||
}
|
||||
|
||||
if flags & CLONE_FS == CLONE_FS {
|
||||
cwd = context.cwd.clone();
|
||||
} else {
|
||||
|
@ -382,6 +389,8 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> {
|
|||
context.stack = Some(stack);
|
||||
}
|
||||
|
||||
context.name = name;
|
||||
|
||||
context.cwd = cwd;
|
||||
|
||||
context.env = env;
|
||||
|
@ -395,61 +404,6 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> {
|
|||
Ok(pid)
|
||||
}
|
||||
|
||||
pub fn exit(status: usize) -> ! {
|
||||
{
|
||||
let mut close_files = Vec::new();
|
||||
{
|
||||
let contexts = context::contexts();
|
||||
let (vfork, ppid) = {
|
||||
let context_lock = contexts.current().expect("tried to exit without context");
|
||||
let mut context = context_lock.write();
|
||||
context.image.clear();
|
||||
drop(context.heap.take());
|
||||
drop(context.stack.take());
|
||||
context.grants = Arc::new(Mutex::new(Vec::new()));
|
||||
if Arc::strong_count(&context.files) == 1 {
|
||||
mem::swap(context.files.lock().deref_mut(), &mut close_files);
|
||||
}
|
||||
context.files = Arc::new(Mutex::new(Vec::new()));
|
||||
context.status = context::Status::Exited(status);
|
||||
|
||||
let vfork = context.vfork;
|
||||
context.vfork = false;
|
||||
context.waitpid.notify();
|
||||
(vfork, context.ppid)
|
||||
};
|
||||
if vfork {
|
||||
if let Some(context_lock) = contexts.get(ppid) {
|
||||
let mut context = context_lock.write();
|
||||
if ! context.unblock() {
|
||||
println!("{} not blocked for exit vfork unblock", ppid);
|
||||
}
|
||||
} else {
|
||||
println!("{} not found for exit vfork unblock", ppid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (fd, file_option) in close_files.drain(..).enumerate() {
|
||||
if let Some(file) = file_option {
|
||||
context::event::unregister(fd, file.scheme, file.number);
|
||||
|
||||
let scheme_option = {
|
||||
let schemes = scheme::schemes();
|
||||
schemes.get(file.scheme).map(|scheme| scheme.clone())
|
||||
};
|
||||
if let Some(scheme) = scheme_option {
|
||||
let _ = scheme.close(file.number);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe { context::switch(); }
|
||||
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
|
||||
let entry;
|
||||
let mut sp = arch::USER_STACK_OFFSET + arch::USER_STACK_SIZE - 256;
|
||||
|
@ -461,14 +415,14 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
|
|||
args.push(arg.to_vec()); // Must be moved into kernel space before exec unmaps all memory
|
||||
}
|
||||
|
||||
let (uid, gid) = {
|
||||
let (uid, gid, canonical) = {
|
||||
let contexts = context::contexts();
|
||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||
let context = context_lock.read();
|
||||
(context.euid, context.egid)
|
||||
(context.euid, context.egid, context.canonicalize(path))
|
||||
};
|
||||
|
||||
let file = syscall::open(path, 0)?;
|
||||
let file = syscall::open(&canonical, 0)?;
|
||||
let mut stat = Stat::default();
|
||||
syscall::file_op_mut_slice(syscall::number::SYS_FSTAT, file, &mut stat)?;
|
||||
|
||||
|
@ -505,6 +459,9 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
|
|||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||
let mut context = context_lock.write();
|
||||
|
||||
// Set name
|
||||
context.name = Arc::new(Mutex::new(canonical));
|
||||
|
||||
// Unmap previous image and stack
|
||||
context.image.clear();
|
||||
drop(context.heap.take());
|
||||
|
@ -639,6 +596,69 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
|
|||
unsafe { usermode(entry, sp); }
|
||||
}
|
||||
|
||||
fn terminate(context_lock: Arc<RwLock<context::Context>>, status: usize) {
|
||||
let mut close_files = Vec::new();
|
||||
{
|
||||
let (vfork, ppid) = {
|
||||
let mut context = context_lock.write();
|
||||
context.image.clear();
|
||||
drop(context.heap.take());
|
||||
drop(context.stack.take());
|
||||
context.grants = Arc::new(Mutex::new(Vec::new()));
|
||||
if Arc::strong_count(&context.files) == 1 {
|
||||
mem::swap(context.files.lock().deref_mut(), &mut close_files);
|
||||
}
|
||||
context.files = Arc::new(Mutex::new(Vec::new()));
|
||||
context.status = context::Status::Exited(status);
|
||||
|
||||
let vfork = context.vfork;
|
||||
context.vfork = false;
|
||||
context.waitpid.notify();
|
||||
(vfork, context.ppid)
|
||||
};
|
||||
if vfork {
|
||||
let contexts = context::contexts();
|
||||
if let Some(parent_lock) = contexts.get(ppid) {
|
||||
let mut parent = parent_lock.write();
|
||||
if ! parent.unblock() {
|
||||
println!("{} not blocked for exit vfork unblock", ppid);
|
||||
}
|
||||
} else {
|
||||
println!("{} not found for exit vfork unblock", ppid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (fd, file_option) in close_files.drain(..).enumerate() {
|
||||
if let Some(file) = file_option {
|
||||
context::event::unregister(fd, file.scheme, file.number);
|
||||
|
||||
let scheme_option = {
|
||||
let schemes = scheme::schemes();
|
||||
schemes.get(file.scheme).map(|scheme| scheme.clone())
|
||||
};
|
||||
if let Some(scheme) = scheme_option {
|
||||
let _ = scheme.close(file.number);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn exit(status: usize) -> ! {
|
||||
{
|
||||
let context_lock = {
|
||||
let contexts = context::contexts();
|
||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH)).expect("exit failed to find context");
|
||||
context_lock.clone()
|
||||
};
|
||||
terminate(context_lock, status);
|
||||
}
|
||||
|
||||
unsafe { context::switch(); }
|
||||
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
pub fn getegid() -> Result<usize> {
|
||||
let contexts = context::contexts();
|
||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||
|
@ -679,6 +699,69 @@ pub fn iopl(_level: usize) -> Result<usize> {
|
|||
Ok(0)
|
||||
}
|
||||
|
||||
pub fn kill(pid: usize, sig: usize) -> Result<usize> {
|
||||
use syscall::flag::*;
|
||||
|
||||
let context_lock = {
|
||||
let contexts = context::contexts();
|
||||
let context_lock = contexts.get(pid).ok_or(Error::new(ESRCH))?;
|
||||
context_lock.clone()
|
||||
};
|
||||
|
||||
let term = |context_lock| {
|
||||
terminate(context_lock, !sig);
|
||||
};
|
||||
|
||||
let core = |context_lock| {
|
||||
terminate(context_lock, !sig);
|
||||
};
|
||||
|
||||
let stop = || {
|
||||
|
||||
};
|
||||
|
||||
let cont = || {
|
||||
|
||||
};
|
||||
|
||||
match sig {
|
||||
0 => (),
|
||||
SIGHUP => term(context_lock),
|
||||
SIGINT => term(context_lock),
|
||||
SIGQUIT => core(context_lock),
|
||||
SIGILL => core(context_lock),
|
||||
SIGTRAP => core(context_lock),
|
||||
SIGABRT => core(context_lock),
|
||||
SIGBUS => core(context_lock),
|
||||
SIGFPE => core(context_lock),
|
||||
SIGKILL => term(context_lock),
|
||||
SIGUSR1 => term(context_lock),
|
||||
SIGSEGV => core(context_lock),
|
||||
SIGPIPE => term(context_lock),
|
||||
SIGALRM => term(context_lock),
|
||||
SIGTERM => term(context_lock),
|
||||
SIGSTKFLT => term(context_lock),
|
||||
SIGCHLD => (),
|
||||
SIGCONT => cont(),
|
||||
SIGSTOP => stop(),
|
||||
SIGTSTP => stop(),
|
||||
SIGTTIN => stop(),
|
||||
SIGTTOU => stop(),
|
||||
SIGURG => (),
|
||||
SIGXCPU => core(context_lock),
|
||||
SIGXFSZ => core(context_lock),
|
||||
SIGVTALRM => term(context_lock),
|
||||
SIGPROF => term(context_lock),
|
||||
SIGWINCH => (),
|
||||
SIGIO => term(context_lock),
|
||||
SIGPWR => term(context_lock),
|
||||
SIGSYS => core(context_lock),
|
||||
_ => return Err(Error::new(EINVAL))
|
||||
}
|
||||
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
pub fn physalloc(size: usize) -> Result<usize> {
|
||||
allocate_frames((size + 4095)/4096).ok_or(Error::new(ENOMEM)).map(|frame| frame.start_address().get())
|
||||
}
|
||||
|
|
|
@ -34,10 +34,6 @@ pub const MODE_PERM: u16 = 0x0FFF;
|
|||
pub const MODE_SETUID: u16 = 0o4000;
|
||||
pub const MODE_SETGID: u16 = 0o2000;
|
||||
|
||||
pub const SEEK_SET: usize = 0;
|
||||
pub const SEEK_CUR: usize = 1;
|
||||
pub const SEEK_END: usize = 2;
|
||||
|
||||
pub const O_RDONLY: usize = 0x0000_0000;
|
||||
pub const O_WRONLY: usize = 0x0001_0000;
|
||||
pub const O_RDWR: usize = 0x0002_0000;
|
||||
|
@ -52,4 +48,40 @@ pub const O_CREAT: usize = 0x0200_0000;
|
|||
pub const O_TRUNC: usize = 0x0400_0000;
|
||||
pub const O_EXCL: usize = 0x0800_0000;
|
||||
|
||||
pub const SEEK_SET: usize = 0;
|
||||
pub const SEEK_CUR: usize = 1;
|
||||
pub const SEEK_END: usize = 2;
|
||||
|
||||
pub const SIGHUP: usize = 1;
|
||||
pub const SIGINT: usize = 2;
|
||||
pub const SIGQUIT: usize = 3;
|
||||
pub const SIGILL: usize = 4;
|
||||
pub const SIGTRAP: usize = 5;
|
||||
pub const SIGABRT: usize = 6;
|
||||
pub const SIGBUS: usize = 7;
|
||||
pub const SIGFPE: usize = 8;
|
||||
pub const SIGKILL: usize = 9;
|
||||
pub const SIGUSR1: usize = 10;
|
||||
pub const SIGSEGV: usize = 11;
|
||||
pub const SIGUSR2: usize = 12;
|
||||
pub const SIGPIPE: usize = 13;
|
||||
pub const SIGALRM: usize = 14;
|
||||
pub const SIGTERM: usize = 15;
|
||||
pub const SIGSTKFLT: usize= 16;
|
||||
pub const SIGCHLD: usize = 17;
|
||||
pub const SIGCONT: usize = 18;
|
||||
pub const SIGSTOP: usize = 19;
|
||||
pub const SIGTSTP: usize = 20;
|
||||
pub const SIGTTIN: usize = 21;
|
||||
pub const SIGTTOU: usize = 22;
|
||||
pub const SIGURG: usize = 23;
|
||||
pub const SIGXCPU: usize = 24;
|
||||
pub const SIGXFSZ: usize = 25;
|
||||
pub const SIGVTALRM: usize= 26;
|
||||
pub const SIGPROF: usize = 27;
|
||||
pub const SIGWINCH: usize = 28;
|
||||
pub const SIGIO: usize = 29;
|
||||
pub const SIGPWR: usize = 30;
|
||||
pub const SIGSYS: usize = 31;
|
||||
|
||||
pub const WNOHANG: usize = 1;
|
||||
|
|
|
@ -112,6 +112,10 @@ pub unsafe fn iopl(level: usize) -> Result<usize> {
|
|||
syscall1(SYS_IOPL, level)
|
||||
}
|
||||
|
||||
pub fn kill(pid: usize, sig: usize) -> Result<usize> {
|
||||
unsafe { syscall2(SYS_KILL, pid, sig) }
|
||||
}
|
||||
|
||||
pub unsafe fn link(old: *const u8, new: *const u8) -> Result<usize> {
|
||||
syscall2(SYS_LINK, old as usize, new as usize)
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ pub const SYS_GETGID: usize = 200;
|
|||
pub const SYS_GETPID: usize = 20;
|
||||
pub const SYS_GETUID: usize = 199;
|
||||
pub const SYS_IOPL: usize = 110;
|
||||
pub const SYS_KILL: usize = 37;
|
||||
pub const SYS_NANOSLEEP: usize =162;
|
||||
pub const SYS_PHYSALLOC: usize =945;
|
||||
pub const SYS_PHYSFREE: usize = 946;
|
||||
|
|
Loading…
Reference in a new issue