Skip to content

Commit

Permalink
Implement ctrlaltdel (#31)
Browse files Browse the repository at this point in the history
* Implement ctrlaltdel

* Add tests for `ctrlaltdel`

* Bless the unit tests on unsupported platforms
  • Loading branch information
sisungo authored May 12, 2024
1 parent 572f84b commit c9ee7d6
Show file tree
Hide file tree
Showing 8 changed files with 191 additions and 0 deletions.
9 changes: 9 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ default = ["feat_common_core"]
feat_common_core = [
"mountpoint",
"lscpu",
"ctrlaltdel",
]

[workspace.dependencies]
Expand Down Expand Up @@ -56,6 +57,7 @@ textwrap = { workspace = true }
#
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" }
ctrlaltdel = { optional = true, version = "0.0.1", package = "uu_ctrlaltdel", path = "src/uu/ctrlaltdel" }

[dev-dependencies]
pretty_assertions = "1"
Expand Down
15 changes: 15 additions & 0 deletions src/uu/ctrlaltdel/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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 changes: 7 additions & 0 deletions src/uu/ctrlaltdel/ctrlaltdel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# ctrlaltdel

```
ctrlaltdel hard|soft
```

set the function of the ctrl-alt-del combination
139 changes: 139 additions & 0 deletions src/uu/ctrlaltdel/src/ctrlaltdel.rs
Original file line number Diff line number Diff line change
@@ -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 change: 1 addition & 0 deletions src/uu/ctrlaltdel/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
uucore::bin!(uu_ctrlaltdel);
14 changes: 14 additions & 0 deletions tests/by-util/test_ctrlaltdel.rs
Original file line number Diff line number Diff line change
@@ -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);
}
4 changes: 4 additions & 0 deletions tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,7 @@ mod test_lscpu;
#[cfg(feature = "mountpoint")]
#[path = "by-util/test_mountpoint.rs"]
mod test_mountpoint;

#[cfg(feature = "ctrlaltdel")]
#[path = "by-util/test_ctrlaltdel.rs"]
mod test_ctrlaltdel;

0 comments on commit c9ee7d6

Please sign in to comment.