Skip to content

Commit

Permalink
refactor: move umount to the common executable
Browse files Browse the repository at this point in the history
  • Loading branch information
llenotre committed Jul 3, 2024
1 parent 1752dab commit aa2b74c
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 89 deletions.
3 changes: 2 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ mod mount;
mod nologin;
mod ps;
mod rmmod;
mod umount;

use std::env;
use utils::error;
Expand All @@ -34,7 +35,7 @@ fn main() {
todo!()
}
"mount" => mount::main(args),
"umount" => todo!(),
"umount" => umount::main(args),
"nologin" => nologin::main(),
"powerctl" => todo!(),
"halt" => todo!(),
Expand Down
68 changes: 68 additions & 0 deletions src/umount.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//! The `mount` command allows to unmount a filesystem.
use std::env::ArgsOs;
use std::ffi::{CStr, CString};
use std::fs;
use std::io;
use std::io::Error;
use std::os::unix::ffi::OsStrExt;
use std::path::PathBuf;
use std::process::exit;
use utils::error;

/// Prints the command's usage.
///
/// `bin` is the name of the current binary.
fn print_usage() {
eprintln!("Usage:");
eprintln!(" umount [-R] dir");
eprintln!();
eprintln!("Options:");
eprintln!(" -R:\tunmounts filesystems recursively");
eprintln!(" dir:\tthe mountpoint path");
}

/// Unmounts the filesystem at the given path `target`.
pub fn unmount_fs(target: &CStr) -> io::Result<()> {
let ret = unsafe { libc::umount(target.as_ptr() as _) };
if ret < 0 {
return Err(Error::last_os_error());
}
Ok(())
}

pub fn main(args: ArgsOs) {
let args: Vec<_> = args.collect();
match &args[..] {
[opt, path] if opt == "-R" => {
// List active mount points
let content = fs::read_to_string("/etc/mtab").unwrap_or_else(|e| {
error("umount", format_args!("cannot list mount points: {e}"))
});
let mut mps: Vec<_> = content
.split('\n')
.filter_map(|entry| Some(entry.split(' ').nth(1)?.into()))
// Filter matching paths
.filter(|mp: &PathBuf| mp.starts_with(path))
.collect();
// Sort to unmount in the right order
mps.sort_unstable();
for mp in mps.into_iter().rev() {
let s = CString::new(mp.as_os_str().as_bytes()).unwrap();
unmount_fs(&s).unwrap_or_else(|e| {
error("umount", format_args!("cannot unmount `{}`: {e}", path.display()));
});
}
}
[path] => {
let s = CString::new(args[1].as_bytes()).unwrap();
unmount_fs(&s).unwrap_or_else(|e| {
error("umount", format_args!("cannot unmount `{}`: {e}", path.display()));
});
}
_ => {
print_usage();
exit(1);
}
}
}
7 changes: 0 additions & 7 deletions umount/Cargo.toml

This file was deleted.

81 changes: 0 additions & 81 deletions umount/src/main.rs

This file was deleted.

0 comments on commit aa2b74c

Please sign in to comment.