Skip to content

Commit

Permalink
Auto merge of #386 - bugaevc:reboot, r=fiveop
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
homu committed Jul 16, 2016
2 parents 1033385 + 215f387 commit 29193ba
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/sys/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ pub mod stat;
#[cfg(any(target_os = "linux", target_os = "android"))]
pub mod syscall;

#[cfg(any(target_os = "linux"))]
pub mod reboot;

#[cfg(not(target_os = "ios"))]
pub mod termios;

Expand Down
43 changes: 43 additions & 0 deletions src/sys/reboot.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//! Reboot/shutdown or enable/disable Ctrl-Alt-Delete.
use {Errno, Error, Result};
use libc;
use void::Void;
use std::mem::drop;

/// How exactly should the system be rebooted.
///
/// See [`set_cad_enabled()`](fn.set_cad_enabled.html) for
/// enabling/disabling Ctrl-Alt-Delete.
#[repr(i32)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum RebootMode {
RB_HALT_SYSTEM = libc::RB_HALT_SYSTEM,
RB_KEXEC = libc::RB_KEXEC,
RB_POWER_OFF = libc::RB_POWER_OFF,
RB_AUTOBOOT = libc::RB_AUTOBOOT,
// we do not support Restart2,
RB_SW_SUSPEND = libc::RB_SW_SUSPEND,
}

pub fn reboot(how: RebootMode) -> Result<Void> {
unsafe {
libc::reboot(how as libc::c_int)
};
Err(Error::Sys(Errno::last()))
}

/// Enable or disable the reboot keystroke (Ctrl-Alt-Delete).
///
/// Corresponds to calling `reboot(RB_ENABLE_CAD)` or `reboot(RB_DISABLE_CAD)` in C.
pub fn set_cad_enabled(enable: bool) -> Result<()> {
let cmd = if enable {
libc::RB_ENABLE_CAD
} else {
libc::RB_DISABLE_CAD
};
let res = unsafe {
libc::reboot(cmd)
};
Errno::result(res).map(drop)
}

0 comments on commit 29193ba

Please sign in to comment.