initial initrs commit
commit
ac86bb7844
@ -0,0 +1,2 @@
|
||||
/target
|
||||
**/*.rs.bk
|
@ -0,0 +1,80 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "arc-swap"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "initrs"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"signal-hook 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.62"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"signal-hook-registry 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"arc-swap 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "void"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[metadata]
|
||||
"checksum arc-swap 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f1a1eca3195b729bbd64e292ef2f5fff6b1c28504fed762ce2b1013dde4d8e92"
|
||||
"checksum bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a606a02debe2813760609f57a64a2ffd27d9fdf5b2f133eaca0b248dd92cdd2"
|
||||
"checksum cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)" = "4fc9a35e1f4290eb9e5fc54ba6cf40671ed2a2514c3eeb2b2a908dda2ea5a1be"
|
||||
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba"
|
||||
"checksum nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3b2e0b4f3320ed72aaedb9a5ac838690a8047c7b275da22711fddff4f8a14229"
|
||||
"checksum signal-hook 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4f61c4d59f3aaa9f61bba6450a9b80ba48362fd7d651689e7a10c453b1f6dc68"
|
||||
"checksum signal-hook-registry 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1797d48f38f91643908bb14e35e79928f9f4b3cefb2420a564dde0991b4358dc"
|
||||
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "initrs"
|
||||
version = "0.1.0"
|
||||
authors = ["Lukáš Hozda <luk.hozda@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
signal-hook = "0.1.10"
|
||||
nix = "0.15"
|
@ -0,0 +1,5 @@
|
||||
pub static TIMEOUT: u32 = 30;
|
||||
|
||||
pub static INIT_CMD: &'static [&'static str] = &["/bin/rc.init"];
|
||||
pub static REBOOT_CMD: &'static [&'static str] = &["/bin/rc.shutdown", "reboot"];
|
||||
pub static POWEROFF_CMD: &'static [&'static str] = &["/bin/rc.init", "poweroff"];
|
@ -0,0 +1,90 @@
|
||||
extern crate signal_hook;
|
||||
|
||||
use std::thread;
|
||||
use std::env::set_current_dir;
|
||||
use std::process::{Stdio, Command};
|
||||
|
||||
use nix::unistd::{alarm, Pid, getpid};
|
||||
use nix::sys::wait::{waitpid, WaitStatus, WaitPidFlag};
|
||||
use signal_hook::{iterator::Signals, SIGINT, SIGALRM, SIGCHLD, SIGUSR1};
|
||||
|
||||
mod config;
|
||||
|
||||
fn sig_poweroff() {
|
||||
if Command::new(config::POWEROFF_CMD[0])
|
||||
.args(config::POWEROFF_CMD.iter().skip(1))
|
||||
.output()
|
||||
.is_err()
|
||||
{
|
||||
println!("[RS] poweroff failed");
|
||||
}
|
||||
}
|
||||
|
||||
fn sig_reap() {
|
||||
loop {
|
||||
match waitpid(Pid::from_raw(-1), Some(WaitPidFlag::WNOHANG)) {
|
||||
Err(_) => break,
|
||||
Ok(status) => match status {
|
||||
WaitStatus::Exited(pid, ..) |
|
||||
WaitStatus::Signaled(pid, ..) |
|
||||
WaitStatus::Stopped(pid, ..) |
|
||||
WaitStatus::Continued(pid) => if pid.as_raw() <= 0 {
|
||||
break
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
alarm::set(config::TIMEOUT);
|
||||
}
|
||||
|
||||
fn sig_reboot() {
|
||||
if Command::new(config::REBOOT_CMD[0])
|
||||
.args(config::REBOOT_CMD.iter().skip(1))
|
||||
.output()
|
||||
.is_err()
|
||||
{
|
||||
println!("[RS] reboot failed");
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
if getpid().as_raw() != 1 { return }
|
||||
|
||||
let signals = Signals::new(&[
|
||||
SIGUSR1,
|
||||
SIGCHLD,
|
||||
SIGALRM,
|
||||
SIGINT,
|
||||
]).expect("[RS] failed to handle signals");
|
||||
|
||||
set_current_dir("/")
|
||||
.expect("[RS] failed to chdir");
|
||||
|
||||
let init = Command::new(config::INIT_CMD[0])
|
||||
.args(config::INIT_CMD.iter().skip(1))
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.expect("[RS] failed to spawn init command");
|
||||
|
||||
thread::spawn(|| {
|
||||
let c = init.wait_with_output()
|
||||
.expect("[RS] failed to wait on init command");
|
||||
|
||||
if !c.status.success() {
|
||||
eprintln!("[RS] exited with a non-zero return code, see stderr below:");
|
||||
eprintln!("{}", String::from_utf8_lossy(&c.stdout));
|
||||
}
|
||||
});
|
||||
|
||||
for signal in signals.forever() {
|
||||
match signal {
|
||||
SIGUSR1 => sig_poweroff(),
|
||||
SIGCHLD |
|
||||
SIGALRM => sig_reap(),
|
||||
SIGINT => sig_reboot(),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue