-
Notifications
You must be signed in to change notification settings - Fork 677
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add reboot() support on Linux #386
Changes from 8 commits
f3d7b01
91b29ab
c63f89c
bf796cc
b19afe5
012c662
cce6bce
f682458
8f6b162
215f387
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
//! 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. | ||
#[derive(Clone, Copy, Debug, Eq, PartialEq)] | ||
pub enum RebootMode { | ||
Halt, | ||
kexec, | ||
PowerOff, | ||
Restart, | ||
// we do not support Restart2, | ||
Suspend, | ||
} | ||
|
||
pub fn reboot(how: RebootMode) -> Result<Void> { | ||
let cmd = match how { | ||
RebootMode::Halt => libc::RB_HALT_SYSTEM, | ||
RebootMode::kexec => libc::RB_KEXEC, | ||
RebootMode::PowerOff => libc::RB_POWER_OFF, | ||
RebootMode::Restart => libc::RB_AUTOBOOT, | ||
// we do not support Restart2, | ||
RebootMode::Suspend => libc::RB_SW_SUSPEND, | ||
}; | ||
unsafe { | ||
libc::reboot(cmd) | ||
}; | ||
Err(Error::Sys(Errno::last())) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Errno::result(res).map(drop) should work here just like in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, the whole point is that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here's what the manual says:
|
||
} | ||
|
||
/// Enable or disable the reboot keystroke (Ctrl-Alt-Delete). | ||
/// | ||
/// Corresponds to calling `reboot(RB_ENABLE_CAD)` or `reboot(RB_DISABLE_CAD)` in C. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we mention in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, will do. Maybe I should just document everything. |
||
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) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Somehow a comment went missing yesterday; I might have forgotten to press comment).
What problem did occur when you tried to use
#[repr(i32)]
? All constants have typelibc::c_int
which is an alias fori32
. The enumerationSignal
insys/signal.rs
does the same. You could then get rid of the match bellow.As you can see there, I used the name of the corresponding constants for the elements of the enumeration. I would prefere if we did that here as well, even though we have no convention yet. However, bitflags types use this convention, so it would be consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having looked at your commit history, your problem probably was that you still have to cast the enumeration elements to
libc::c_int
in order to pass them toreboot
, i.e.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As you can see from this commit, that's exactly what I tried before, and here's the Travis failure that GitHub UI displays as a little red cross next to the commit -- however now that I look carefully I see that the commit hash is wrong and the link back gives me 404 -- is it a bug or something (I definetely commited that after rebasing)?
On your "middle" point -- do you mean to call the enum variants
RebootMode::RB_POWER_OFF
as so on? Doesn't seem beautiful; but if that's the convention -- OK¯\_(ツ)_/¯
. I would rather prefer to name them appropriately and list the C analogues in the documentation, but we obviously can't rename all of the bitflags now, so consistency wins, yeah.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding the names, you understood me correctly.
I had a look at the Travis output and I dont understand it. The constants are
libc::c_int
in libc, which isi32
hence an enumeration with #[repr(i32)] should work.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So maybe it is a bug in GH/Travis. Let me change the names and try
#[repr(i32)]
one more time then.