From 1385021b0f9d1379ab153723fa6a3e6dfc130588 Mon Sep 17 00:00:00 2001 From: Xavier Moffett Date: Thu, 9 May 2024 20:45:24 -0400 Subject: [PATCH] Fixed error condition handling in edit function with some minor refactoring - A bug wherein the lock doesn't get removed when an error occurs (e.g. file not found) has been fixed. --- pacwrap/src/utils.rs | 4 ++-- pacwrap/src/utils/edit.rs | 43 +++++++++++++++++++++++---------------- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/pacwrap/src/utils.rs b/pacwrap/src/utils.rs index 4f48b84..ea6e678 100644 --- a/pacwrap/src/utils.rs +++ b/pacwrap/src/utils.rs @@ -42,8 +42,8 @@ const GIO: &'static str = "gio"; pub fn engage_utility(args: &mut Arguments) -> Result<()> { match args.next().unwrap_or_default() { - Operand::Short('v') | Operand::Long("view") | Operand::Value("view") => edit::edit_file(args, false), - Operand::Short('e') | Operand::Long("edit") | Operand::Value("edit") => edit::edit_file(args, true), + Operand::Short('v') | Operand::Long("view") | Operand::Value("view") => edit::edit(args, false), + Operand::Short('e') | Operand::Long("edit") | Operand::Value("edit") => edit::edit(args, true), Operand::Short('r') | Operand::Long("remove") | Operand::Value("remove") => delete::remove_containers(args), Operand::Short('l') | Operand::Long("list") | Operand::Value("list") => list::list_containers(args), Operand::Short('d') | Operand::Long("desktop") | Operand::Value("desktop") => desktop::file(args), diff --git a/pacwrap/src/utils/edit.rs b/pacwrap/src/utils/edit.rs index d78d764..a63f9a3 100644 --- a/pacwrap/src/utils/edit.rs +++ b/pacwrap/src/utils/edit.rs @@ -20,7 +20,7 @@ use std::{ fmt::{Display, Formatter}, fs::{copy, remove_file, File}, - io::{copy as copy_io, Read}, + io::{copy as copy_io, Read, Result as IOResult}, process::Command, }; @@ -73,7 +73,7 @@ impl<'a> Display for FileType<'a> { } } -pub fn edit_file(args: &mut Arguments, edit: bool) -> Result<()> { +pub fn edit(args: &mut Arguments, edit: bool) -> Result<()> { let mut file = None; while let Some(arg) = args.next() { @@ -95,41 +95,50 @@ pub fn edit_file(args: &mut Arguments, edit: bool) -> Result<()> { }); } - let (file, temporary_file, lock, edit) = &match file { + let (file, temp, lock, edit) = &match file { Some(file) => { let edit = file.can_edit(edit); + let prs = pseudorandom_string(10).prepend_io(|| "/dev/urandom".into())?; + let temp = format!("/tmp/tmp.{}", prs); let lock = if let (FileType::ContainerConfig(_), true) = (file, edit) { Some(Lock::new().lock()?) } else { None }; - - (file.to_string(), format!("/tmp/tmp.{}", random_string(10)?), lock, edit) + let file = file.to_string(); + + (file, temp, lock, edit) } None => return args.invalid_operand(), }; + if let Err(err) = edit_file(file, temp, lock.as_ref(), *edit) { + if let Some(lock) = lock { + lock.unlock()?; + } + + Err(err)? + } + + Ok(()) +} + +fn edit_file(file: &str, temporary_file: &str, lock: Option<&Lock>, edit: bool) -> Result<()> { copy(file, temporary_file).prepend_io(|| file.into())?; handle_process(*EDITOR, Command::new(*EDITOR).arg(temporary_file).spawn())?; - if *edit && hash_file(file)? != hash_file(temporary_file)? { + if edit && hash_file(file)? != hash_file(temporary_file)? { if let Some(lock) = lock { lock.assert()?; } copy(temporary_file, file).prepend_io(|| temporary_file.into())?; eprintln!("{} Changes written to file.", *ARROW_GREEN); - } else if *edit { + } else if edit { eprintln!("{} No changes made.", *ARROW_CYAN); } - remove_file(temporary_file).prepend_io(|| temporary_file.into())?; - - if let Some(lock) = lock { - lock.unlock()?; - } - - Ok(()) + remove_file(temporary_file).prepend_io(|| temporary_file.into()) } fn hash_file(file_path: &str) -> Result> { @@ -140,8 +149,8 @@ fn hash_file(file_path: &str) -> Result> { Ok(hasher.finalize().to_vec()) } -fn random_string(len: usize) -> Result { - let mut urand = File::open("/dev/urandom").prepend_io(|| "/dev/urandom".into())?; +fn pseudorandom_string(len: usize) -> IOResult { + let mut urand = File::open("/dev/urandom")?; let mut vec: Vec = Vec::new(); vec.reserve_exact(len); @@ -149,7 +158,7 @@ fn random_string(len: usize) -> Result { while vec.len() < len { let mut buffer = [0; 1]; - urand.read_exact(&mut buffer).prepend_io(|| "/dev/urandom".into())?; + urand.read_exact(&mut buffer)?; if buffer[0] > 64 && buffer[0] < 91 || buffer[0] > 96 && buffer[0] < 122 || buffer[0] > 48 && buffer[0] < 58 { vec.push(buffer[0]);