Skip to content

Commit 29193ba

Browse files
committed
Auto merge of #386 - bugaevc:reboot, r=fiveop
Add reboot() support on Linux This adds support for calling [reboot(2)](http://linux.die.net/man/2/reboot) on Linux (useful for implementing PID 1!). * **Testing**: I can't imagine how this could be tested other than manually, which is what I did to ensure it works. * **libc**: for some reason libc includes neither `reboot()` function, nor `RB_*` constants, so I had to hack-define them here. Should I open a bug/PR against the libc crate? * **API**: I went with `reboot()` function for restarting, powering off, halting, etc. and an additional `set_cad_enabled()` function for enabling/disabling Ctrl-Alt-Delete, which still corresponds to `reboot()` C call, but has different semantics and return type. (But I'm open to suggestions here -- maybe it would be better to separate each action into its own function, i.e. `restart()`, `poweroff()`, `halt()`?) * **Documentation**: I see most of the things in nix are undocumented, so I didn't document anything except for the `set_cad_enabled()` function, which obviously uses a non-standard name. * **Portability**: I implemented the Linux version as I'm not familiar with anything else, but there surely are others (ex. [BSD](http://www.freebsd.org/cgi/man.cgi?reboot(2))). If I didn't mess up anything, the new code is only compiled on Linux/Android, so it should be straightforward to implement the other versions too.
2 parents 1033385 + 215f387 commit 29193ba

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

src/sys/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ pub mod stat;
3131
#[cfg(any(target_os = "linux", target_os = "android"))]
3232
pub mod syscall;
3333

34+
#[cfg(any(target_os = "linux"))]
35+
pub mod reboot;
36+
3437
#[cfg(not(target_os = "ios"))]
3538
pub mod termios;
3639

src/sys/reboot.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//! Reboot/shutdown or enable/disable Ctrl-Alt-Delete.
2+
3+
use {Errno, Error, Result};
4+
use libc;
5+
use void::Void;
6+
use std::mem::drop;
7+
8+
/// How exactly should the system be rebooted.
9+
///
10+
/// See [`set_cad_enabled()`](fn.set_cad_enabled.html) for
11+
/// enabling/disabling Ctrl-Alt-Delete.
12+
#[repr(i32)]
13+
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
14+
pub enum RebootMode {
15+
RB_HALT_SYSTEM = libc::RB_HALT_SYSTEM,
16+
RB_KEXEC = libc::RB_KEXEC,
17+
RB_POWER_OFF = libc::RB_POWER_OFF,
18+
RB_AUTOBOOT = libc::RB_AUTOBOOT,
19+
// we do not support Restart2,
20+
RB_SW_SUSPEND = libc::RB_SW_SUSPEND,
21+
}
22+
23+
pub fn reboot(how: RebootMode) -> Result<Void> {
24+
unsafe {
25+
libc::reboot(how as libc::c_int)
26+
};
27+
Err(Error::Sys(Errno::last()))
28+
}
29+
30+
/// Enable or disable the reboot keystroke (Ctrl-Alt-Delete).
31+
///
32+
/// Corresponds to calling `reboot(RB_ENABLE_CAD)` or `reboot(RB_DISABLE_CAD)` in C.
33+
pub fn set_cad_enabled(enable: bool) -> Result<()> {
34+
let cmd = if enable {
35+
libc::RB_ENABLE_CAD
36+
} else {
37+
libc::RB_DISABLE_CAD
38+
};
39+
let res = unsafe {
40+
libc::reboot(cmd)
41+
};
42+
Errno::result(res).map(drop)
43+
}

0 commit comments

Comments
 (0)