From 97679e43a6a2715851a368e3666e6d94923e6c13 Mon Sep 17 00:00:00 2001 From: Nathan Fisher Date: Mon, 17 Apr 2023 22:40:49 -0400 Subject: [PATCH] Finish truncate applet (untested) --- corebox/commands/truncate/mod.rs | 55 ++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/corebox/commands/truncate/mod.rs b/corebox/commands/truncate/mod.rs index 1020c22..8758b9b 100644 --- a/corebox/commands/truncate/mod.rs +++ b/corebox/commands/truncate/mod.rs @@ -1,7 +1,9 @@ +use std::fs::File; + use { super::Cmd, clap::{Arg, ArgAction, ArgGroup, Command, ValueHint}, - std::{error::Error, fmt, fs, num::ParseIntError}, + std::{error::Error, fmt, fs, num::ParseIntError, path::PathBuf}, }; #[derive(Debug, Default)] @@ -65,12 +67,49 @@ impl Cmd for Truncate { fn run(&self, matches: &clap::ArgMatches) -> Result<(), Box> { let size = if let Some(file) = matches.get_one::("reference") { let num: i64 = fs::metadata(file)?.len().try_into()?; - Size { operator: Operator::Equal, num } + Size { + operator: Operator::Equal, + num, + } } else if let Some(s) = matches.get_one::("size") { parse_size(s)? } else { unreachable!(); }; + matches + .get_many::("file") + .unwrap() + .try_for_each(|file| { + let path = PathBuf::from(file); + if !matches.get_flag("create") && !path.exists() { + return Ok(()); + } + let fd = File::options().write(true).create(true).open(&path)?; + let current: i64 = fd.metadata()?.len().try_into()?; + let len = match size.operator { + Operator::Equal => size.num, + Operator::Add => size.num + current, + Operator::Remove => current - size.num, + Operator::ModUp => { + if current % size.num == 0 { + current + } else { + let fraction = current / size.num; + (fraction + 1) * size.num + } + } + Operator::ModDown => { + if current % size.num == 0 { + current + } else { + let fraction = current / size.num; + fraction * size.num + } + } + }; + unistd::ftruncate(&fd, len)?; + Ok::<(), Box>(()) + })?; Ok(()) } @@ -79,6 +118,7 @@ impl Cmd for Truncate { } } +#[derive(PartialEq)] enum Operator { Equal, Add, @@ -201,13 +241,16 @@ fn parse_size(size: &str) -> Result { if let Some(m) = multiplier { match m { Multiplier::Kilo => num *= 1024, - Multiplier::Mega => num *= (1024 * 1024), - Multiplier::Giga => num *= (1024 * 1024 * 1024), - Multiplier::Tera => num *= (1024 * 1024 * 1024 * 1024), + Multiplier::Mega => num *= 1024 * 1024, + Multiplier::Giga => num *= 1024 * 1024 * 1024, + Multiplier::Tera => num *= 1024 * 1024 * 1024 * 1024, } } match operator { Some(operator) => Ok(Size { operator, num }), - None => Ok(Size { operator: Operator::Equal, num }), + None => Ok(Size { + operator: Operator::Equal, + num, + }), } }