diff --git a/audiod/src/main.rs b/audiod/src/main.rs index 2aeda1c817..192967572f 100644 --- a/audiod/src/main.rs +++ b/audiod/src/main.rs @@ -88,7 +88,11 @@ fn daemon(daemon: Daemon) -> anyhow::Result<()> { } fn main() { - Daemon::new(|x| match daemon(x) { + Daemon::new(inner); +} + +fn inner(x: Daemon) -> ! { + match daemon(x) { Ok(()) => { process::exit(0); } @@ -96,5 +100,5 @@ fn main() { eprintln!("audiod: {}", err); process::exit(1); } - }); + } } diff --git a/bootstrap/Cargo.toml b/bootstrap/Cargo.toml index 4e47886def..c7a17745f1 100644 --- a/bootstrap/Cargo.toml +++ b/bootstrap/Cargo.toml @@ -20,11 +20,13 @@ plain = "0.2" redox-initfs = { path = "../initfs", default-features = false } redox_syscall = { version = "0.5.4", default-features = false } redox-scheme = { version = "0.6", default-features = false } -redox-rt = { git = "https://gitlab.redox-os.org/redox-os/relibc.git", default-features = false } redox-path = "0.3.1" slab = { version = "0.4.9", default-features = false } arrayvec = { version = "0.7.6", default-features = false } +[target.'cfg(target_os = "redox")'.dependencies] +redox-rt = { git = "https://gitlab.redox-os.org/redox-os/relibc.git", default-features = false } + [profile.release] panic = "abort" lto = "fat" diff --git a/bootstrap/src/exec.rs b/bootstrap/src/exec.rs index 9f5a32bdec..7d32305718 100644 --- a/bootstrap/src/exec.rs +++ b/bootstrap/src/exec.rs @@ -90,7 +90,7 @@ pub fn main() -> ! { // from this point, this_thr_fd is no longer valid const CWD: &[u8] = b"/scheme/initfs"; - const DEFAULT_SCHEME: &[u8] = b"initfs"; + const DEFAULT_SCHEME: &[u8] = b"file"; let extrainfo = ExtraInfo { cwd: Some(CWD), default_scheme: Some(DEFAULT_SCHEME), diff --git a/drivers/audio/ac97d/src/main.rs b/drivers/audio/ac97d/src/main.rs index d31be1a00d..9d9e785199 100644 --- a/drivers/audio/ac97d/src/main.rs +++ b/drivers/audio/ac97d/src/main.rs @@ -18,7 +18,10 @@ use std::cell::RefCell; pub mod device; fn main() { - let pcid_handle = PciFunctionHandle::connect_default(); + pcid_interface::pci_daemon(daemon); +} + +fn daemon(daemon: daemon::Daemon, pcid_handle: PciFunctionHandle) -> ! { let pci_config = pcid_handle.config(); let mut name = pci_config.func.name(); @@ -34,106 +37,101 @@ fn main() { println!(" + ac97 {}", pci_config.func.display()); - // Daemonize - daemon::Daemon::new(move |daemon| { - common::setup_logging( - "audio", - "pci", - &name, - common::output_level(), - common::file_level(), - ); + common::setup_logging( + "audio", + "pci", + &name, + common::output_level(), + common::file_level(), + ); - common::acquire_port_io_rights() - .expect("ac97d: failed to set I/O privilege level to Ring 3"); + common::acquire_port_io_rights().expect("ac97d: failed to set I/O privilege level to Ring 3"); - let mut irq_file = irq.irq_handle("ac97d"); + let mut irq_file = irq.irq_handle("ac97d"); - let device = RefCell::new(unsafe { - device::Ac97::new(bar0, bar1).expect("ac97d: failed to allocate device") - }); - let socket = Socket::nonblock("audiohw").expect("ac97d: failed to create socket"); - let mut readiness_based = ReadinessBased::new(&socket, 16); - - user_data! { - enum Source { - Irq, - Scheme, - } - } - - let event_queue = - EventQueue::::new().expect("ac97d: Could not create event queue."); - event_queue - .subscribe( - irq_file.as_raw_fd() as usize, - Source::Irq, - event::EventFlags::READ, - ) - .unwrap(); - event_queue - .subscribe( - socket.inner().raw(), - Source::Scheme, - event::EventFlags::READ, - ) - .unwrap(); - - daemon.ready(); - - libredox::call::setrens(0, 0).expect("ac97d: failed to enter null namespace"); - - let all = [Source::Irq, Source::Scheme]; - for event in all - .into_iter() - .chain(event_queue.map(|e| e.expect("ac97d: failed to get next event").user_data)) - { - match event { - Source::Irq => { - let mut irq = [0; 8]; - irq_file.read(&mut irq).unwrap(); - - if !device.borrow_mut().irq() { - continue; - } - irq_file.write(&mut irq).unwrap(); - - readiness_based - .poll_all_requests(|| device.borrow_mut()) - .expect("ac97d: failed to poll requests"); - - /* - let next_read = device_irq.next_read(); - if next_read > 0 { - return Ok(Some(next_read)); - } - */ - } - Source::Scheme => { - if !readiness_based - .read_requests() - .expect("ac97d: failed to read from socket") - { - break; - } - readiness_based.process_requests(|| device.borrow_mut()); - if !readiness_based - .write_responses() - .expect("ac97d: failed to write to socket") - { - break; - } - - /* - let next_read = device.borrow().next_read(); - if next_read > 0 { - return Ok(Some(next_read)); - } - */ - } - } - } - - std::process::exit(0); + let device = RefCell::new(unsafe { + device::Ac97::new(bar0, bar1).expect("ac97d: failed to allocate device") }); + let socket = Socket::nonblock("audiohw").expect("ac97d: failed to create socket"); + let mut readiness_based = ReadinessBased::new(&socket, 16); + + user_data! { + enum Source { + Irq, + Scheme, + } + } + + let event_queue = EventQueue::::new().expect("ac97d: Could not create event queue."); + event_queue + .subscribe( + irq_file.as_raw_fd() as usize, + Source::Irq, + event::EventFlags::READ, + ) + .unwrap(); + event_queue + .subscribe( + socket.inner().raw(), + Source::Scheme, + event::EventFlags::READ, + ) + .unwrap(); + + daemon.ready(); + + libredox::call::setrens(0, 0).expect("ac97d: failed to enter null namespace"); + + let all = [Source::Irq, Source::Scheme]; + for event in all + .into_iter() + .chain(event_queue.map(|e| e.expect("ac97d: failed to get next event").user_data)) + { + match event { + Source::Irq => { + let mut irq = [0; 8]; + irq_file.read(&mut irq).unwrap(); + + if !device.borrow_mut().irq() { + continue; + } + irq_file.write(&mut irq).unwrap(); + + readiness_based + .poll_all_requests(|| device.borrow_mut()) + .expect("ac97d: failed to poll requests"); + + /* + let next_read = device_irq.next_read(); + if next_read > 0 { + return Ok(Some(next_read)); + } + */ + } + Source::Scheme => { + if !readiness_based + .read_requests() + .expect("ac97d: failed to read from socket") + { + break; + } + readiness_based.process_requests(|| device.borrow_mut()); + if !readiness_based + .write_responses() + .expect("ac97d: failed to write to socket") + { + break; + } + + /* + let next_read = device.borrow().next_read(); + if next_read > 0 { + return Ok(Some(next_read)); + } + */ + } + } + } + + std::process::exit(0); } diff --git a/drivers/audio/ihdad/src/main.rs b/drivers/audio/ihdad/src/main.rs index 7660681a71..7331a59197 100755 --- a/drivers/audio/ihdad/src/main.rs +++ b/drivers/audio/ihdad/src/main.rs @@ -23,9 +23,11 @@ QEMU ICH9 8086:293E 82801H ICH8 8086:284B */ -fn daemon(daemon: daemon::Daemon) -> ! { - let mut pcid_handle = PciFunctionHandle::connect_default(); +fn main() { + pcid_interface::pci_daemon(daemon); +} +fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! { let pci_config = pcid_handle.config(); let mut name = pci_config.func.name(); @@ -138,8 +140,3 @@ fn daemon(daemon: daemon::Daemon) -> ! { std::process::exit(0); } } - -fn main() { - // Daemonize - daemon::Daemon::new(daemon); -} diff --git a/drivers/audio/sb16d/src/main.rs b/drivers/audio/sb16d/src/main.rs index 72e9c82c8e..7701f55b87 100644 --- a/drivers/audio/sb16d/src/main.rs +++ b/drivers/audio/sb16d/src/main.rs @@ -11,6 +11,10 @@ use event::{user_data, EventQueue}; pub mod device; fn main() { + daemon::Daemon::new(daemon); +} + +fn daemon(daemon: daemon::Daemon) -> ! { let mut args = env::args().skip(1); let addr_str = args.next().unwrap_or("220".to_string()); @@ -18,99 +22,94 @@ fn main() { println!(" + sb16 at 0x{:X}\n", addr); - // Daemonize - daemon::Daemon::new(move |daemon| { - common::setup_logging( - "audio", - "pci", - "sb16", - common::output_level(), - common::file_level(), - ); + common::setup_logging( + "audio", + "pci", + "sb16", + common::output_level(), + common::file_level(), + ); - common::acquire_port_io_rights().expect("sb16d: failed to acquire port IO rights"); + common::acquire_port_io_rights().expect("sb16d: failed to acquire port IO rights"); - let device = RefCell::new(unsafe { - device::Sb16::new(addr).expect("sb16d: failed to allocate device") - }); - let socket = Socket::nonblock("audiohw").expect("sb16d: failed to create socket"); - let mut readiness_based = ReadinessBased::new(&socket, 16); + let device = + RefCell::new(unsafe { device::Sb16::new(addr).expect("sb16d: failed to allocate device") }); + let socket = Socket::nonblock("audiohw").expect("sb16d: failed to create socket"); + let mut readiness_based = ReadinessBased::new(&socket, 16); - //TODO: error on multiple IRQs? - let irq_file = match device.borrow().irqs.first() { - Some(irq) => Fd::open(&format!("/scheme/irq/{}", irq), flag::O_RDWR, 0) - .expect("sb16d: failed to open IRQ file"), - None => panic!("sb16d: no IRQs found"), - }; - user_data! { - enum Source { - Irq, - Scheme, - } + //TODO: error on multiple IRQs? + let irq_file = match device.borrow().irqs.first() { + Some(irq) => Fd::open(&format!("/scheme/irq/{}", irq), flag::O_RDWR, 0) + .expect("sb16d: failed to open IRQ file"), + None => panic!("sb16d: no IRQs found"), + }; + user_data! { + enum Source { + Irq, + Scheme, } + } - let event_queue = - EventQueue::::new().expect("sb16d: Could not create event queue."); - event_queue - .subscribe(irq_file.raw(), Source::Irq, event::EventFlags::READ) - .unwrap(); - event_queue - .subscribe( - socket.inner().raw(), - Source::Scheme, - event::EventFlags::READ, - ) - .unwrap(); + let event_queue = EventQueue::::new().expect("sb16d: Could not create event queue."); + event_queue + .subscribe(irq_file.raw(), Source::Irq, event::EventFlags::READ) + .unwrap(); + event_queue + .subscribe( + socket.inner().raw(), + Source::Scheme, + event::EventFlags::READ, + ) + .unwrap(); - daemon.ready(); + daemon.ready(); - libredox::call::setrens(0, 0).expect("sb16d: failed to enter null namespace"); + libredox::call::setrens(0, 0).expect("sb16d: failed to enter null namespace"); - let all = [Source::Irq, Source::Scheme]; + let all = [Source::Irq, Source::Scheme]; - for event in all - .into_iter() - .chain(event_queue.map(|e| e.expect("sb16d: failed to get next event").user_data)) - { - match event { - Source::Irq => { - let mut irq = [0; 8]; - irq_file.read(&mut irq).unwrap(); + for event in all + .into_iter() + .chain(event_queue.map(|e| e.expect("sb16d: failed to get next event").user_data)) + { + match event { + Source::Irq => { + let mut irq = [0; 8]; + irq_file.read(&mut irq).unwrap(); - if !device.borrow_mut().irq() { - continue; - } - irq_file.write(&mut irq).unwrap(); - - readiness_based - .poll_all_requests(|| device.borrow_mut()) - .expect("sb16d: failed to poll requests"); - - /* - let next_read = device_irq.next_read(); - if next_read > 0 { - return Ok(Some(next_read)); - } - */ + if !device.borrow_mut().irq() { + continue; } - Source::Scheme => { - if !readiness_based - .read_requests() - .expect("sb16d: failed to read from socket") - { - break; - } - readiness_based.process_requests(|| device.borrow_mut()); - if !readiness_based - .write_responses() - .expect("sb16d: failed to write to socket") - { - break; - } + irq_file.write(&mut irq).unwrap(); + + readiness_based + .poll_all_requests(|| device.borrow_mut()) + .expect("sb16d: failed to poll requests"); + + /* + let next_read = device_irq.next_read(); + if next_read > 0 { + return Ok(Some(next_read)); + } + */ + } + Source::Scheme => { + if !readiness_based + .read_requests() + .expect("sb16d: failed to read from socket") + { + break; + } + readiness_based.process_requests(|| device.borrow_mut()); + if !readiness_based + .write_responses() + .expect("sb16d: failed to write to socket") + { + break; } } } + } - std::process::exit(0); - }); + std::process::exit(0); } diff --git a/drivers/graphics/bgad/src/main.rs b/drivers/graphics/bgad/src/main.rs index 640908a8d9..2170d21b2d 100644 --- a/drivers/graphics/bgad/src/main.rs +++ b/drivers/graphics/bgad/src/main.rs @@ -13,7 +13,10 @@ mod scheme; // FIXME add a driver-graphics implementation fn main() { - let mut pcid_handle = PciFunctionHandle::connect_default(); + pcid_interface::pci_daemon(daemon); +} + +fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! { let pci_config = pcid_handle.config(); let mut name = pci_config.func.name(); @@ -29,46 +32,44 @@ fn main() { log::info!("BGA {}", pci_config.func.display()); - daemon::Daemon::new(move |daemon| { - let socket = Socket::create("bga").expect("bgad: failed to create bga scheme"); + let socket = Socket::create("bga").expect("bgad: failed to create bga scheme"); - let bar = unsafe { pcid_handle.map_bar(2) }.ptr.as_ptr(); + let bar = unsafe { pcid_handle.map_bar(2) }.ptr.as_ptr(); - let mut bga = unsafe { Bga::new(bar) }; - log::debug!("BGA {}x{}", bga.width(), bga.height()); + let mut bga = unsafe { Bga::new(bar) }; + log::debug!("BGA {}x{}", bga.width(), bga.height()); - let mut scheme = BgaScheme { - bga, - display: ProducerHandle::new().ok(), + let mut scheme = BgaScheme { + bga, + display: ProducerHandle::new().ok(), + }; + + scheme.update_size(); + + libredox::call::setrens(0, 0).expect("bgad: failed to enter null namespace"); + + daemon.ready(); + + loop { + let Some(request) = socket + .next_request(SignalBehavior::Restart) + .expect("bgad: failed to get next scheme request") + else { + // Scheme likely got unmounted + std::process::exit(0); }; + match request.kind() { + RequestKind::Call(call) => { + let response = call.handle_sync(&mut scheme); - scheme.update_size(); - - libredox::call::setrens(0, 0).expect("bgad: failed to enter null namespace"); - - daemon.ready(); - - loop { - let Some(request) = socket - .next_request(SignalBehavior::Restart) - .expect("bgad: failed to get next scheme request") - else { - // Scheme likely got unmounted - std::process::exit(0); - }; - match request.kind() { - RequestKind::Call(call) => { - let response = call.handle_sync(&mut scheme); - - socket - .write_response(response, SignalBehavior::Restart) - .expect("bgad: failed to write next scheme response"); - } - RequestKind::OnClose { id } => { - scheme.on_close(id); - } - _ => (), + socket + .write_response(response, SignalBehavior::Restart) + .expect("bgad: failed to write next scheme response"); } + RequestKind::OnClose { id } => { + scheme.on_close(id); + } + _ => (), } - }); + } } diff --git a/drivers/graphics/fbbootlogd/src/main.rs b/drivers/graphics/fbbootlogd/src/main.rs index bee32c5398..69e18659c8 100644 --- a/drivers/graphics/fbbootlogd/src/main.rs +++ b/drivers/graphics/fbbootlogd/src/main.rs @@ -21,9 +21,9 @@ use crate::scheme::FbbootlogScheme; mod scheme; fn main() { - daemon::Daemon::new(|daemon| inner(daemon)); + daemon::Daemon::new(daemon); } -fn inner(daemon: daemon::Daemon) -> ! { +fn daemon(daemon: daemon::Daemon) -> ! { let event_queue = EventQueue::new().expect("fbbootlogd: failed to create event queue"); event::user_data! { diff --git a/drivers/graphics/fbcond/src/main.rs b/drivers/graphics/fbcond/src/main.rs index ad0c88016a..1ecfd30403 100644 --- a/drivers/graphics/fbcond/src/main.rs +++ b/drivers/graphics/fbcond/src/main.rs @@ -13,6 +13,9 @@ mod scheme; mod text; fn main() { + daemon::Daemon::new(daemon); +} +fn daemon(daemon: daemon::Daemon) -> ! { let vt_ids = env::args() .skip(1) .map(|arg| arg.parse().expect("invalid vt number")) @@ -26,9 +29,6 @@ fn main() { common::file_level(), ); - daemon::Daemon::new(|daemon| inner(daemon, &vt_ids)); -} -fn inner(daemon: daemon::Daemon, vt_ids: &[usize]) -> ! { let mut event_queue = EventQueue::new().expect("fbcond: failed to create event queue"); // FIXME listen for resize events from inputd and handle them @@ -42,7 +42,7 @@ fn inner(daemon: daemon::Daemon, vt_ids: &[usize]) -> ! { ) .expect("fbcond: failed to subscribe to scheme events"); - let mut scheme = FbconScheme::new(vt_ids, &mut event_queue); + let mut scheme = FbconScheme::new(&vt_ids, &mut event_queue); // This is not possible for now as fbcond needs to open new displays at runtime for graphics // driver handoff. In the future inputd may directly pass a handle to the display instead. diff --git a/drivers/graphics/vesad/src/main.rs b/drivers/graphics/vesad/src/main.rs index f5457c6fdb..5d71b9d5fb 100644 --- a/drivers/graphics/vesad/src/main.rs +++ b/drivers/graphics/vesad/src/main.rs @@ -12,9 +12,13 @@ use crate::scheme::{FbAdapter, FrameBuffer}; mod scheme; fn main() { + daemon::Daemon::new(daemon); +} +fn daemon(daemon: daemon::Daemon) -> ! { if env::var("FRAMEBUFFER_WIDTH").is_err() { println!("vesad: No boot framebuffer"); - return; + daemon.ready(); + std::process::exit(0); } let width = usize::from_str_radix( @@ -45,7 +49,8 @@ fn main() { if phys == 0 { println!("vesad: Boot framebuffer at address 0"); - return; + daemon.ready(); + std::process::exit(0); } let mut framebuffers = vec![unsafe { FrameBuffer::new(phys, width, height, stride) }]; @@ -69,9 +74,6 @@ fn main() { }; } - daemon::Daemon::new(|daemon| inner(daemon, framebuffers)); -} -fn inner(daemon: daemon::Daemon, framebuffers: Vec) -> ! { let mut inputd_display_handle = DisplayHandle::new_early("vesa").unwrap(); let mut scheme = GraphicsScheme::new(FbAdapter { framebuffers }, "display.vesa".to_owned()); diff --git a/drivers/graphics/virtio-gpud/src/main.rs b/drivers/graphics/virtio-gpud/src/main.rs index fcd0142201..5852efaebb 100644 --- a/drivers/graphics/virtio-gpud/src/main.rs +++ b/drivers/graphics/virtio-gpud/src/main.rs @@ -430,8 +430,23 @@ impl MoveCursor { static DEVICE: spin::Once = spin::Once::new(); -fn deamon(deamon: daemon::Daemon) -> anyhow::Result<()> { - let mut pcid_handle = PciFunctionHandle::connect_default(); +fn main() { + pcid_interface::pci_daemon(daemon_runner); +} + +fn daemon_runner(daemon: daemon::Daemon, pcid_handle: PciFunctionHandle) -> ! { + deamon(daemon, pcid_handle).unwrap(); + unreachable!(); +} + +fn deamon(deamon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> anyhow::Result<()> { + common::setup_logging( + "graphics", + "pci", + "virtio-gpud", + common::output_level(), + common::file_level(), + ); // Double check that we have the right device. // @@ -542,19 +557,3 @@ fn deamon(deamon: daemon::Daemon) -> anyhow::Result<()> { std::process::exit(0); } - -fn daemon_runner(daemon: daemon::Daemon) -> ! { - deamon(daemon).unwrap(); - unreachable!(); -} - -pub fn main() { - common::setup_logging( - "graphics", - "pci", - "virtio-gpud", - common::output_level(), - common::file_level(), - ); - daemon::Daemon::new(daemon_runner); -} diff --git a/drivers/net/alxd/src/main.rs b/drivers/net/alxd/src/main.rs index 2a481f77ad..6c63136eff 100644 --- a/drivers/net/alxd/src/main.rs +++ b/drivers/net/alxd/src/main.rs @@ -19,6 +19,10 @@ use std::cell::RefCell; pub mod device; fn main() { + daemon::Daemon::new(daemon); +} + +fn daemon(daemon: daemon::Daemon) -> ! { let mut args = env::args().skip(1); let mut name = args.next().expect("alxd: no name provided"); @@ -32,106 +36,102 @@ fn main() { println!(" + ALX {} on: {:X}, IRQ: {}\n", name, bar, irq); - // Daemonize - daemon::Daemon::new(move |daemon| { - let socket = Socket::nonblock("network").expect("alxd: failed to create socket"); - let mut readiness_based = ReadinessBased::new(&socket, 16); + let socket = Socket::nonblock("network").expect("alxd: failed to create socket"); + let mut readiness_based = ReadinessBased::new(&socket, 16); - daemon.ready(); + daemon.ready(); - let mut irq_file = - File::open(format!("/scheme/irq/{}", irq)).expect("alxd: failed to open IRQ file"); + let mut irq_file = + File::open(format!("/scheme/irq/{}", irq)).expect("alxd: failed to open IRQ file"); - let address = unsafe { - common::physmap( - bar, - 128 * 1024, - common::Prot::RW, - common::MemoryType::Uncacheable, - ) - .expect("alxd: failed to map address") as usize - }; - { - let device = RefCell::new(unsafe { - device::Alx::new(address).expect("alxd: failed to allocate device") - }); + let address = unsafe { + common::physmap( + bar, + 128 * 1024, + common::Prot::RW, + common::MemoryType::Uncacheable, + ) + .expect("alxd: failed to map address") as usize + }; + { + let device = RefCell::new(unsafe { + device::Alx::new(address).expect("alxd: failed to allocate device") + }); - user_data! { - enum Source { - Irq, - Scheme, - } + user_data! { + enum Source { + Irq, + Scheme, } + } - let event_queue = - EventQueue::::new().expect("alxd: failed to create event queue"); - event_queue - .subscribe( - irq_file.as_raw_fd() as usize, - Source::Irq, - event::EventFlags::READ, - ) - .unwrap(); - event_queue - .subscribe( - socket.inner().raw(), - Source::Scheme, - event::EventFlags::READ, - ) - .unwrap(); + let event_queue = EventQueue::::new().expect("alxd: failed to create event queue"); + event_queue + .subscribe( + irq_file.as_raw_fd() as usize, + Source::Irq, + event::EventFlags::READ, + ) + .unwrap(); + event_queue + .subscribe( + socket.inner().raw(), + Source::Scheme, + event::EventFlags::READ, + ) + .unwrap(); - libredox::call::setrens(0, 0).expect("alxd: failed to enter null namespace"); + libredox::call::setrens(0, 0).expect("alxd: failed to enter null namespace"); - for event in iter::once(Source::Scheme) - .chain(event_queue.map(|e| e.expect("alxd: failed to get next event").user_data)) - { - match event { - Source::Irq => { - let mut irq = [0; 8]; - irq_file.read(&mut irq).unwrap(); - if !unsafe { device.borrow_mut().intr_legacy() } { - continue; - } - irq_file.write(&mut irq).unwrap(); + for event in iter::once(Source::Scheme) + .chain(event_queue.map(|e| e.expect("alxd: failed to get next event").user_data)) + { + match event { + Source::Irq => { + let mut irq = [0; 8]; + irq_file.read(&mut irq).unwrap(); + if !unsafe { device.borrow_mut().intr_legacy() } { + continue; + } + irq_file.write(&mut irq).unwrap(); - readiness_based - .poll_all_requests(|| device.borrow_mut()) - .expect("ihdad: failed to poll requests"); + readiness_based + .poll_all_requests(|| device.borrow_mut()) + .expect("ihdad: failed to poll requests"); - /* TODO: Currently a no-op - let next_read = device.next_read(); - if next_read > 0 { - return Ok(Some(next_read)); - } - */ + /* TODO: Currently a no-op + let next_read = device.next_read(); + if next_read > 0 { + return Ok(Some(next_read)); + } + */ + } + + Source::Scheme => { + if !readiness_based + .read_requests() + .expect("alxd: failed to read from socket") + { + break; + } + readiness_based.process_requests(|| device.borrow_mut()); + if !readiness_based + .write_responses() + .expect("alxd: failed to write to socket") + { + break; } - Source::Scheme => { - if !readiness_based - .read_requests() - .expect("alxd: failed to read from socket") - { - break; - } - readiness_based.process_requests(|| device.borrow_mut()); - if !readiness_based - .write_responses() - .expect("alxd: failed to write to socket") - { - break; - } - - // TODO - /* - let next_read = device.next_read(); - if next_read > 0 { - return Ok(Some(next_read)); - } - */ + // TODO + /* + let next_read = device.next_read(); + if next_read > 0 { + return Ok(Some(next_read)); } + */ } } } - std::process::exit(0); - }); + } + std::process::exit(0); } diff --git a/drivers/net/e1000d/src/main.rs b/drivers/net/e1000d/src/main.rs index 2824d8716b..373ea9b38b 100644 --- a/drivers/net/e1000d/src/main.rs +++ b/drivers/net/e1000d/src/main.rs @@ -8,7 +8,10 @@ use pcid_interface::PciFunctionHandle; pub mod device; fn main() { - let mut pcid_handle = PciFunctionHandle::connect_default(); + pcid_interface::pci_daemon(daemon); +} + +fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! { let pci_config = pcid_handle.config(); let mut name = pci_config.func.name(); @@ -29,62 +32,59 @@ fn main() { log::info!("E1000 {}", pci_config.func.display()); - daemon::Daemon::new(move |daemon| { - let mut irq_file = irq.irq_handle("e1000d"); + let mut irq_file = irq.irq_handle("e1000d"); - let address = unsafe { pcid_handle.map_bar(0) }.ptr.as_ptr() as usize; + let address = unsafe { pcid_handle.map_bar(0) }.ptr.as_ptr() as usize; - let mut scheme = NetworkScheme::new( - move || unsafe { - device::Intel8254x::new(address).expect("e1000d: failed to allocate device") - }, - daemon, - format!("network.{name}"), - ); + let mut scheme = NetworkScheme::new( + move || unsafe { + device::Intel8254x::new(address).expect("e1000d: failed to allocate device") + }, + daemon, + format!("network.{name}"), + ); - user_data! { - enum Source { - Irq, - Scheme, - } + user_data! { + enum Source { + Irq, + Scheme, } + } - let event_queue = - EventQueue::::new().expect("e1000d: failed to create event queue"); + let event_queue = EventQueue::::new().expect("e1000d: failed to create event queue"); - event_queue - .subscribe( - irq_file.as_raw_fd() as usize, - Source::Irq, - event::EventFlags::READ, - ) - .expect("e1000d: failed to subscribe to IRQ fd"); - event_queue - .subscribe( - scheme.event_handle().raw(), - Source::Scheme, - event::EventFlags::READ, - ) - .expect("e1000d: failed to subscribe to scheme fd"); + event_queue + .subscribe( + irq_file.as_raw_fd() as usize, + Source::Irq, + event::EventFlags::READ, + ) + .expect("e1000d: failed to subscribe to IRQ fd"); + event_queue + .subscribe( + scheme.event_handle().raw(), + Source::Scheme, + event::EventFlags::READ, + ) + .expect("e1000d: failed to subscribe to scheme fd"); - libredox::call::setrens(0, 0).expect("e1000d: failed to enter null namespace"); + libredox::call::setrens(0, 0).expect("e1000d: failed to enter null namespace"); - scheme.tick().unwrap(); + scheme.tick().unwrap(); - for event in event_queue.map(|e| e.expect("e1000d: failed to get event")) { - match event.user_data { - Source::Irq => { - let mut irq = [0; 8]; - irq_file.read(&mut irq).unwrap(); - if unsafe { scheme.adapter().irq() } { - irq_file.write(&mut irq).unwrap(); + for event in event_queue.map(|e| e.expect("e1000d: failed to get event")) { + match event.user_data { + Source::Irq => { + let mut irq = [0; 8]; + irq_file.read(&mut irq).unwrap(); + if unsafe { scheme.adapter().irq() } { + irq_file.write(&mut irq).unwrap(); - scheme.tick().expect("e1000d: failed to handle IRQ") - } + scheme.tick().expect("e1000d: failed to handle IRQ") } - Source::Scheme => scheme.tick().expect("e1000d: failed to handle scheme op"), } + Source::Scheme => scheme.tick().expect("e1000d: failed to handle scheme op"), } - unreachable!() - }); + } + unreachable!() } diff --git a/drivers/net/ixgbed/src/main.rs b/drivers/net/ixgbed/src/main.rs index a0431ec920..4a6ce74dcd 100644 --- a/drivers/net/ixgbed/src/main.rs +++ b/drivers/net/ixgbed/src/main.rs @@ -10,7 +10,10 @@ pub mod device; mod ixgbe; fn main() { - let mut pcid_handle = PciFunctionHandle::connect_default(); + pcid_interface::pci_daemon(daemon); +} + +fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! { let pci_config = pcid_handle.config(); let mut name = pci_config.func.name(); @@ -23,66 +26,63 @@ fn main() { println!(" + IXGBE {}", pci_config.func.display()); - daemon::Daemon::new(move |daemon| { - let mut irq_file = irq.irq_handle("ixgbed"); + let mut irq_file = irq.irq_handle("ixgbed"); - let mapped_bar = unsafe { pcid_handle.map_bar(0) }; - let address = mapped_bar.ptr.as_ptr(); - let size = mapped_bar.bar_size; + let mapped_bar = unsafe { pcid_handle.map_bar(0) }; + let address = mapped_bar.ptr.as_ptr(); + let size = mapped_bar.bar_size; - let mut scheme = NetworkScheme::new( - move || { - device::Intel8259x::new(address as usize, size) - .expect("ixgbed: failed to allocate device") - }, - daemon, - format!("network.{name}"), - ); + let mut scheme = NetworkScheme::new( + move || { + device::Intel8259x::new(address as usize, size) + .expect("ixgbed: failed to allocate device") + }, + daemon, + format!("network.{name}"), + ); - user_data! { - enum Source { - Irq, - Scheme, - } + user_data! { + enum Source { + Irq, + Scheme, } + } - let event_queue = - EventQueue::::new().expect("ixgbed: Could not create event queue."); - event_queue - .subscribe( - irq_file.as_raw_fd() as usize, - Source::Irq, - event::EventFlags::READ, - ) - .unwrap(); - event_queue - .subscribe( - scheme.event_handle().raw(), - Source::Scheme, - event::EventFlags::READ, - ) - .unwrap(); + let event_queue = EventQueue::::new().expect("ixgbed: Could not create event queue."); + event_queue + .subscribe( + irq_file.as_raw_fd() as usize, + Source::Irq, + event::EventFlags::READ, + ) + .unwrap(); + event_queue + .subscribe( + scheme.event_handle().raw(), + Source::Scheme, + event::EventFlags::READ, + ) + .unwrap(); - libredox::call::setrens(0, 0).expect("ixgbed: failed to enter null namespace"); + libredox::call::setrens(0, 0).expect("ixgbed: failed to enter null namespace"); - scheme.tick().unwrap(); + scheme.tick().unwrap(); - for event in event_queue.map(|e| e.expect("ixgbed: failed to get next event")) { - match event.user_data { - Source::Irq => { - let mut irq = [0; 8]; - irq_file.read(&mut irq).unwrap(); - if scheme.adapter().irq() { - irq_file.write(&mut irq).unwrap(); + for event in event_queue.map(|e| e.expect("ixgbed: failed to get next event")) { + match event.user_data { + Source::Irq => { + let mut irq = [0; 8]; + irq_file.read(&mut irq).unwrap(); + if scheme.adapter().irq() { + irq_file.write(&mut irq).unwrap(); - scheme.tick().unwrap(); - } - } - Source::Scheme => { scheme.tick().unwrap(); } } + Source::Scheme => { + scheme.tick().unwrap(); + } } - unreachable!() - }); + } + unreachable!() } diff --git a/drivers/net/rtl8139d/src/main.rs b/drivers/net/rtl8139d/src/main.rs index df736ec565..d470e814df 100644 --- a/drivers/net/rtl8139d/src/main.rs +++ b/drivers/net/rtl8139d/src/main.rs @@ -35,9 +35,11 @@ fn map_bar(pcid_handle: &mut PciFunctionHandle) -> *mut u8 { panic!("rtl8139d: failed to find BAR"); } -fn daemon(daemon: daemon::Daemon) -> ! { - let mut pcid_handle = PciFunctionHandle::connect_default(); +fn main() { + pcid_interface::pci_daemon(daemon); +} +fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! { let pci_config = pcid_handle.config(); let mut name = pci_config.func.name(); @@ -111,7 +113,3 @@ fn daemon(daemon: daemon::Daemon) -> ! { } unreachable!() } - -fn main() { - daemon::Daemon::new(daemon); -} diff --git a/drivers/net/rtl8168d/src/main.rs b/drivers/net/rtl8168d/src/main.rs index 11742dd574..1d9963a3ad 100644 --- a/drivers/net/rtl8168d/src/main.rs +++ b/drivers/net/rtl8168d/src/main.rs @@ -35,9 +35,11 @@ fn map_bar(pcid_handle: &mut PciFunctionHandle) -> *mut u8 { panic!("rtl8168d: failed to find BAR"); } -fn daemon(daemon: daemon::Daemon) -> ! { - let mut pcid_handle = PciFunctionHandle::connect_default(); +fn main() { + pcid_interface::pci_daemon(daemon); +} +fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! { let pci_config = pcid_handle.config(); let mut name = pci_config.func.name(); @@ -111,7 +113,3 @@ fn daemon(daemon: daemon::Daemon) -> ! { } unreachable!() } - -fn main() { - daemon::Daemon::new(daemon); -} diff --git a/drivers/net/virtio-netd/src/main.rs b/drivers/net/virtio-netd/src/main.rs index 4b1fa76d70..17d168efdf 100644 --- a/drivers/net/virtio-netd/src/main.rs +++ b/drivers/net/virtio-netd/src/main.rs @@ -26,9 +26,26 @@ pub struct VirtHeader { static_assertions::const_assert_eq!(core::mem::size_of::(), 12); const MAX_BUFFER_LEN: usize = 65535; +fn main() { + pcid_interface::pci_daemon(daemon_runner); +} -fn deamon(daemon: daemon::Daemon) -> Result<(), Box> { - let mut pcid_handle = PciFunctionHandle::connect_default(); +fn daemon_runner(daemon: daemon::Daemon, pcid_handle: PciFunctionHandle) -> ! { + deamon(daemon, pcid_handle).unwrap(); + unreachable!(); +} + +fn deamon( + daemon: daemon::Daemon, + mut pcid_handle: PciFunctionHandle, +) -> Result<(), Box> { + common::setup_logging( + "net", + "pci", + "virtio-netd", + common::output_level(), + common::file_level(), + ); // Double check that we have the right device. // @@ -118,19 +135,3 @@ fn deamon(daemon: daemon::Daemon) -> Result<(), Box> { scheme.tick()?; } } - -fn daemon_runner(daemon: daemon::Daemon) -> ! { - deamon(daemon).unwrap(); - unreachable!(); -} - -pub fn main() { - common::setup_logging( - "net", - "pci", - "virtio-netd", - common::output_level(), - common::file_level(), - ); - daemon::Daemon::new(daemon_runner); -} diff --git a/drivers/pcid/src/driver_interface/mod.rs b/drivers/pcid/src/driver_interface/mod.rs index d1fa8d733d..f7c93b51f8 100644 --- a/drivers/pcid/src/driver_interface/mod.rs +++ b/drivers/pcid/src/driver_interface/mod.rs @@ -6,6 +6,7 @@ use std::ptr::NonNull; use std::{env, io}; use std::{fmt, process}; +use daemon::Daemon; use serde::{de::DeserializeOwned, Deserialize, Serialize}; pub use bar::PciBar; @@ -297,7 +298,7 @@ fn recv(r: &mut File) -> T { } impl PciFunctionHandle { - pub fn connect_default() -> Self { + fn connect_default() -> Self { let channel_fd = match env::var("PCID_CLIENT_CHANNEL") { Ok(channel_fd) => channel_fd, Err(err) => { @@ -471,3 +472,10 @@ impl PciFunctionHandle { } } } + +pub fn pci_daemon !>(f: F) -> ! { + Daemon::new(|daemon| { + let pcid_handle = PciFunctionHandle::connect_default(); + f(daemon, pcid_handle) + }) +} diff --git a/drivers/pcid/src/lib.rs b/drivers/pcid/src/lib.rs index 312a886cf5..e8098a1786 100644 --- a/drivers/pcid/src/lib.rs +++ b/drivers/pcid/src/lib.rs @@ -1,4 +1,6 @@ //! Interface to `pcid`. +#![feature(never_type)] + mod driver_interface; pub use driver_interface::*; diff --git a/drivers/pcid/src/main.rs b/drivers/pcid/src/main.rs index f1d0b471ef..40a68815f2 100644 --- a/drivers/pcid/src/main.rs +++ b/drivers/pcid/src/main.rs @@ -187,6 +187,10 @@ fn enable_function( } fn main() { + daemon::Daemon::new(daemon); +} + +fn daemon(daemon: daemon::Daemon) -> ! { let mut args = pico_args::Arguments::from_env(); let verbosity = (0..).find(|_| !args.contains("-v")).unwrap_or(0); let log_level = match verbosity { @@ -197,10 +201,6 @@ fn main() { common::setup_logging("bus", "pci", "pcid", log_level, log::LevelFilter::Info); - daemon::Daemon::new(move |daemon| main_inner(daemon)); -} - -fn main_inner(daemon: daemon::Daemon) -> ! { let pcie = Pcie::new(); let mut tree = BTreeMap::new(); diff --git a/drivers/storage/ahcid/src/main.rs b/drivers/storage/ahcid/src/main.rs index 4b6a34523f..45415732bf 100644 --- a/drivers/storage/ahcid/src/main.rs +++ b/drivers/storage/ahcid/src/main.rs @@ -14,11 +14,10 @@ use log::{error, info}; pub mod ahci; fn main() { - daemon::Daemon::new(daemon); + pcid_interface::pci_daemon(daemon); } -fn daemon(daemon: daemon::Daemon) -> ! { - let mut pcid_handle = PciFunctionHandle::connect_default(); +fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! { let pci_config = pcid_handle.config(); let mut name = pci_config.func.name(); diff --git a/drivers/storage/ided/src/main.rs b/drivers/storage/ided/src/main.rs index a5c07e331d..e94998a713 100644 --- a/drivers/storage/ided/src/main.rs +++ b/drivers/storage/ided/src/main.rs @@ -18,12 +18,10 @@ use crate::ide::{AtaCommand, AtaDisk, Channel}; pub mod ide; fn main() { - daemon::Daemon::new(daemon); + pcid_interface::pci_daemon(daemon); } -fn daemon(daemon: daemon::Daemon) -> ! { - let pcid_handle = PciFunctionHandle::connect_default(); - +fn daemon(daemon: daemon::Daemon, pcid_handle: PciFunctionHandle) -> ! { let pci_config = pcid_handle.config(); let mut name = pci_config.func.name(); diff --git a/drivers/storage/lived/src/main.rs b/drivers/storage/lived/src/main.rs index 1ba08e2a16..2ca1ff27e5 100644 --- a/drivers/storage/lived/src/main.rs +++ b/drivers/storage/lived/src/main.rs @@ -103,13 +103,18 @@ impl Disk for LiveDisk { } } -fn main() -> anyhow::Result<()> { +fn main() { + daemon::Daemon::new(daemon); +} + +fn daemon(daemon: daemon::Daemon) -> ! { let mut phys = 0; let mut size = 0; // TODO: handle error for line in std::fs::read_to_string("/scheme/sys/env") - .context("failed to read env")? + .context("failed to read env") + .unwrap() .lines() { let mut parts = line.splitn(2, '='); @@ -126,48 +131,47 @@ fn main() -> anyhow::Result<()> { } if phys == 0 || size == 0 { - // No live disk data, no need to say anything or exit with error + // No live disk data, no need to say anything or exit with + daemon.ready(); std::process::exit(0); } - daemon::Daemon::new(move |daemon| { - let event_queue = event::EventQueue::new().unwrap(); + let event_queue = event::EventQueue::new().unwrap(); - event::user_data! { - enum Event { - Scheme, - } - }; - - let mut scheme = DiskScheme::new( - Some(daemon), - "disk.live".to_owned(), - BTreeMap::from([( - 0, - LiveDisk::new(phys, size).unwrap_or_else(|err| { - eprintln!("failed to initialize livedisk scheme: {}", err); - std::process::exit(1) - }), - )]), - &TrivialExecutor, - ); - - libredox::call::setrens(0, 0).expect("nvmed: failed to enter null namespace"); - - event_queue - .subscribe( - scheme.event_handle().raw(), - Event::Scheme, - event::EventFlags::READ, - ) - .unwrap(); - - for event in event_queue { - match event.unwrap().user_data { - Event::Scheme => TrivialExecutor.block_on(scheme.tick()).unwrap(), - } + event::user_data! { + enum Event { + Scheme, } + }; - std::process::exit(0); - }); + let mut scheme = DiskScheme::new( + Some(daemon), + "disk.live".to_owned(), + BTreeMap::from([( + 0, + LiveDisk::new(phys, size).unwrap_or_else(|err| { + eprintln!("failed to initialize livedisk scheme: {}", err); + std::process::exit(1) + }), + )]), + &TrivialExecutor, + ); + + libredox::call::setrens(0, 0).expect("nvmed: failed to enter null namespace"); + + event_queue + .subscribe( + scheme.event_handle().raw(), + Event::Scheme, + event::EventFlags::READ, + ) + .unwrap(); + + for event in event_queue { + match event.unwrap().user_data { + Event::Scheme => TrivialExecutor.block_on(scheme.tick()).unwrap(), + } + } + + std::process::exit(0); } diff --git a/drivers/storage/nvmed/src/main.rs b/drivers/storage/nvmed/src/main.rs index bdf4a8c08f..beb1b68940 100644 --- a/drivers/storage/nvmed/src/main.rs +++ b/drivers/storage/nvmed/src/main.rs @@ -57,10 +57,10 @@ fn time_arm(time_handle: &mut File, secs: i64) -> io::Result<()> { } fn main() { - daemon::Daemon::new(daemon); + pcid_interface::pci_daemon(daemon); } -fn daemon(daemon: daemon::Daemon) -> ! { - let mut pcid_handle = PciFunctionHandle::connect_default(); + +fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! { let pci_config = pcid_handle.config(); let scheme_name = format!("disk.{}-nvme", pci_config.func.name()); diff --git a/drivers/storage/usbscsid/src/main.rs b/drivers/storage/usbscsid/src/main.rs index 118f915ca2..c438c8781f 100644 --- a/drivers/storage/usbscsid/src/main.rs +++ b/drivers/storage/usbscsid/src/main.rs @@ -12,6 +12,9 @@ use crate::protocol::Protocol; use crate::scsi::Scsi; fn main() { + daemon::Daemon::new(daemon); +} +fn daemon(daemon: daemon::Daemon) -> ! { let mut args = env::args().skip(1); const USAGE: &'static str = "usbscsid "; @@ -33,9 +36,6 @@ fn main() { scheme, port, protocol ); - daemon::Daemon::new(move |d| daemon(d, scheme, port, protocol)); -} -fn daemon(daemon: daemon::Daemon, scheme: String, port: PortId, protocol: u8) -> ! { let disk_scheme_name = format!("disk.usb-{scheme}+{port}-scsi"); // TODO: Use eventfds. diff --git a/drivers/storage/virtio-blkd/src/main.rs b/drivers/storage/virtio-blkd/src/main.rs index 414b67d713..d21236b377 100644 --- a/drivers/storage/virtio-blkd/src/main.rs +++ b/drivers/storage/virtio-blkd/src/main.rs @@ -30,17 +30,6 @@ pub enum Error { SyscallError(syscall::Error), } -pub fn main() { - common::setup_logging( - "disk", - "pci", - "virtio-blkd", - common::output_level(), - common::file_level(), - ); - daemon::Daemon::new(daemon_runner); -} - #[repr(C)] pub struct BlockGeometry { pub cylinders: VolatileCell, @@ -109,8 +98,23 @@ pub struct BlockVirtRequest { const_assert_eq!(core::mem::size_of::(), 16); -fn daemon(daemon: daemon::Daemon) -> anyhow::Result<()> { - let mut pcid_handle = PciFunctionHandle::connect_default(); +fn main() { + pcid_interface::pci_daemon(daemon_runner); +} + +fn daemon_runner(redox_daemon: daemon::Daemon, pcid_handle: PciFunctionHandle) -> ! { + daemon(redox_daemon, pcid_handle).unwrap(); + unreachable!(); +} + +fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> anyhow::Result<()> { + common::setup_logging( + "disk", + "pci", + "virtio-blkd", + common::output_level(), + common::file_level(), + ); // Double check that we have the right device. // @@ -176,8 +180,3 @@ fn daemon(daemon: daemon::Daemon) -> anyhow::Result<()> { Ok(()) } - -fn daemon_runner(redox_daemon: daemon::Daemon) -> ! { - daemon(redox_daemon).unwrap(); - unreachable!(); -} diff --git a/drivers/usb/xhcid/src/main.rs b/drivers/usb/xhcid/src/main.rs index 0a20f84d71..613bd1c7be 100644 --- a/drivers/usb/xhcid/src/main.rs +++ b/drivers/usb/xhcid/src/main.rs @@ -115,10 +115,6 @@ fn get_int_method(pcid_handle: &mut PciFunctionHandle) -> (Option, Interru } } -fn main() { - daemon::Daemon::new(daemon); -} - //TODO: cleanup CSZ support fn daemon_with_context_size( daemon: daemon::Daemon, @@ -185,8 +181,11 @@ fn daemon_with_context_size( } } -fn daemon(daemon: daemon::Daemon) -> ! { - let mut pcid_handle = PciFunctionHandle::connect_default(); +fn main() { + pcid_interface::pci_daemon(daemon); +} + +fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! { let address = unsafe { pcid_handle.map_bar(0) }.ptr.as_ptr() as usize; let cap = unsafe { &mut *(address as *mut xhci::CapabilityRegs) }; if cap.csz() { diff --git a/drivers/vboxd/src/main.rs b/drivers/vboxd/src/main.rs index 59715708ca..710f6afa06 100644 --- a/drivers/vboxd/src/main.rs +++ b/drivers/vboxd/src/main.rs @@ -191,7 +191,10 @@ impl VboxGuestInfo { } fn main() { - let mut pcid_handle = PciFunctionHandle::connect_default(); + pcid_interface::pci_daemon(daemon); +} + +fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! { let pci_config = pcid_handle.config(); let mut name = pci_config.func.name(); @@ -206,129 +209,124 @@ fn main() { println!(" + VirtualBox {}", pci_config.func.display()); - // Daemonize - daemon::Daemon::new(move |daemon| { - common::acquire_port_io_rights().expect("vboxd: failed to get I/O permission"); + common::acquire_port_io_rights().expect("vboxd: failed to get I/O permission"); - let mut width = 0; - let mut height = 0; - let mut display_opt = File::open("inputd:producer").ok(); - if let Some(ref display) = display_opt { - let mut buf: [u8; 4096] = [0; 4096]; - if let Ok(count) = libredox::call::fpath(display.as_raw_fd() as usize, &mut buf) { - let path = unsafe { String::from_utf8_unchecked(Vec::from(&buf[..count])) }; - let res = path.split(":").nth(1).unwrap_or(""); - width = res - .split("/") - .nth(1) - .unwrap_or("") - .parse::() - .unwrap_or(0); - height = res - .split("/") - .nth(2) - .unwrap_or("") - .parse::() - .unwrap_or(0); + let mut width = 0; + let mut height = 0; + let mut display_opt = File::open("inputd:producer").ok(); + if let Some(ref display) = display_opt { + let mut buf: [u8; 4096] = [0; 4096]; + if let Ok(count) = libredox::call::fpath(display.as_raw_fd() as usize, &mut buf) { + let path = unsafe { String::from_utf8_unchecked(Vec::from(&buf[..count])) }; + let res = path.split(":").nth(1).unwrap_or(""); + width = res + .split("/") + .nth(1) + .unwrap_or("") + .parse::() + .unwrap_or(0); + height = res + .split("/") + .nth(2) + .unwrap_or("") + .parse::() + .unwrap_or(0); + } + } + + let mut irq_file = irq.irq_handle("vboxd"); + + let mut port = Pio::::new(bar0 as u16); + let address = unsafe { pcid_handle.map_bar(1) }.ptr.as_ptr(); + { + let vmmdev = unsafe { &mut *(address as *mut VboxVmmDev) }; + + let mut guest_info = VboxGuestInfo::new().expect("vboxd: failed to map GuestInfo"); + guest_info.version.write(VBOX_VMMDEV_VERSION); + guest_info.ostype.write(0x100); + port.write(guest_info.physical() as u32); + + let mut guest_caps = VboxGuestCaps::new().expect("vboxd: failed to map GuestCaps"); + guest_caps.caps.write(1 << 2); + port.write(guest_caps.physical() as u32); + + let mut set_mouse = VboxSetMouse::new().expect("vboxd: failed to map SetMouse"); + set_mouse.features.write(1 << 4 | 1); + port.write(set_mouse.physical() as u32); + + vmmdev + .guest_events + .write(VBOX_EVENT_DISPLAY | VBOX_EVENT_MOUSE); + + user_data! { + enum Source { + Irq, } } - let mut irq_file = irq.irq_handle("vboxd"); + let event_queue = + EventQueue::::new().expect("vboxd: Could not create event queue."); + event_queue + .subscribe( + irq_file.as_raw_fd() as usize, + Source::Irq, + event::EventFlags::READ, + ) + .unwrap(); - let mut port = Pio::::new(bar0 as u16); - let address = unsafe { pcid_handle.map_bar(1) }.ptr.as_ptr(); + daemon.ready(); + + libredox::call::setrens(0, 0).expect("vboxd: failed to enter null namespace"); + + let mut bga = Bga::new(); + let get_mouse = VboxGetMouse::new().expect("vboxd: failed to map GetMouse"); + let display_change = VboxDisplayChange::new().expect("vboxd: failed to map DisplayChange"); + let ack_events = VboxAckEvents::new().expect("vboxd: failed to map AckEvents"); + + for Source::Irq in iter::once(Source::Irq) + .chain(event_queue.map(|e| e.expect("vboxd: failed to get next event").user_data)) { - let vmmdev = unsafe { &mut *(address as *mut VboxVmmDev) }; + let mut irq = [0; 8]; + if irq_file.read(&mut irq).unwrap() >= irq.len() { + let host_events = vmmdev.host_events.read(); + if host_events != 0 { + port.write(ack_events.physical() as u32); + irq_file.write(&irq).unwrap(); - let mut guest_info = VboxGuestInfo::new().expect("vboxd: failed to map GuestInfo"); - guest_info.version.write(VBOX_VMMDEV_VERSION); - guest_info.ostype.write(0x100); - port.write(guest_info.physical() as u32); - - let mut guest_caps = VboxGuestCaps::new().expect("vboxd: failed to map GuestCaps"); - guest_caps.caps.write(1 << 2); - port.write(guest_caps.physical() as u32); - - let mut set_mouse = VboxSetMouse::new().expect("vboxd: failed to map SetMouse"); - set_mouse.features.write(1 << 4 | 1); - port.write(set_mouse.physical() as u32); - - vmmdev - .guest_events - .write(VBOX_EVENT_DISPLAY | VBOX_EVENT_MOUSE); - - user_data! { - enum Source { - Irq, - } - } - - let event_queue = - EventQueue::::new().expect("vboxd: Could not create event queue."); - event_queue - .subscribe( - irq_file.as_raw_fd() as usize, - Source::Irq, - event::EventFlags::READ, - ) - .unwrap(); - - daemon.ready(); - - libredox::call::setrens(0, 0).expect("vboxd: failed to enter null namespace"); - - let mut bga = Bga::new(); - let get_mouse = VboxGetMouse::new().expect("vboxd: failed to map GetMouse"); - let display_change = - VboxDisplayChange::new().expect("vboxd: failed to map DisplayChange"); - let ack_events = VboxAckEvents::new().expect("vboxd: failed to map AckEvents"); - - for Source::Irq in iter::once(Source::Irq) - .chain(event_queue.map(|e| e.expect("vboxd: failed to get next event").user_data)) - { - let mut irq = [0; 8]; - if irq_file.read(&mut irq).unwrap() >= irq.len() { - let host_events = vmmdev.host_events.read(); - if host_events != 0 { - port.write(ack_events.physical() as u32); - irq_file.write(&irq).unwrap(); - - if host_events & VBOX_EVENT_DISPLAY == VBOX_EVENT_DISPLAY { - port.write(display_change.physical() as u32); - if let Some(ref mut display) = display_opt { - let new_width = display_change.xres.read(); - let new_height = display_change.yres.read(); - if width != new_width || height != new_height { - width = new_width; - height = new_height; - println!("Display {}, {}", width, height); - bga.set_size(width as u16, height as u16); - let _ = display.write( - &orbclient::ResizeEvent { width, height }.to_event(), - ); - } + if host_events & VBOX_EVENT_DISPLAY == VBOX_EVENT_DISPLAY { + port.write(display_change.physical() as u32); + if let Some(ref mut display) = display_opt { + let new_width = display_change.xres.read(); + let new_height = display_change.yres.read(); + if width != new_width || height != new_height { + width = new_width; + height = new_height; + println!("Display {}, {}", width, height); + bga.set_size(width as u16, height as u16); + let _ = display + .write(&orbclient::ResizeEvent { width, height }.to_event()); } } + } - if host_events & VBOX_EVENT_MOUSE == VBOX_EVENT_MOUSE { - port.write(get_mouse.physical() as u32); - if let Some(ref mut display) = display_opt { - let x = get_mouse.x.read() * width / 0x10000; - let y = get_mouse.y.read() * height / 0x10000; - let _ = display.write( - &orbclient::MouseEvent { - x: x as i32, - y: y as i32, - } - .to_event(), - ); - } + if host_events & VBOX_EVENT_MOUSE == VBOX_EVENT_MOUSE { + port.write(get_mouse.physical() as u32); + if let Some(ref mut display) = display_opt { + let x = get_mouse.x.read() * width / 0x10000; + let y = get_mouse.y.read() * height / 0x10000; + let _ = display.write( + &orbclient::MouseEvent { + x: x as i32, + y: y as i32, + } + .to_event(), + ); } } } } } + } - std::process::exit(0); - }); + std::process::exit(0); } diff --git a/init.rc b/init.rc index 6fb3094f77..dc716b7582 100644 --- a/init.rc +++ b/init.rc @@ -1,6 +1,6 @@ # Various daemons that relibc needs to function as well as a bunch of env vars # that should be set for every program. -export PATH /bin +export PATH /scheme/initfs/bin export RUST_BACKTRACE 1 rtcd nulld @@ -34,7 +34,6 @@ redoxfs --uuid $REDOXFS_UUID file $REDOXFS_BLOCK unset REDOXFS_UUID REDOXFS_BLOCK REDOXFS_PASSWORD_ADDR REDOXFS_PASSWORD_SIZE # Exit initfs -set-default-scheme file cd / export PATH /usr/bin run.d /usr/lib/init.d /etc/init.d diff --git a/init/Cargo.toml b/init/Cargo.toml index 1c2eee4630..8362f047a1 100644 --- a/init/Cargo.toml +++ b/init/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "init" version = "0.1.0" -edition = "2021" +edition = "2024" license = "MIT" [dependencies] diff --git a/init/src/main.rs b/init/src/main.rs index a20e489f32..78b6dc4094 100644 --- a/init/src/main.rs +++ b/init/src/main.rs @@ -1,33 +1,12 @@ use std::collections::BTreeMap; -use std::env; -use std::ffi::CString; -use std::fs::{read_dir, File}; -use std::io::{BufRead, BufReader, Result}; +use std::fs::read_dir; +use std::io::Result; use std::path::Path; use std::process::Command; - -use libredox::error::Error as OsError; +use std::{env, fs}; use libredox::flag::{O_RDONLY, O_WRONLY}; -fn set_default_scheme(scheme: &str) -> std::result::Result<(), OsError> { - use std::ffi::{c_char, c_int}; - - extern "C" { - fn set_default_scheme(scheme: *const c_char) -> c_int; - } - - let cstr = - CString::new(scheme.as_bytes()).expect(&format!("init: invalid default scheme {}", scheme)); - - let res = unsafe { set_default_scheme(cstr.as_ptr()) }; - - match res { - 0 => Ok(()), - error_code => Err(OsError::new(error_code)), - } -} - fn switch_stdio(stdio: &str) -> Result<()> { let stdin = libredox::Fd::open(stdio, O_RDONLY, 0)?; let stdout = libredox::Fd::open(stdio, O_WRONLY, 0)?; @@ -41,194 +20,170 @@ fn switch_stdio(stdio: &str) -> Result<()> { } pub fn run(file: &Path) -> Result<()> { - let file = File::open(file)?; - let reader = BufReader::new(file); - for line_res in reader.lines() { - let line_raw = line_res?; - let line = line_raw.trim(); - if !line.is_empty() && !line.starts_with('#') { - let mut args = line.split(' ').map(|arg| { - if arg.starts_with('$') { - env::var(&arg[1..]).unwrap_or(String::new()) - } else { - arg.to_string() - } - }); - - if let Some(cmd) = args.next() { - match cmd.as_str() { - "cd" => { - if let Some(dir) = args.next() { - if let Err(err) = env::set_current_dir(&dir) { - println!("init: failed to cd to '{}': {}", dir, err); - } - } else { - println!("init: failed to cd: no argument"); - } - } - "set-default-scheme" => { - if let Some(scheme) = args.next() { - if let Err(err) = set_default_scheme(&scheme) { - println!( - "init: failed to set default scheme to '{}': {}", - scheme, err - ); - } - } else { - println!("init: failed to set default scheme: no argument"); - } - } - "echo" => { - if let Some(arg) = args.next() { - print!("{}", arg); - } - for arg in args { - print!(" {}", arg); - } - print!("\n"); - } - "export" => { - if let Some(var) = args.next() { - let mut value = String::new(); - if let Some(arg) = args.next() { - value.push_str(&arg); - } - for arg in args { - value.push(' '); - value.push_str(&arg); - } - env::set_var(var, value); - } else { - println!("init: failed to export: no argument"); - } - } - "run" => { - if let Some(new_file) = args.next() { - if let Err(err) = run(&Path::new(&new_file)) { - println!("init: failed to run '{}': {}", new_file, err); - } - } else { - println!("init: failed to run: no argument"); - } - } - "run.d" => { - // This must be a BTreeMap to iterate in sorted order. - let mut entries = BTreeMap::new(); - let mut missing_arg = true; - - for new_dir in args { - if !Path::new(&new_dir).exists() { - // Skip non-existent dirs - continue; - } - missing_arg = false; - - match read_dir(&new_dir) { - Ok(list) => { - for entry_res in list { - match entry_res { - Ok(entry) => { - // This intentionally overwrites older entries with - // the same filename to allow overriding entries in - // one search dir with those in a later search dir. - entries.insert(entry.file_name(), entry.path()); - } - Err(err) => { - println!( - "init: failed to run.d: '{}': {}", - new_dir, err - ); - } - } - } - } - Err(err) => { - println!("init: failed to run.d: '{}': {}", new_dir, err); - } - } - } - - if missing_arg { - println!( - "init: failed to run.d: no argument or all dirs are non-existent" - ); - } else { - // This takes advantage of BTreeMap iterating in sorted order. - for (_, entry_path) in entries { - if let Err(err) = run(&entry_path) { - println!( - "init: failed to run '{}': {}", - entry_path.display(), - err - ); - } - } - } - } - "stdio" => { - if let Some(stdio) = args.next() { - if let Err(err) = switch_stdio(&stdio) { - println!("init: failed to switch stdio to '{}': {}", stdio, err); - } - } else { - println!("init: failed to set stdio: no argument"); - } - } - "unset" => { - for arg in args { - env::remove_var(&arg); - } - } - "nowait" => { - if let Some(cmd) = args.next() { - let mut command = Command::new(cmd); - - for arg in args { - command.arg(arg); - } - - match command.spawn() { - Ok(_child) => {} - Err(err) => println!("init: failed to execute '{}': {}", line, err), - } - } else { - println!("init: failed to run nowait: no argument"); - } - } - _ => { - let mut command = Command::new(cmd.clone()); - for arg in args { - command.arg(arg); - } - - match command.spawn() { - Ok(mut child) => match child.wait() { - Ok(exit_status) => { - if !exit_status.success() { - println!("{cmd} failed with {exit_status}"); - } - } - Err(err) => { - println!("init: failed to wait for '{}': {}", line, err) - } - }, - Err(err) => println!("init: failed to execute '{}': {}", line, err), - } - } - } - } - } + for line in fs::read_to_string(file)?.lines() { + run_command(line); } Ok(()) } -pub fn main() { - if let Err(err) = set_default_scheme("initfs") { - println!("init: failed to set default scheme: {}", err); +fn run_command(line_raw: &str) { + let line = line_raw.trim(); + if line.is_empty() || line.starts_with('#') { + return; } + let mut args = line.split(' ').map(|arg| { + if arg.starts_with('$') { + env::var(&arg[1..]).unwrap_or(String::new()) + } else { + arg.to_string() + } + }); - let config = "/etc/init.rc"; + if let Some(cmd) = args.next() { + match cmd.as_str() { + "cd" => { + let Some(dir) = args.next() else { + println!("init: failed to cd: no argument"); + return; + }; + if let Err(err) = env::set_current_dir(&dir) { + println!("init: failed to cd to '{}': {}", dir, err); + } + } + "echo" => { + println!("{}", args.collect::>().join(" ")); + } + "export" => { + let Some(var) = args.next() else { + println!("init: failed to export: no argument"); + return; + }; + let mut value = String::new(); + if let Some(arg) = args.next() { + value.push_str(&arg); + } + for arg in args { + value.push(' '); + value.push_str(&arg); + } + unsafe { env::set_var(var, value) }; + } + "run" => { + let Some(new_file) = args.next() else { + println!("init: failed to run: no argument"); + return; + }; + if let Err(err) = run(&Path::new(&new_file)) { + println!("init: failed to run '{}': {}", new_file, err); + } + } + "run.d" => { + // This must be a BTreeMap to iterate in sorted order. + let mut entries = BTreeMap::new(); + let mut missing_arg = true; + + for new_dir in args { + if !Path::new(&new_dir).exists() { + // Skip non-existent dirs + continue; + } + missing_arg = false; + + let list = match read_dir(&new_dir) { + Ok(list) => list, + Err(err) => { + println!("init: failed to run.d: '{}': {}", new_dir, err); + continue; + } + }; + for entry_res in list { + match entry_res { + Ok(entry) => { + // This intentionally overwrites older entries with + // the same filename to allow overriding entries in + // one search dir with those in a later search dir. + entries.insert(entry.file_name(), entry.path()); + } + Err(err) => { + println!("init: failed to run.d: '{}': {}", new_dir, err); + } + } + } + } + + if missing_arg { + println!("init: failed to run.d: no argument or all dirs are non-existent"); + return; + } + + // This takes advantage of BTreeMap iterating in sorted order. + for (_, entry_path) in entries { + if let Err(err) = run(&entry_path) { + println!("init: failed to run '{}': {}", entry_path.display(), err); + } + } + } + "stdio" => { + let Some(stdio) = args.next() else { + println!("init: failed to set stdio: no argument"); + return; + }; + if let Err(err) = switch_stdio(&stdio) { + println!("init: failed to switch stdio to '{}': {}", stdio, err); + } + } + "unset" => { + for arg in args { + unsafe { env::remove_var(&arg) }; + } + } + "nowait" => { + let Some(cmd) = args.next() else { + println!("init: failed to run nowait: no argument"); + return; + }; + let mut command = Command::new(cmd); + + for arg in args { + command.arg(arg); + } + + match command.spawn() { + Ok(_child) => {} + Err(err) => println!("init: failed to execute '{}': {}", line, err), + } + } + _ => { + let mut command = Command::new(cmd.clone()); + for arg in args { + command.arg(arg); + } + + let mut child = match command.spawn() { + Ok(child) => child, + Err(err) => { + println!("init: failed to execute '{}': {}", line, err); + return; + } + }; + match child.wait() { + Ok(exit_status) => { + if !exit_status.success() { + println!("{cmd} failed with {exit_status}"); + } + } + Err(err) => { + println!("init: failed to wait for '{}': {}", line, err) + } + } + } + } + } +} + +pub fn main() { + let config = "/scheme/initfs/etc/init.rc"; if let Err(err) = run(&Path::new(config)) { println!("init: failed to run {}: {}", config, err); } diff --git a/init_drivers.rc b/init_drivers.rc index 586b45ac87..4ccdf61475 100644 --- a/init_drivers.rc +++ b/init_drivers.rc @@ -1,3 +1,3 @@ ps2d us hwd -pcid-spawner /etc/pcid/initfs.toml +pcid-spawner /scheme/initfs/etc/pcid/initfs.toml diff --git a/ipcd/Cargo.toml b/ipcd/Cargo.toml index 594b6ac889..53586a144a 100644 --- a/ipcd/Cargo.toml +++ b/ipcd/Cargo.toml @@ -8,8 +8,10 @@ libredox = { version = "0.1.8", features = ["call"]} daemon = { path = "../daemon" } redox_syscall = "0.5.17" redox-scheme = "0.8.0" -redox-rt = { git = "https://gitlab.redox-os.org/redox-os/relibc.git", default-features = false } redox_event = "0.4.0" anyhow = "1.0.97" libc = "0.2" rand = { version = "0.8", features = ["small_rng"] } + +[target.'cfg(target_os = "redox")'.dependencies] +redox-rt = { git = "https://gitlab.redox-os.org/redox-os/relibc.git", default-features = false } diff --git a/ipcd/src/main.rs b/ipcd/src/main.rs index 91d67ab68d..76797de798 100644 --- a/ipcd/src/main.rs +++ b/ipcd/src/main.rs @@ -14,16 +14,18 @@ use self::uds::dgram::UdsDgramScheme; use self::uds::stream::UdsStreamScheme; fn main() { - 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); - } + daemon::Daemon::new(daemon_runner); +} + +fn daemon_runner(daemon: daemon::Daemon) -> ! { + // TODO: Better error handling + match inner(daemon) { + Ok(()) => std::process::exit(0), + Err(error) => { + println!("ipcd failed: {error}"); + std::process::exit(1); } - }); + } } fn inner(daemon: daemon::Daemon) -> anyhow::Result<()> { diff --git a/ipcd/src/uds/dgram.rs b/ipcd/src/uds/dgram.rs index 57cd811ccb..ef5b9f53a6 100644 --- a/ipcd/src/uds/dgram.rs +++ b/ipcd/src/uds/dgram.rs @@ -737,9 +737,9 @@ impl<'sock> SchemeSync for UdsDgramScheme<'sock> { } } - fn fevent(&mut self, id: usize, flags: EventFlags, ctx: &CallerCtx) -> Result { + fn fevent(&mut self, id: usize, flags: EventFlags, _ctx: &CallerCtx) -> Result { let socket_rc = self.get_socket(id)?; - let mut socket = socket_rc.borrow_mut(); + let socket = socket_rc.borrow_mut(); let mut ready = EventFlags::empty(); if flags.contains(EVENT_READ) && !socket.messages.is_empty() { @@ -752,7 +752,7 @@ impl<'sock> SchemeSync for UdsDgramScheme<'sock> { Ok(ready) } - fn fstat(&mut self, id: usize, stat: &mut Stat, ctx: &CallerCtx) -> Result<()> { + fn fstat(&mut self, id: usize, stat: &mut Stat, _ctx: &CallerCtx) -> Result<()> { self.get_socket(id)?; *stat = Stat { diff --git a/ipcd/src/uds/stream.rs b/ipcd/src/uds/stream.rs index 3f41638446..8b084b12a1 100644 --- a/ipcd/src/uds/stream.rs +++ b/ipcd/src/uds/stream.rs @@ -16,7 +16,7 @@ use std::{ cell::RefCell, cmp, collections::{HashMap, HashSet, VecDeque}, - mem, ptr, + mem, rc::Rc, slice, }; @@ -383,7 +383,7 @@ impl<'sock> UdsStreamScheme<'sock> { }) } - fn post_fevent(&self, id: usize, mut flags: EventFlags) -> Result<()> { + fn post_fevent(&self, id: usize, flags: EventFlags) -> Result<()> { /*TODO: filter out unnecessary flags? if let Ok(socket_rc) = self.get_socket(id) { let socket = socket_rc.borrow(); @@ -1324,13 +1324,13 @@ impl<'sock> SchemeSync for UdsStreamScheme<'sock> { } } - fn fevent(&mut self, id: usize, flags: EventFlags, ctx: &CallerCtx) -> Result { + fn fevent(&mut self, id: usize, flags: EventFlags, _ctx: &CallerCtx) -> Result { let socket_rc = self.get_socket(id)?; let socket = socket_rc.borrow(); Ok(socket.events() & flags) } - fn fstat(&mut self, id: usize, stat: &mut Stat, ctx: &CallerCtx) -> Result<()> { + fn fstat(&mut self, id: usize, stat: &mut Stat, _ctx: &CallerCtx) -> Result<()> { self.get_socket(id)?; *stat = Stat { diff --git a/netstack/src/main.rs b/netstack/src/main.rs index 186f8d3f02..cf77bd430f 100644 --- a/netstack/src/main.rs +++ b/netstack/src/main.rs @@ -164,13 +164,15 @@ fn run(daemon: daemon::Daemon) -> Result<()> { } fn main() { - daemon::Daemon::new(move |daemon| { - logger::init_logger("smolnetd"); - - if let Err(err) = run(daemon) { - error!("smoltcpd: {}", err); - process::exit(1); - } - process::exit(0); - }); + daemon::Daemon::new(daemon_runner); +} + +fn daemon_runner(daemon: daemon::Daemon) -> ! { + logger::init_logger("smolnetd"); + + if let Err(err) = run(daemon) { + error!("smoltcpd: {}", err); + process::exit(1); + } + process::exit(0); } diff --git a/ptyd/src/main.rs b/ptyd/src/main.rs index 8e38a2de01..335f2ff856 100644 --- a/ptyd/src/main.rs +++ b/ptyd/src/main.rs @@ -19,71 +19,72 @@ mod winsize; use scheme::PtyScheme; fn main() { - daemon::Daemon::new(move |daemon| { - user_data! { - enum EventSource { - Socket, - Time, + daemon::Daemon::new(daemon); +} + +fn daemon(daemon: daemon::Daemon) -> ! { + user_data! { + enum EventSource { + Socket, + Time, + } + } + + let event_queue = EventQueue::::new().expect("pty: failed to open event:"); + + let time_path = format!("/scheme/time/{}", flag::CLOCK_MONOTONIC); + let mut time_file = + Fd::open(&time_path, flag::O_NONBLOCK, 0).expect("pty: failed to open time:"); + + let socket = redox_scheme::Socket::nonblock("pty").expect("pty: failed to create pty scheme"); + + libredox::call::setrens(0, 0).expect("ptyd: failed to enter null namespace"); + + event_queue + .subscribe(socket.inner().raw(), EventSource::Socket, EventFlags::READ) + .expect("pty: failed to watch events on pty:"); + event_queue + .subscribe(time_file.raw(), EventSource::Time, EventFlags::READ) + .expect("pty: failed to watch events on time:"); + + daemon.ready(); + + //TODO: do not set timeout if not necessary + timeout(&mut time_file).expect("pty: failed to set timeout"); + + let mut scheme = PtyScheme::new(); + let mut todo = Vec::new(); + let mut timeout_count = 0u64; + + scan_requests(&socket, &mut scheme, &mut todo).expect("pty: could not scan requests"); + do_todos(&socket, &mut scheme, &mut todo); + issue_events(&socket, &mut scheme); + + for event_res in event_queue { + let event = event_res.expect("pty: failed to read from event queue"); + + match event.user_data { + EventSource::Socket => { + if scan_requests(&socket, &mut scheme, &mut todo).is_err() { + break; + } + } + EventSource::Time => { + timeout(&mut time_file).expect("pty: failed to set timeout"); + + timeout_count = timeout_count.wrapping_add(1); + + for (_id, handle) in scheme.handles.iter_mut() { + handle.timeout(timeout_count); + } } } - let event_queue = EventQueue::::new().expect("pty: failed to open event:"); - - let time_path = format!("/scheme/time/{}", flag::CLOCK_MONOTONIC); - let mut time_file = - Fd::open(&time_path, flag::O_NONBLOCK, 0).expect("pty: failed to open time:"); - - let socket = - redox_scheme::Socket::nonblock("pty").expect("pty: failed to create pty scheme"); - - libredox::call::setrens(0, 0).expect("ptyd: failed to enter null namespace"); - - event_queue - .subscribe(socket.inner().raw(), EventSource::Socket, EventFlags::READ) - .expect("pty: failed to watch events on pty:"); - event_queue - .subscribe(time_file.raw(), EventSource::Time, EventFlags::READ) - .expect("pty: failed to watch events on time:"); - - daemon.ready(); - - //TODO: do not set timeout if not necessary - timeout(&mut time_file).expect("pty: failed to set timeout"); - - let mut scheme = PtyScheme::new(); - let mut todo = Vec::new(); - let mut timeout_count = 0u64; - - scan_requests(&socket, &mut scheme, &mut todo).expect("pty: could not scan requests"); do_todos(&socket, &mut scheme, &mut todo); issue_events(&socket, &mut scheme); + } - for event_res in event_queue { - let event = event_res.expect("pty: failed to read from event queue"); - - match event.user_data { - EventSource::Socket => { - if scan_requests(&socket, &mut scheme, &mut todo).is_err() { - break; - } - } - EventSource::Time => { - timeout(&mut time_file).expect("pty: failed to set timeout"); - - timeout_count = timeout_count.wrapping_add(1); - - for (_id, handle) in scheme.handles.iter_mut() { - handle.timeout(timeout_count); - } - } - } - - do_todos(&socket, &mut scheme, &mut todo); - issue_events(&socket, &mut scheme); - } - - std::process::exit(0); - }); + std::process::exit(0); } struct Todo { diff --git a/ramfs/src/main.rs b/ramfs/src/main.rs index ccd2c61f91..45fb3bcd36 100644 --- a/ramfs/src/main.rs +++ b/ramfs/src/main.rs @@ -8,40 +8,42 @@ use redox_scheme::{RequestKind, SignalBehavior}; use self::scheme::Scheme; fn main() { + daemon::Daemon::new(daemon); +} + +fn daemon(daemon: daemon::Daemon) -> ! { let scheme_name = env::args().nth(1).expect("Usage:\n\tramfs SCHEME_NAME"); - daemon::Daemon::new(move |daemon| { - let socket = - redox_scheme::Socket::create(&scheme_name).expect("ramfs: failed to create socket"); + let socket = + redox_scheme::Socket::create(&scheme_name).expect("ramfs: failed to create socket"); - let mut scheme = Scheme::new(scheme_name).expect("ramfs: failed to initialize scheme"); + let mut scheme = Scheme::new(scheme_name).expect("ramfs: failed to initialize scheme"); - libredox::call::setrens(0, 0).expect("ramfs: failed to enter null namespace"); + libredox::call::setrens(0, 0).expect("ramfs: failed to enter null namespace"); - daemon.ready(); + daemon.ready(); - loop { - let Some(request) = socket - .next_request(SignalBehavior::Restart) - .expect("ramfs: failed to get next scheme request") - else { - break; - }; - match request.kind() { - RequestKind::Call(call) => { - let response = call.handle_sync(&mut scheme); + loop { + let Some(request) = socket + .next_request(SignalBehavior::Restart) + .expect("ramfs: failed to get next scheme request") + else { + break; + }; + match request.kind() { + RequestKind::Call(call) => { + let response = call.handle_sync(&mut scheme); - socket - .write_responses(&[response], SignalBehavior::Restart) - .expect("ramfs: failed to write next scheme response"); - } - RequestKind::OnClose { id } => { - scheme.on_close(id); - } - _ => (), + socket + .write_responses(&[response], SignalBehavior::Restart) + .expect("ramfs: failed to write next scheme response"); } + RequestKind::OnClose { id } => { + scheme.on_close(id); + } + _ => (), } + } - process::exit(0); - }); + process::exit(0); } diff --git a/zerod/src/main.rs b/zerod/src/main.rs index c500775e31..f34ec93bc3 100644 --- a/zerod/src/main.rs +++ b/zerod/src/main.rs @@ -10,41 +10,43 @@ enum Ty { } fn main() { + daemon::Daemon::new(daemon); +} + +fn daemon(daemon: daemon::Daemon) -> ! { let ty = match &*std::env::args().next().unwrap() { "nulld" => Ty::Null, "zerod" => Ty::Zero, _ => panic!("needs to be called as either nulld or zerod"), }; - daemon::Daemon::new(move |daemon| { - let name = match ty { - Ty::Null => "null", - Ty::Zero => "zero", + let name = match ty { + Ty::Null => "null", + Ty::Zero => "zero", + }; + let socket = Socket::::create(name).expect("zerod: failed to create zero scheme"); + let mut zero_scheme = ZeroScheme(ty); + + libredox::call::setrens(0, 0).expect("zerod: failed to enter null namespace"); + + daemon.ready(); + + loop { + let Some(request) = socket + .next_request(SignalBehavior::Restart) + .expect("zerod: failed to read events from zero scheme") + else { + std::process::exit(0); }; - let socket = Socket::::create(name).expect("zerod: failed to create zero scheme"); - let mut zero_scheme = ZeroScheme(ty); + match request.kind() { + RequestKind::Call(request) => { + let response = request.handle_scheme_mut(&mut zero_scheme); - libredox::call::setrens(0, 0).expect("zerod: failed to enter null namespace"); - - daemon.ready(); - - loop { - let Some(request) = socket - .next_request(SignalBehavior::Restart) - .expect("zerod: failed to read events from zero scheme") - else { - std::process::exit(0); - }; - match request.kind() { - RequestKind::Call(request) => { - let response = request.handle_scheme_mut(&mut zero_scheme); - - socket - .write_responses(&[response], SignalBehavior::Restart) - .expect("zerod: failed to write responses to zero scheme"); - } - _ => (), + socket + .write_responses(&[response], SignalBehavior::Restart) + .expect("zerod: failed to write responses to zero scheme"); } + _ => (), } - }); + } }