initial initrs commit

master
Lukáš Hozda 5 years ago
commit ac86bb7844

2
.gitignore vendored

@ -0,0 +1,2 @@
/target
**/*.rs.bk

80
Cargo.lock generated

@ -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…
Cancel
Save