diff --git a/Cargo.lock b/Cargo.lock index e16f7f2693..a7cbfc4fb9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -91,11 +91,13 @@ source = "git+https://gitlab.redox-os.org/redox-os/arg-parser.git#1c434b55f3e1a0 name = "audiod" version = "0.1.0" dependencies = [ + "anyhow", + "ioslice", "libc", - "libredox 0.0.3", + "libredox", "redox-daemon", - "redox-scheme 0.1.0", - "redox_syscall 0.4.1", + "redox-scheme 0.5.0 (git+https://gitlab.redox-os.org/redox-os/redox-scheme.git)", + "redox_syscall", ] [[package]] @@ -405,7 +407,7 @@ dependencies = [ name = "init" version = "0.1.0" dependencies = [ - "libredox 0.1.3", + "libredox", ] [[package]] @@ -422,11 +424,11 @@ dependencies = [ name = "ipcd" version = "0.1.0" dependencies = [ - "libredox 0.1.3", + "libredox", "redox-daemon", "redox-scheme 0.2.4", "redox_event", - "redox_syscall 0.5.11", + "redox_syscall", ] [[package]] @@ -451,17 +453,6 @@ version = "0.2.171" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" -[[package]] -name = "libredox" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "962b650e6b934f95cec493e1464e0f5cba98dd9ba9ef2b1c42cdfdb7864cab5a" -dependencies = [ - "bitflags 2.9.0", - "libc", - "redox_syscall 0.4.1", -] - [[package]] name = "libredox" version = "0.1.3" @@ -471,7 +462,7 @@ dependencies = [ "bitflags 2.9.0", "ioslice", "libc", - "redox_syscall 0.5.11", + "redox_syscall", ] [[package]] @@ -484,10 +475,10 @@ checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" name = "logd" version = "0.1.0" dependencies = [ - "libredox 0.1.3", + "libredox", "redox-daemon", "redox-scheme 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.5.11", + "redox_syscall", ] [[package]] @@ -527,7 +518,7 @@ dependencies = [ "arg_parser", "clap", "libc", - "libredox 0.1.3", + "libredox", "net2", "ntpclient", "pbr", @@ -636,11 +627,11 @@ dependencies = [ name = "ptyd" version = "0.1.0" dependencies = [ - "libredox 0.1.3", + "libredox", "redox-daemon", "redox-scheme 0.3.0", "redox_event", - "redox_syscall 0.5.11", + "redox_syscall", "redox_termios", ] @@ -664,10 +655,10 @@ name = "ramfs" version = "0.1.0" dependencies = [ "indexmap", - "libredox 0.1.3", + "libredox", "redox-daemon", "redox-scheme 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.5.11", + "redox_syscall", "slab", ] @@ -691,13 +682,13 @@ checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" name = "randd" version = "0.1.0" dependencies = [ - "libredox 0.1.3", + "libredox", "rand_chacha", "rand_core", "raw-cpuid", "redox-daemon", "redox-scheme 0.2.4", - "redox_syscall 0.5.11", + "redox_syscall", "sha2", ] @@ -717,7 +708,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fbdeffdb03cf2961b211a2023e683d71f2c225ea93404da5dc34b0dc94f0341" dependencies = [ "libc", - "libredox 0.1.3", + "libredox", ] [[package]] @@ -732,24 +723,14 @@ dependencies = [ "termion", ] -[[package]] -name = "redox-scheme" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "425289b64797f9b7d98971e61d4838c67041c2ca13511e5a62539936873ae1a8" -dependencies = [ - "libredox 0.0.3", - "redox_syscall 0.4.1", -] - [[package]] name = "redox-scheme" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6143c4d307e1c99ac14f60b5b07b2dccaf9d17137f7cee4e4e29977dd8014a1b" dependencies = [ - "libredox 0.1.3", - "redox_syscall 0.5.11", + "libredox", + "redox_syscall", ] [[package]] @@ -758,8 +739,8 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63e7f06e1b19d8143043e959fbd7b76a37e759e3e9c6bbfc9c91c496b0b44d20" dependencies = [ - "libredox 0.1.3", - "redox_syscall 0.5.11", + "libredox", + "redox_syscall", ] [[package]] @@ -768,17 +749,17 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a96b9cfb034251dfb0aaa66a67059a7f0ea344039904d1d70cd36266af9c8a2f" dependencies = [ - "libredox 0.1.3", - "redox_syscall 0.5.11", + "libredox", + "redox_syscall", ] [[package]] name = "redox-scheme" version = "0.5.0" -source = "git+https://gitlab.redox-os.org/redox-os/redox-scheme.git#ce4eead6798c2d1d1d5a6d57b45481a4909ec62e" +source = "git+https://gitlab.redox-os.org/redox-os/redox-scheme.git#ef9f1512f54758be20960717dfad193d6cd70dc7" dependencies = [ - "libredox 0.1.3", - "redox_syscall 0.5.11", + "libredox", + "redox_syscall", ] [[package]] @@ -788,7 +769,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69609faa5d5992247a4ef379917bb3e39be281405d6a0ccd4f942429400b956f" dependencies = [ "bitflags 2.9.0", - "libredox 0.1.3", + "libredox", ] [[package]] @@ -798,26 +779,17 @@ dependencies = [ "anyhow", "dns-parser", "ioslice", - "libredox 0.1.3", + "libredox", "log", "netutils", "redox-daemon", "redox-log", "redox-scheme 0.5.0 (git+https://gitlab.redox-os.org/redox-os/redox-scheme.git)", "redox_event", - "redox_syscall 0.5.11", + "redox_syscall", "smoltcp", ] -[[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.5.11" @@ -946,7 +918,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3669a69de26799d6321a5aa713f55f7e2cd37bd47be044b50f2acafc42c122bb" dependencies = [ "libc", - "libredox 0.1.3", + "libredox", "numtoa", "redox_termios", ] @@ -1283,8 +1255,8 @@ dependencies = [ name = "zerod" version = "0.1.0" dependencies = [ - "libredox 0.1.3", + "libredox", "redox-daemon", "redox-scheme 0.2.4", - "redox_syscall 0.5.11", + "redox_syscall", ] diff --git a/audiod/Cargo.toml b/audiod/Cargo.toml index 94f7a21b01..70ed471c26 100644 --- a/audiod/Cargo.toml +++ b/audiod/Cargo.toml @@ -2,11 +2,13 @@ name = "audiod" version = "0.1.0" authors = ["Jeremy Soller "] -edition = "2018" +edition = "2021" [dependencies] redox-daemon = "0.1.2" -redox_syscall = "0.4.1" +redox_syscall = { version = "0.5", features = ["std"] } libc = "0.2" -libredox = "0.0.3" -redox-scheme = "0.1.0" +libredox = { version = "0.1", features = ["mkns"] } +redox-scheme = { git = "https://gitlab.redox-os.org/redox-os/redox-scheme.git" } +anyhow = "1.0.97" +ioslice = "0.6.0" diff --git a/audiod/src/main.rs b/audiod/src/main.rs index 13835c8ffe..759b53cdcf 100644 --- a/audiod/src/main.rs +++ b/audiod/src/main.rs @@ -1,13 +1,15 @@ -extern crate syscall; - use std::mem::MaybeUninit; use std::ptr::addr_of_mut; use std::sync::{Arc, Mutex}; use std::{mem, process, slice, thread}; +use anyhow::Context; +use ioslice::IoSlice; use libredox::flag; use libredox::{error::Result, Fd}; -use redox_scheme::{SignalBehavior, Socket}; + +use redox_scheme::wrappers::ReadinessBased; +use redox_scheme::Socket; use redox_daemon::Daemon; @@ -18,9 +20,6 @@ mod scheme; extern "C" fn sigusr_handler(_sig: usize) {} fn thread(scheme: Arc>, pid: usize, hw_file: Fd) -> Result<()> { - // Enter null namespace - libredox::call::setrens(0, 0)?; - loop { let buffer = scheme.lock().unwrap().buffer(); let buffer_u8 = unsafe { @@ -34,7 +33,7 @@ fn thread(scheme: Arc>, pid: usize, hw_file: Fd) -> Result<() } } -fn daemon(daemon: Daemon) -> Result<()> { +fn daemon(daemon: Daemon) -> anyhow::Result<()> { // Handle signals from the hw thread let new_sigaction = unsafe { @@ -50,55 +49,45 @@ fn daemon(daemon: Daemon) -> Result<()> { let hw_file = Fd::open("/scheme/audiohw", flag::O_WRONLY | flag::O_CLOEXEC, 0)?; - let socket = Socket::create("audio")?; + let socket = Socket::create("audio").context("failed to create scheme")?; let scheme = Arc::new(Mutex::new(AudioScheme::new())); + // Enter a constrained namespace + let ns = libredox::call::mkns(&[ + //IoSlice::new(b"memory"), TODO: already included, uncommenting gives EEXIST + IoSlice::new(b"rand"), // for HashMap + IoSlice::new(b"thisproc"), // for thread::spawn + ]).context("failed to make namespace")?; + libredox::call::setrens(ns, ns).context("failed to set namespace")?; + // Spawn a thread to mix and send audio data let scheme_thread = scheme.clone(); - let _thread = thread::spawn(move || thread(scheme_thread, pid, hw_file)); - - // Enter the null namespace - done after thread is created so - // memory: can be accessed for stack allocation - libredox::call::setrens(0, 0)?; + let _thread = thread::spawn(move || { + libredox::call::setrens(ns, ns).unwrap(); + thread(scheme_thread, pid, hw_file) + }); // The scheme is now ready to accept requests, notify the original process daemon.ready().unwrap(); - let mut pending = Vec::new(); + let mut readiness = ReadinessBased::new(&socket, 16); loop { - match socket.next_request(SignalBehavior::Interrupt) { - Ok(Some(request)) => { - match request.handle_scheme_block_mut(&mut *scheme.lock().unwrap()) { - Ok(response) => { - socket.write_responses(&[response], SignalBehavior::Restart)?; - } - Err(request) => pending.push(request), - } - } - Ok(None) => {} - Err(err) => match err.errno { - libredox::errno::EINTR => {} - _ => return Err(err), - }, - } - - let mut i = 0; - while i < pending.len() { - let request = pending[i]; - match request.handle_scheme_block_mut(&mut *scheme.lock().unwrap()) { - Ok(response) => { - pending.remove(i); - socket.write_responses(&[response], SignalBehavior::Restart)?; - } - Err(_) => i += 1, - } + if !readiness.read_requests()? { + break; } + readiness.process_requests(|| scheme.lock().unwrap()); + readiness.poll_all_requests(|| scheme.lock().unwrap())?; + if !readiness.write_responses()? { + break; + }; } + + Ok(()) } -fn main() { +fn main() -> anyhow::Result<()> { let Err(err) = Daemon::new(|x| match daemon(x) { Ok(()) => { process::exit(0); diff --git a/audiod/src/scheme.rs b/audiod/src/scheme.rs index fe525ae7fc..2e078361c2 100644 --- a/audiod/src/scheme.rs +++ b/audiod/src/scheme.rs @@ -1,9 +1,10 @@ +use redox_scheme::{CallerCtx, OpenResult}; use std::collections::{BTreeMap, VecDeque}; use std::str; -use syscall::error::{EBADF, EINVAL, ENOENT, EWOULDBLOCK, Error, Result}; -use syscall::flag::O_NONBLOCK; +use syscall::error::{Error, Result, EBADF, EINVAL, ENOENT, EWOULDBLOCK}; -use redox_scheme::SchemeBlockMut; +use redox_scheme::scheme::SchemeSync; +use syscall::schemev2::NewFdFlags; // The strict buffer size of the audiohw: driver const HW_BUFFER_SIZE: usize = 512; @@ -11,14 +12,10 @@ const HW_BUFFER_SIZE: usize = 512; const HANDLE_BUFFER_SIZE: usize = 4096; enum Handle { - Audio { - flags: usize, - buffer: VecDeque<(i16, i16)>, - }, - //TODO: move volume to audiohw:? - Volume { - offset: usize, - } + Audio { buffer: VecDeque<(i16, i16)> }, + // TODO: move volume to audiohw:? + // TODO: Use SYS_CALL to handle this better? + Volume, } pub struct AudioScheme { @@ -44,7 +41,7 @@ impl AudioScheme { let volume_factor = ((self.volume as f32) / 100.0).powi(3); for (_id, handle) in self.handles.iter_mut() { match handle { - Handle::Audio { flags: _, ref mut buffer } => { + Handle::Audio { ref mut buffer } => { let mut i = 0; while i < mix_buffer.len() { if let Some(sample) = buffer.pop_front() { @@ -57,7 +54,7 @@ impl AudioScheme { } i += 1; } - }, + } _ => (), } } @@ -66,16 +63,16 @@ impl AudioScheme { } } -impl SchemeBlockMut for AudioScheme { - fn open(&mut self, path: &str, flags: usize, _uid: u32, _gid: u32) -> Result> { - let handle = match path.trim_matches('/') { - "" => Handle::Audio { - flags, - buffer: VecDeque::new() - }, - "volume" => Handle::Volume { - offset: 0, - }, +impl SchemeSync for AudioScheme { + fn open(&mut self, path: &str, _flags: usize, _ctx: &CallerCtx) -> Result { + let (handle, flags) = match path.trim_matches('/') { + "" => ( + Handle::Audio { + buffer: VecDeque::new(), + }, + NewFdFlags::empty(), + ), + "volume" => (Handle::Volume, NewFdFlags::POSITIONED), _ => return Err(Error::new(ENOENT)), }; @@ -83,60 +80,68 @@ impl SchemeBlockMut for AudioScheme { self.next_id += 1; self.handles.insert(id, handle); - Ok(Some(id)) + Ok(OpenResult::ThisScheme { number: id, flags }) } - fn read(&mut self, id: usize, buf: &mut [u8]) -> Result> { + fn read( + &mut self, + id: usize, + buf: &mut [u8], + off: u64, + _flags: u32, + _ctx: &CallerCtx, + ) -> Result { //TODO: check flags for readable match self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { - Handle::Audio { flags: _, buffer: _ } => { + Handle::Audio { buffer: _ } => { //TODO: audio input? Err(Error::new(EBADF)) - }, - Handle::Volume { ref mut offset } => { + } + Handle::Volume => { + let Ok(off) = usize::try_from(off) else { + return Ok(0); + }; //TODO: should we allocate every time? - let string = format!("{}", self.volume); - let bytes = string.as_bytes(); + let bytes = format!("{}", self.volume).into_bytes(); + let src = bytes.get(off..).unwrap_or(&[]); + let len = src.len().min(buf.len()); + buf[..len].copy_from_slice(&src[..len]); - let mut i = 0; - while i < buf.len() && *offset + i < bytes.len() { - buf[i] = bytes[*offset + i]; - i += 1; - } - - *offset += i; - Ok(Some(i)) + Ok(len) } } } - fn write(&mut self, id: usize, buf: &[u8]) -> Result> { + fn write( + &mut self, + id: usize, + buf: &[u8], + offset: u64, + _flags: u32, + _ctx: &CallerCtx, + ) -> Result { //TODO: check flags for writable match self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { - Handle::Audio { ref flags, ref mut buffer } => { + Handle::Audio { ref mut buffer } => { if buffer.len() >= HANDLE_BUFFER_SIZE { - if flags & O_NONBLOCK > 0 { - Err(Error::new(EWOULDBLOCK)) - } else { - Ok(None) - } + Err(Error::new(EWOULDBLOCK)) } else { let mut i = 0; while i + 4 <= buf.len() { buffer.push_back(( (buf[i] as i16) | ((buf[i + 1] as i16) << 8), - (buf[i + 2] as i16) | ((buf[i + 3] as i16) << 8) + (buf[i + 2] as i16) | ((buf[i + 3] as i16) << 8), )); i += 4; } - Ok(Some(i)) + Ok(i) } - }, - Handle::Volume { ref mut offset } => { + } + Handle::Volume => { //TODO: support other offsets? - if *offset == 0 { + if offset == 0 { let value = str::from_utf8(buf) .map_err(|_| Error::new(EINVAL))? .trim() @@ -144,14 +149,13 @@ impl SchemeBlockMut for AudioScheme { .map_err(|_| Error::new(EINVAL))?; if value >= 0 && value <= 100 { self.volume = value; - *offset += buf.len(); - Ok(Some(buf.len())) + Ok(buf.len()) } else { Err(Error::new(EINVAL)) } } else { // EOF - Ok(Some(0)) + Ok(0) } } }