d248f7d17b
derive(Default) from applets
86 lines
2.9 KiB
Rust
86 lines
2.9 KiB
Rust
use super::Cmd;
|
|
use clap::{Arg, ArgAction, Command, ValueHint};
|
|
use std::{ffi::CString, fs, io, path::PathBuf};
|
|
|
|
#[derive(Debug)]
|
|
pub struct MkTemp;
|
|
|
|
impl Cmd for MkTemp {
|
|
fn cli(&self) -> clap::Command {
|
|
Command::new("mktemp")
|
|
.about("create a unique temporary file")
|
|
.author("Nathan Fisher")
|
|
.version(env!("CARGO_PKG_VERSION"))
|
|
.args([
|
|
Arg::new("directory")
|
|
.short('d')
|
|
.long("directory")
|
|
.help("create a directory instead of a file")
|
|
.action(ArgAction::SetTrue),
|
|
Arg::new("tmpdir")
|
|
.short('p')
|
|
.long("tmpdir")
|
|
.help("specify the directory to create temporary files in")
|
|
.value_hint(ValueHint::DirPath)
|
|
.num_args(1),
|
|
Arg::new("prefix")
|
|
.short('t')
|
|
.long("template")
|
|
.help("specify a prefix to append to the created files")
|
|
.num_args(1),
|
|
Arg::new("dryrun")
|
|
.short('u')
|
|
.long("dryrun")
|
|
.help("immediately remove created files and directories")
|
|
.action(ArgAction::SetTrue),
|
|
])
|
|
}
|
|
|
|
fn run(&self, matches: &clap::ArgMatches) -> Result<(), Box<dyn std::error::Error>> {
|
|
let mut path = if let Some(t) = matches.get_one::<String>("tmpdir") {
|
|
PathBuf::from(t)
|
|
} else {
|
|
PathBuf::from("/tmp")
|
|
};
|
|
let fname = if let Some(p) = matches.get_one::<String>("prefix") {
|
|
format!("{p}.XXXXXX")
|
|
} else {
|
|
"mktemp.XXXXXX".to_string()
|
|
};
|
|
path.push(&fname);
|
|
let fname = path
|
|
.to_str()
|
|
.ok_or(io::Error::new(io::ErrorKind::Other, "utf8 error"))?;
|
|
let cname = CString::new(fname)?;
|
|
let ptr = cname.into_raw();
|
|
if matches.get_flag("directory") {
|
|
let raw_fd = unsafe { libc::mkdtemp(ptr) };
|
|
if raw_fd.is_null() {
|
|
return Err(io::Error::last_os_error().into());
|
|
}
|
|
let cname = unsafe { CString::from_raw(ptr) };
|
|
let fname = cname.to_str()?;
|
|
println!("{fname}");
|
|
if matches.get_flag("dryrun") {
|
|
fs::remove_dir(fname)?;
|
|
}
|
|
} else {
|
|
let raw_fd = unsafe { libc::mkstemp(ptr) };
|
|
if raw_fd == -1 {
|
|
return Err(io::Error::last_os_error().into());
|
|
}
|
|
let cname = unsafe { CString::from_raw(ptr) };
|
|
let fname = cname.to_str()?;
|
|
println!("{fname}");
|
|
if matches.get_flag("dryrun") {
|
|
fs::remove_file(fname)?;
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
fn path(&self) -> Option<shitbox::Path> {
|
|
Some(shitbox::Path::UsrBin)
|
|
}
|
|
}
|