Migrate to libredox and redox-scheme.
This commit is contained in:
Generated
+68
-6
@@ -8,24 +8,86 @@ version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
|
||||
|
||||
[[package]]
|
||||
name = "ipcd"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"libredox 0.0.3",
|
||||
"redox-daemon",
|
||||
"redox-scheme",
|
||||
"redox_event",
|
||||
"redox_syscall",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.147"
|
||||
version = "0.2.150"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
|
||||
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
version = "0.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8"
|
||||
dependencies = [
|
||||
"bitflags 2.4.1",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
version = "0.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "962b650e6b934f95cec493e1464e0f5cba98dd9ba9ef2b1c42cdfdb7864cab5a"
|
||||
dependencies = [
|
||||
"bitflags 2.4.1",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox-daemon"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "353178b5771a301b9d2b318914ab5dfeb21dd6e65930faedde19248cfceca5a7"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"libredox 0.0.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox-scheme"
|
||||
version = "0.1.0"
|
||||
source = "git+https://gitlab.redox-os.org/redox-os/redox-scheme.git#265e056726066f319e47eedd5f20f9549fb4c581"
|
||||
dependencies = [
|
||||
"libredox 0.0.3",
|
||||
"redox_syscall",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_event"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b78fedc17aea72caee38ac1208e0f709fa1641af1bbe0205e7d434413a60621d"
|
||||
dependencies = [
|
||||
"bitflags 2.4.1",
|
||||
"libredox 0.0.1",
|
||||
"redox_syscall",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.3.5"
|
||||
source = "git+https://gitlab.redox-os.org/4lDO2/syscall.git?branch=better_fmap#f0976e1d6020e6854ca30ed1f6d61b10dfc4fa58"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
+5
-2
@@ -4,5 +4,8 @@ name = "ipcd"
|
||||
version = "0.1.0"
|
||||
|
||||
[dependencies]
|
||||
libc = "0.2"
|
||||
redox_syscall = { git = "https://gitlab.redox-os.org/redox-os/syscall.git" }
|
||||
libredox = "0.0.3"
|
||||
redox-daemon = "0.1.2"
|
||||
redox_syscall = "0.4.1"
|
||||
redox-scheme = { git = "https://gitlab.redox-os.org/redox-os/redox-scheme.git" }
|
||||
redox_event = "0.2.0"
|
||||
|
||||
+10
-19
@@ -1,12 +1,9 @@
|
||||
use crate::post_fevent;
|
||||
use std::{
|
||||
cmp,
|
||||
collections::{HashMap, VecDeque},
|
||||
fs::{File, OpenOptions},
|
||||
io,
|
||||
os::unix::fs::OpenOptionsExt,
|
||||
};
|
||||
use syscall::{flag::*, error::*, Error, SchemeBlockMut, Result};
|
||||
use syscall::{flag::*, error::*, Error};
|
||||
use redox_scheme::SchemeBlockMut;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Client {
|
||||
@@ -42,7 +39,6 @@ impl Default for Connection {
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Handle {
|
||||
id: usize,
|
||||
flags: usize,
|
||||
extra: Extra,
|
||||
path: Option<String>,
|
||||
@@ -96,20 +92,15 @@ pub struct ChanScheme {
|
||||
handles: HashMap<usize, Handle>,
|
||||
listeners: HashMap<String, usize>,
|
||||
next_id: usize,
|
||||
pub socket: File
|
||||
pub socket: redox_scheme::Socket,
|
||||
}
|
||||
impl ChanScheme {
|
||||
pub fn new() -> io::Result<Self> {
|
||||
pub fn new() -> Result<Self> {
|
||||
Ok(Self {
|
||||
handles: HashMap::new(),
|
||||
listeners: HashMap::new(),
|
||||
next_id: 0,
|
||||
socket: OpenOptions::new()
|
||||
.read(true)
|
||||
.write(true)
|
||||
.create(true)
|
||||
.custom_flags(O_NONBLOCK as i32)
|
||||
.open(":chan")?
|
||||
socket: redox_scheme::Socket::nonblock("chan")?,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -147,7 +138,7 @@ impl SchemeBlockMut for ChanScheme {
|
||||
// smoltcp sends writeable whenever a listener gets a
|
||||
// client, we'll do the same too (but also readable, why
|
||||
// not)
|
||||
post_fevent(&mut self.socket, listener_id, EVENT_READ | EVENT_WRITE)?;
|
||||
self.socket.post_fevent(listener_id, (EVENT_READ | EVENT_WRITE).bits())?;
|
||||
}
|
||||
|
||||
self.handles.insert(new_id, new);
|
||||
@@ -179,7 +170,7 @@ impl SchemeBlockMut for ChanScheme {
|
||||
},
|
||||
Extra::Listener(_) => panic!("newly created handle can't possibly be a listener")
|
||||
}
|
||||
post_fevent(&mut self.socket, remote_id, EVENT_WRITE)?;
|
||||
self.socket.post_fevent(remote_id, EVENT_WRITE.bits())?;
|
||||
|
||||
new.path = listener_path;
|
||||
|
||||
@@ -204,7 +195,7 @@ impl SchemeBlockMut for ChanScheme {
|
||||
// smoltcp sends writeable whenever a listener gets a
|
||||
// client, we'll do the same too (but also readable,
|
||||
// why not)
|
||||
post_fevent(&mut self.socket, id, EVENT_READ | EVENT_WRITE)?;
|
||||
self.socket.post_fevent(id, (EVENT_READ | EVENT_WRITE).bits())?;
|
||||
|
||||
self.handles.insert(new_id, new);
|
||||
self.next_id += 1;
|
||||
@@ -249,7 +240,7 @@ impl SchemeBlockMut for ChanScheme {
|
||||
if client.buffer.len() == buf.len() {
|
||||
// Send readable only if it wasn't readable
|
||||
// before
|
||||
post_fevent(&mut self.socket, remote_id, EVENT_READ)?;
|
||||
self.socket.post_fevent(remote_id, EVENT_READ.bits())?;
|
||||
}
|
||||
Ok(Some(buf.len()))
|
||||
},
|
||||
@@ -316,7 +307,7 @@ impl SchemeBlockMut for ChanScheme {
|
||||
if client.buffer.is_empty() {
|
||||
// Post readable on EOF only if it wasn't
|
||||
// readable before
|
||||
post_fevent(&mut self.socket, remote_id, EVENT_READ)?;
|
||||
self.socket.post_fevent(remote_id, EVENT_READ.bits())?;
|
||||
}
|
||||
},
|
||||
Extra::Listener(_) => panic!("a client can't be connected to a listener!")
|
||||
|
||||
+67
-92
@@ -1,12 +1,9 @@
|
||||
#![feature(int_roundings)]
|
||||
#![feature(int_roundings, let_chains)]
|
||||
|
||||
use std::{
|
||||
collections::VecDeque,
|
||||
fs::File,
|
||||
io::{self, prelude::*},
|
||||
os::unix::io::AsRawFd
|
||||
};
|
||||
use syscall::{flag::*, error, Error, Event, Packet, SchemeBlockMut, SchemeMut};
|
||||
use std::collections::VecDeque;
|
||||
use event::{EventQueue, EventFlags};
|
||||
use redox_scheme::{SignalBehavior, Response};
|
||||
use syscall::{Error, Result, EAGAIN, EWOULDBLOCK, ENODEV};
|
||||
|
||||
mod chan;
|
||||
mod shm;
|
||||
@@ -14,77 +11,76 @@ mod shm;
|
||||
use self::chan::ChanScheme;
|
||||
use self::shm::ShmScheme;
|
||||
|
||||
fn from_syscall_error(error: syscall::Error) -> io::Error {
|
||||
io::Error::from_raw_os_error(error.errno as i32)
|
||||
fn main() {
|
||||
redox_daemon::Daemon::new(move |daemon| {
|
||||
// TODO: Better error handling
|
||||
match inner(daemon) {
|
||||
Ok(()) => std::process::exit(0),
|
||||
Err(error) => {
|
||||
println!("ipcd failed: {error}");
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
}).expect("ipcd: failed to daemonize");
|
||||
}
|
||||
|
||||
const TOKEN_CHAN: usize = 0;
|
||||
const TOKEN_SHM: usize = 1;
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
match unsafe { libc::fork() } {
|
||||
0 => (),
|
||||
-1 => return Err(Box::new(io::Error::last_os_error())),
|
||||
_child => return Ok(()),
|
||||
fn inner(daemon: redox_daemon::Daemon) -> Result<()> {
|
||||
event::user_data! {
|
||||
enum EventSource {
|
||||
ChanSocket,
|
||||
ShmSocket,
|
||||
}
|
||||
}
|
||||
let chan = ChanScheme::new()?;
|
||||
let shm = ShmScheme::new()?;
|
||||
daemon.ready().unwrap();
|
||||
|
||||
// Create event listener for both files
|
||||
let mut event_file = File::open("event:")?;
|
||||
let mut event_queue = EventQueue::<EventSource>::new()?;
|
||||
|
||||
let chan = ChanScheme::new()?;
|
||||
event_file.write(&Event {
|
||||
id: chan.socket.as_raw_fd() as usize,
|
||||
flags: EVENT_READ,
|
||||
data: TOKEN_CHAN
|
||||
})?;
|
||||
let shm = ShmScheme::new()?;
|
||||
event_file.write(&Event {
|
||||
id: shm.socket.as_raw_fd() as usize,
|
||||
flags: EVENT_READ,
|
||||
data: TOKEN_SHM
|
||||
})?;
|
||||
event_queue.subscribe(chan.socket.inner().raw(), EventSource::ChanSocket, EventFlags::READ)?;
|
||||
event_queue.subscribe(shm.socket.inner().raw(), EventSource::ShmSocket, EventFlags::READ)?;
|
||||
|
||||
let mut todo = VecDeque::with_capacity(16);
|
||||
|
||||
syscall::setrens(0, 0).map_err(from_syscall_error)?;
|
||||
libredox::call::setrens(0, 0)?;
|
||||
|
||||
let mut chan_opt = Some(chan);
|
||||
let mut shm_opt = Some(shm);
|
||||
while chan_opt.is_some() || shm_opt.is_some() {
|
||||
let mut event = Event::default();
|
||||
event_file.read(&mut event)?;
|
||||
let Some(event_res) = event_queue.next() else {
|
||||
break;
|
||||
};
|
||||
let event = event_res?;
|
||||
|
||||
match event.data {
|
||||
TOKEN_CHAN => {
|
||||
let mut error: Option<io::Error> = None;
|
||||
match event.user_data {
|
||||
EventSource::ChanSocket => {
|
||||
let mut error: Option<Error> = None;
|
||||
|
||||
let unmount = if let Some(ref mut chan) = chan_opt {
|
||||
let eof = loop {
|
||||
let mut packet = Packet::default();
|
||||
match chan.socket.read(&mut packet) {
|
||||
Ok(0) => break true,
|
||||
Ok(_) => todo.push_front(packet),
|
||||
Err(err) => if err.kind() == io::ErrorKind::WouldBlock {
|
||||
break false;
|
||||
} else {
|
||||
return Err(Box::new(err));
|
||||
}
|
||||
};
|
||||
match chan.socket.next_request(SignalBehavior::Restart) {
|
||||
Ok(None) => break true,
|
||||
Ok(Some(request)) => todo.push_front(Some(request)),
|
||||
Err(Error { errno: EAGAIN | EWOULDBLOCK }) => break false,
|
||||
Err(error) => return Err(error),
|
||||
}
|
||||
};
|
||||
|
||||
// Process queue, delete finished items
|
||||
todo.retain(|packet| {
|
||||
if let Some(status) = chan.handle(&packet) {
|
||||
// Send packet back with new ID
|
||||
let mut packet = *packet;
|
||||
packet.a = status;
|
||||
if let Err(err) = chan.socket.write(&packet) {
|
||||
error = Some(err);
|
||||
todo.retain_mut(|request_opt| {
|
||||
match request_opt.take().unwrap().handle_scheme_block_mut(chan) {
|
||||
Ok(res) => {
|
||||
if let Err(err) = chan.socket.write_response(res, SignalBehavior::Restart) {
|
||||
error = Some(err);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
Err(req) => {
|
||||
*request_opt = Some(req);
|
||||
true
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
true
|
||||
});
|
||||
|
||||
eof
|
||||
@@ -92,38 +88,29 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
false
|
||||
};
|
||||
|
||||
if unmount {
|
||||
if let Some(mut chan) = chan_opt.take() {
|
||||
for mut packet in todo.drain(..) {
|
||||
packet.a = Error::mux(Err(Error::new(error::ENODEV)));
|
||||
if let Err(err) = chan.socket.write(&packet) {
|
||||
error = Some(err);
|
||||
}
|
||||
if unmount && let Some(chan) = chan_opt.take() {
|
||||
for req in todo.drain(..) {
|
||||
if let Err(err) = chan.socket.write_response(Response::new(&req.unwrap(), Err(Error::new(ENODEV))), SignalBehavior::Restart) {
|
||||
error = Some(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(err) = error {
|
||||
return Err(Box::new(err));
|
||||
return Err(err);
|
||||
}
|
||||
},
|
||||
TOKEN_SHM => {
|
||||
EventSource::ShmSocket => {
|
||||
let unmount = if let Some(ref mut shm) = shm_opt {
|
||||
let eof = loop {
|
||||
let mut packet = Packet::default();
|
||||
match shm.socket.read(&mut packet) {
|
||||
Ok(0) => break true,
|
||||
Ok(_) => {
|
||||
unsafe {
|
||||
shm.handle(&mut packet);
|
||||
}
|
||||
shm.socket.write(&packet)?;
|
||||
match shm.socket.next_request(SignalBehavior::Restart) {
|
||||
Ok(None) => break true,
|
||||
Ok(Some(request)) => {
|
||||
let response = request.handle_scheme_mut(shm);
|
||||
shm.socket.write_response(response, SignalBehavior::Restart)?;
|
||||
},
|
||||
Err(err) => if err.kind() == io::ErrorKind::WouldBlock {
|
||||
break false;
|
||||
} else {
|
||||
return Err(Box::new(err));
|
||||
}
|
||||
Err(Error { errno: EAGAIN | EWOULDBLOCK }) => break false,
|
||||
Err(err) => return Err(err),
|
||||
};
|
||||
};
|
||||
|
||||
@@ -135,21 +122,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
if unmount {
|
||||
shm_opt.take();
|
||||
}
|
||||
},
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
fn post_fevent(file: &mut File, id: usize, flag: EventFlags) -> syscall::Result<()> {
|
||||
file.write(&syscall::Packet {
|
||||
a: syscall::SYS_FEVENT,
|
||||
b: id,
|
||||
c: flag.bits(),
|
||||
d: 1,
|
||||
..Default::default()
|
||||
})
|
||||
.map(|_| ())
|
||||
.map_err(|_| Error::new(error::EIO))
|
||||
}
|
||||
|
||||
+6
-13
@@ -1,12 +1,10 @@
|
||||
use std::{
|
||||
cmp,
|
||||
collections::{HashMap, hash_map::Entry},
|
||||
fs::{File, OpenOptions},
|
||||
io,
|
||||
os::unix::fs::OpenOptionsExt,
|
||||
rc::Rc,
|
||||
};
|
||||
use syscall::{error::*, flag::O_NONBLOCK, Error, Map, SchemeMut, Result, Packet, KSMSG_MMAP_PREP, MapFlags, KSMSG_MMAP, PAGE_SIZE, MAP_PRIVATE};
|
||||
use syscall::{error::*, Error, Map, Result, MapFlags, PAGE_SIZE, MAP_PRIVATE};
|
||||
use redox_scheme::SchemeMut;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct ShmHandle {
|
||||
@@ -17,20 +15,15 @@ pub struct ShmScheme {
|
||||
maps: HashMap<Rc<str>, ShmHandle>,
|
||||
handles: HashMap<usize, Rc<str>>,
|
||||
next_id: usize,
|
||||
pub socket: File
|
||||
pub socket: redox_scheme::Socket,
|
||||
}
|
||||
impl ShmScheme {
|
||||
pub fn new() -> io::Result<Self> {
|
||||
pub fn new() -> Result<Self> {
|
||||
Ok(Self {
|
||||
maps: HashMap::new(),
|
||||
handles: HashMap::new(),
|
||||
next_id: 0,
|
||||
socket: OpenOptions::new()
|
||||
.read(true)
|
||||
.write(true)
|
||||
.create(true)
|
||||
.custom_flags(O_NONBLOCK as i32)
|
||||
.open(":shm")?
|
||||
socket: redox_scheme::Socket::nonblock("shm")?,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -75,7 +68,7 @@ impl SchemeMut for ShmScheme {
|
||||
}
|
||||
Ok(0)
|
||||
}
|
||||
fn mmap_prep(&mut self, id: usize, offset: u64, size: usize, flags: MapFlags) -> Result<usize> {
|
||||
fn mmap_prep(&mut self, id: usize, offset: u64, size: usize, _: MapFlags) -> Result<usize> {
|
||||
let path = self.handles.get(&id).ok_or(Error::new(EBADF))?;
|
||||
let total_size = offset as usize + size;
|
||||
match self.maps.get_mut(path).expect("handle pointing to nothing").buffer {
|
||||
|
||||
Reference in New Issue
Block a user