Merge branch 'daemon_improvements2' into 'main'
Various improvements to the way daemons work See merge request redox-os/base!48
This commit is contained in:
+6
-2
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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::<Source>::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::<Source>::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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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::<Source>::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::<Source>::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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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! {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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<FrameBuffer>) -> ! {
|
||||
let mut inputd_display_handle = DisplayHandle::new_early("vesa").unwrap();
|
||||
|
||||
let mut scheme = GraphicsScheme::new(FbAdapter { framebuffers }, "display.vesa".to_owned());
|
||||
|
||||
@@ -430,8 +430,23 @@ impl MoveCursor {
|
||||
|
||||
static DEVICE: spin::Once<virtio_core::Device> = 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);
|
||||
}
|
||||
|
||||
@@ -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::<Source>::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::<Source>::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);
|
||||
}
|
||||
|
||||
@@ -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::<Source>::new().expect("e1000d: failed to create event queue");
|
||||
let event_queue = EventQueue::<Source>::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!()
|
||||
}
|
||||
|
||||
@@ -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::<Source>::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::<Source>::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!()
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -26,9 +26,26 @@ pub struct VirtHeader {
|
||||
static_assertions::const_assert_eq!(core::mem::size_of::<VirtHeader>(), 12);
|
||||
|
||||
const MAX_BUFFER_LEN: usize = 65535;
|
||||
fn main() {
|
||||
pcid_interface::pci_daemon(daemon_runner);
|
||||
}
|
||||
|
||||
fn deamon(daemon: daemon::Daemon) -> Result<(), Box<dyn std::error::Error>> {
|
||||
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<dyn std::error::Error>> {
|
||||
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<dyn std::error::Error>> {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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<T: DeserializeOwned>(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: FnOnce(Daemon, PciFunctionHandle) -> !>(f: F) -> ! {
|
||||
Daemon::new(|daemon| {
|
||||
let pcid_handle = PciFunctionHandle::connect_default();
|
||||
f(daemon, pcid_handle)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
//! Interface to `pcid`.
|
||||
|
||||
#![feature(never_type)]
|
||||
|
||||
mod driver_interface;
|
||||
pub use driver_interface::*;
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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 <scheme> <port> <protocol>";
|
||||
@@ -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.
|
||||
|
||||
@@ -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<u16>,
|
||||
@@ -109,8 +98,23 @@ pub struct BlockVirtRequest {
|
||||
|
||||
const_assert_eq!(core::mem::size_of::<BlockVirtRequest>(), 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!();
|
||||
}
|
||||
|
||||
@@ -115,10 +115,6 @@ fn get_int_method(pcid_handle: &mut PciFunctionHandle) -> (Option<File>, Interru
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
daemon::Daemon::new(daemon);
|
||||
}
|
||||
|
||||
//TODO: cleanup CSZ support
|
||||
fn daemon_with_context_size<const N: usize>(
|
||||
daemon: daemon::Daemon,
|
||||
@@ -185,8 +181,11 @@ fn daemon_with_context_size<const N: usize>(
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
|
||||
+108
-110
@@ -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::<u32>()
|
||||
.unwrap_or(0);
|
||||
height = res
|
||||
.split("/")
|
||||
.nth(2)
|
||||
.unwrap_or("")
|
||||
.parse::<u32>()
|
||||
.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::<u32>()
|
||||
.unwrap_or(0);
|
||||
height = res
|
||||
.split("/")
|
||||
.nth(2)
|
||||
.unwrap_or("")
|
||||
.parse::<u32>()
|
||||
.unwrap_or(0);
|
||||
}
|
||||
}
|
||||
|
||||
let mut irq_file = irq.irq_handle("vboxd");
|
||||
|
||||
let mut port = Pio::<u32>::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::<Source>::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::<u32>::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::<Source>::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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "init"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
|
||||
[dependencies]
|
||||
|
||||
+160
-205
@@ -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::<Vec<_>>().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);
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
ps2d us
|
||||
hwd
|
||||
pcid-spawner /etc/pcid/initfs.toml
|
||||
pcid-spawner /scheme/initfs/etc/pcid/initfs.toml
|
||||
|
||||
+3
-1
@@ -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 }
|
||||
|
||||
+11
-9
@@ -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<()> {
|
||||
|
||||
@@ -737,9 +737,9 @@ impl<'sock> SchemeSync for UdsDgramScheme<'sock> {
|
||||
}
|
||||
}
|
||||
|
||||
fn fevent(&mut self, id: usize, flags: EventFlags, ctx: &CallerCtx) -> Result<EventFlags> {
|
||||
fn fevent(&mut self, id: usize, flags: EventFlags, _ctx: &CallerCtx) -> Result<EventFlags> {
|
||||
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 {
|
||||
|
||||
@@ -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<EventFlags> {
|
||||
fn fevent(&mut self, id: usize, flags: EventFlags, _ctx: &CallerCtx) -> Result<EventFlags> {
|
||||
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 {
|
||||
|
||||
+11
-9
@@ -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);
|
||||
}
|
||||
|
||||
+60
-59
@@ -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::<EventSource>::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::<EventSource>::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 {
|
||||
|
||||
+28
-26
@@ -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);
|
||||
}
|
||||
|
||||
+29
-27
@@ -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::<V2>::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::<V2>::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");
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user