From 3158f9c7c0ff4fa7f6969d3f76fdc5177ef9e2eb Mon Sep 17 00:00:00 2001 From: Alex Lyon Date: Fri, 15 Dec 2017 19:59:14 -0800 Subject: [PATCH] Move zero scheme from kernel space to user space --- .gitignore | 3 +++ Cargo.toml | 7 ++++++ src/main.rs | 28 ++++++++++++++++++++++++ src/scheme.rs | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 src/main.rs create mode 100644 src/scheme.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..0196246bdd --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ + +/target/ +**/*.rs.bk diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000000..ab09cc3f00 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "zerod" +version = "0.1.0" +authors = ["Alex Lyon "] + +[dependencies] +redox_syscall = "*" \ No newline at end of file diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000000..88589ea7f9 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,28 @@ +extern crate syscall; + +use syscall::data::Packet; +use syscall::scheme::Scheme; +use std::fs::File; +use std::io::{Read, Write}; +use std::mem::size_of; +use scheme::ZeroScheme; + +mod scheme; + +fn main() { + if unsafe { syscall::clone(0).unwrap() } == 0 { + let mut socket = File::create(":zero").expect("zerod: failed to create zero scheme"); + let scheme = ZeroScheme; + + syscall::setrens(0, 0).expect("zerod: failed to enter null namespace"); + + loop { + let mut packet = Packet::default(); + socket.read(&mut packet).expect("zerod: failed to read events from zero scheme"); + + scheme.handle(&mut packet); + + socket.write(&packet).expect("zerod: failed to write responses to zero scheme"); + } + } +} diff --git a/src/scheme.rs b/src/scheme.rs new file mode 100644 index 0000000000..91f5871460 --- /dev/null +++ b/src/scheme.rs @@ -0,0 +1,60 @@ +use syscall::error::*; +use syscall::scheme::Scheme; + +use std::cmp; + +pub struct ZeroScheme; + +impl Scheme for ZeroScheme { + fn open(&self, _path: &[u8], _flags: usize, _uid: u32, _gid: u32) -> Result { + Ok(0) + } + + fn dup(&self, _file: usize, buf: &[u8]) -> Result { + if ! buf.is_empty() { + return Err(Error::new(EINVAL)); + } + + Ok(0) + } + + /// Read the file `number` into the `buffer` + /// + /// Returns the number of bytes read + fn read(&self, _file: usize, buf: &mut [u8]) -> Result { + let size = buf.len(); + + buf[..size].iter_mut().for_each(|val| *val = 0); + + Ok(size) + } + + /// Write the `buffer` to the `file` + /// + /// Returns the number of bytes written + fn write(&self, _file: usize, buffer: &[u8]) -> Result { + Ok(buffer.len()) + } + + fn fcntl(&self, _id: usize, _cmd: usize, _arg: usize) -> Result { + Ok(0) + } + + fn fpath(&self, _id: usize, buf: &mut [u8]) -> Result { + let scheme_path = b"zero:"; + let size = cmp::min(buf.len(), scheme_path.len()); + + buf[..size].copy_from_slice(&scheme_path[..size]); + + Ok(size) + } + + fn fsync(&self, _file: usize) -> Result { + Ok(0) + } + + /// Close the file `number` + fn close(&self, _file: usize) -> Result { + Ok(0) + } +}