Implement ctrlaltdel
(#31)
* Implement ctrlaltdel * Add tests for `ctrlaltdel` * Bless the unit tests on unsupported platforms
This commit is contained in:
9
Cargo.lock
generated
9
Cargo.lock
generated
@@ -641,12 +641,21 @@ dependencies = [
|
|||||||
"rlimit",
|
"rlimit",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"textwrap",
|
"textwrap",
|
||||||
|
"uu_ctrlaltdel",
|
||||||
"uu_lscpu",
|
"uu_lscpu",
|
||||||
"uu_mountpoint",
|
"uu_mountpoint",
|
||||||
"uucore",
|
"uucore",
|
||||||
"xattr",
|
"xattr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uu_ctrlaltdel"
|
||||||
|
version = "0.0.1"
|
||||||
|
dependencies = [
|
||||||
|
"clap",
|
||||||
|
"uucore",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uu_lscpu"
|
name = "uu_lscpu"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
|
@@ -27,6 +27,7 @@ default = ["feat_common_core"]
|
|||||||
feat_common_core = [
|
feat_common_core = [
|
||||||
"mountpoint",
|
"mountpoint",
|
||||||
"lscpu",
|
"lscpu",
|
||||||
|
"ctrlaltdel",
|
||||||
]
|
]
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
@@ -56,6 +57,7 @@ textwrap = { workspace = true }
|
|||||||
#
|
#
|
||||||
lscpu = { optional = true, version = "0.0.1", package = "uu_lscpu", path = "src/uu/lscpu" }
|
lscpu = { optional = true, version = "0.0.1", package = "uu_lscpu", path = "src/uu/lscpu" }
|
||||||
mountpoint = { optional = true, version = "0.0.1", package = "uu_mountpoint", path = "src/uu/mountpoint" }
|
mountpoint = { optional = true, version = "0.0.1", package = "uu_mountpoint", path = "src/uu/mountpoint" }
|
||||||
|
ctrlaltdel = { optional = true, version = "0.0.1", package = "uu_ctrlaltdel", path = "src/uu/ctrlaltdel" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
pretty_assertions = "1"
|
pretty_assertions = "1"
|
||||||
|
15
src/uu/ctrlaltdel/Cargo.toml
Normal file
15
src/uu/ctrlaltdel/Cargo.toml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
[package]
|
||||||
|
name = "uu_ctrlaltdel"
|
||||||
|
version = "0.0.1"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
path = "src/ctrlaltdel.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "ctrlaltdel"
|
||||||
|
path = "src/main.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
uucore = { workspace = true }
|
||||||
|
clap = { workspace = true }
|
7
src/uu/ctrlaltdel/ctrlaltdel.md
Normal file
7
src/uu/ctrlaltdel/ctrlaltdel.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# ctrlaltdel
|
||||||
|
|
||||||
|
```
|
||||||
|
ctrlaltdel hard|soft
|
||||||
|
```
|
||||||
|
|
||||||
|
set the function of the ctrl-alt-del combination
|
139
src/uu/ctrlaltdel/src/ctrlaltdel.rs
Normal file
139
src/uu/ctrlaltdel/src/ctrlaltdel.rs
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
// This file is part of the uutils util-linux package.
|
||||||
|
//
|
||||||
|
// For the full copyright and license information, please view the LICENSE
|
||||||
|
// file that was distributed with this source code.
|
||||||
|
|
||||||
|
use clap::{crate_version, Arg, ArgAction, Command};
|
||||||
|
use uucore::{error::UResult, format_usage, help_about, help_usage};
|
||||||
|
|
||||||
|
const ABOUT: &str = help_about!("ctrlaltdel.md");
|
||||||
|
const USAGE: &str = help_usage!("ctrlaltdel.md");
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
const CTRL_ALT_DEL_PATH: &str = "/proc/sys/kernel/ctrl-alt-del";
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
#[uucore::main]
|
||||||
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
|
let matches: clap::ArgMatches = uu_app().try_get_matches_from(args)?;
|
||||||
|
let pattern = matches.get_one::<String>("pattern");
|
||||||
|
match pattern {
|
||||||
|
Some(x) if x == "hard" => {
|
||||||
|
set_ctrlaltdel(CtrlAltDel::Hard)?;
|
||||||
|
}
|
||||||
|
Some(x) if x == "soft" => {
|
||||||
|
set_ctrlaltdel(CtrlAltDel::Soft)?;
|
||||||
|
}
|
||||||
|
Some(x) => {
|
||||||
|
Err(Error::UnknownArgument(x.clone()))?;
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
println!("{}", get_ctrlaltdel()?);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "linux"))]
|
||||||
|
#[uucore::main]
|
||||||
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
|
let _matches: clap::ArgMatches = uu_app().try_get_matches_from(args)?;
|
||||||
|
|
||||||
|
Err(uucore::error::USimpleError::new(
|
||||||
|
1,
|
||||||
|
"`ctrlaltdel` is unavailable on current platform.",
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
fn get_ctrlaltdel() -> UResult<CtrlAltDel> {
|
||||||
|
let value: i32 = std::fs::read_to_string(CTRL_ALT_DEL_PATH)?
|
||||||
|
.trim()
|
||||||
|
.parse()
|
||||||
|
.map_err(|_| Error::UnknownData)?;
|
||||||
|
|
||||||
|
Ok(CtrlAltDel::from_sysctl(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
fn set_ctrlaltdel(ctrlaltdel: CtrlAltDel) -> UResult<()> {
|
||||||
|
std::fs::write(CTRL_ALT_DEL_PATH, format!("{}\n", ctrlaltdel.to_sysctl()))
|
||||||
|
.map_err(|_| Error::NotRoot)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
enum CtrlAltDel {
|
||||||
|
Soft,
|
||||||
|
Hard,
|
||||||
|
}
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
impl CtrlAltDel {
|
||||||
|
/// # Panics
|
||||||
|
/// Panics if value of the parameter `value` is neither `0` nor `1`.
|
||||||
|
fn from_sysctl(value: i32) -> Self {
|
||||||
|
match value {
|
||||||
|
0 => Self::Soft,
|
||||||
|
1 => Self::Hard,
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_sysctl(self) -> i32 {
|
||||||
|
match self {
|
||||||
|
Self::Soft => 0,
|
||||||
|
Self::Hard => 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
impl std::fmt::Display for CtrlAltDel {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Soft => write!(f, "soft"),
|
||||||
|
Self::Hard => write!(f, "hard"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum Error {
|
||||||
|
NotRoot,
|
||||||
|
UnknownArgument(String),
|
||||||
|
UnknownData,
|
||||||
|
}
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
impl std::fmt::Display for Error {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::NotRoot => write!(f, "You must be root to set the Ctrl-Alt-Del behavior"),
|
||||||
|
Self::UnknownArgument(x) => write!(f, "unknown argument: {x}"),
|
||||||
|
Self::UnknownData => write!(f, "unknown data"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
impl std::error::Error for Error {}
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
impl uucore::error::UError for Error {
|
||||||
|
fn code(&self) -> i32 {
|
||||||
|
1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn usage(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn uu_app() -> Command {
|
||||||
|
Command::new(uucore::util_name())
|
||||||
|
.version(crate_version!())
|
||||||
|
.about(ABOUT)
|
||||||
|
.override_usage(format_usage(USAGE))
|
||||||
|
.infer_long_args(true)
|
||||||
|
.arg(Arg::new("pattern").action(ArgAction::Set))
|
||||||
|
}
|
1
src/uu/ctrlaltdel/src/main.rs
Normal file
1
src/uu/ctrlaltdel/src/main.rs
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uucore::bin!(uu_ctrlaltdel);
|
14
tests/by-util/test_ctrlaltdel.rs
Normal file
14
tests/by-util/test_ctrlaltdel.rs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
// This file is part of the uutils util-linux package.
|
||||||
|
//
|
||||||
|
// For the full copyright and license information, please view the LICENSE
|
||||||
|
// file that was distributed with this source code.
|
||||||
|
// spell-checker:ignore (words) symdir somefakedir
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
use crate::common::util::TestScenario;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
fn test_invalid_arg() {
|
||||||
|
new_ucmd!().arg("--definitely-invalid").fails().code_is(1);
|
||||||
|
}
|
@@ -12,3 +12,7 @@ mod test_lscpu;
|
|||||||
#[cfg(feature = "mountpoint")]
|
#[cfg(feature = "mountpoint")]
|
||||||
#[path = "by-util/test_mountpoint.rs"]
|
#[path = "by-util/test_mountpoint.rs"]
|
||||||
mod test_mountpoint;
|
mod test_mountpoint;
|
||||||
|
|
||||||
|
#[cfg(feature = "ctrlaltdel")]
|
||||||
|
#[path = "by-util/test_ctrlaltdel.rs"]
|
||||||
|
mod test_ctrlaltdel;
|
||||||
|
Reference in New Issue
Block a user