use crate::unistd; use super::Cmd; use clap::{Arg, ArgAction, Command}; use std::{error::Error, io, fs::OpenOptions}; #[derive(Debug, Default)] pub struct Sync; impl Cmd for Sync { fn cli(&self) -> clap::Command { Command::new("sync") .about("force completion of pending disk writes (flush cache)") .author("Nathan Fisher") .version(env!("CARGO_PKG_VERSION")) .args([ Arg::new("data") .short('d') .long("data") .help("sync only file data, no unneeded metadata") .conflicts_with("fs") .action(ArgAction::SetTrue), Arg::new("fs") .short('f') .long("file-system") .help("sync the file systems that contain the files") .action(ArgAction::SetTrue), Arg::new("FILE") .help( "If one or more files are specified, sync only them, or \ their containing file systems.", ) .num_args(0..), ]) } fn run(&self, matches: Option<&clap::ArgMatches>) -> Result<(), Box> { let Some(matches) = matches else { return Err(Box::new(io::Error::new(io::ErrorKind::Other, "no input"))); }; if let Some(files) = matches.get_many::("FILE") { for f in files { let mut opts = OpenOptions::new(); let opts = opts.read(true).write(true); let fd = opts.open(f)?; if matches.get_flag("data") { unistd::fdatasync(&fd)?; } else if matches.get_flag("fs") { unistd::syncfs(&fd)?; } else { unistd::fsync(&fd)?; } } } else { unistd::sync(); } Ok(()) } fn path(&self) -> Option { Some(crate::Path::Bin) } }