Add mktemp
applet
This commit is contained in:
parent
5076dcc350
commit
754f604603
@ -13,9 +13,7 @@ impl Cmd for Hostid {
|
||||
}
|
||||
|
||||
fn run(&self, _matches: Option<&clap::ArgMatches>) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let hostid = unsafe {
|
||||
libc::gethostid()
|
||||
};
|
||||
let hostid = unsafe { libc::gethostid() };
|
||||
let hostid: String = format!("{hostid:x}").chars().skip(8).collect();
|
||||
println!("{}", hostid);
|
||||
Ok(())
|
||||
|
88
src/cmd/mktemp/mod.rs
Normal file
88
src/cmd/mktemp/mod.rs
Normal file
@ -0,0 +1,88 @@
|
||||
use super::Cmd;
|
||||
use clap::{Arg, ArgAction, Command, ValueHint};
|
||||
use std::{ffi::CString, fs, io, path::PathBuf};
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
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: Option<&clap::ArgMatches>) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let Some(matches) = matches else {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "no input").into());
|
||||
};
|
||||
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<crate::Path> {
|
||||
Some(crate::Path::UsrBin)
|
||||
}
|
||||
}
|
@ -30,6 +30,7 @@ mod logname;
|
||||
mod ls;
|
||||
mod mkfifo;
|
||||
mod mknod;
|
||||
mod mktemp;
|
||||
mod mountpoint;
|
||||
mod mv;
|
||||
mod nologin;
|
||||
@ -93,6 +94,7 @@ pub fn get(name: &str) -> Option<Box<dyn Cmd>> {
|
||||
"logname" => Some(Box::new(logname::Logname::default())),
|
||||
"mkfifo" => Some(Box::new(mkfifo::MkFifo::default())),
|
||||
"mknod" => Some(Box::new(mknod::MkNod::default())),
|
||||
"mktemp" => Some(Box::new(mktemp::MkTemp::default())),
|
||||
"mountpoint" => Some(Box::new(mountpoint::Mountpoint::default())),
|
||||
"nologin" => Some(Box::new(nologin::Nologin::default())),
|
||||
"nproc" => Some(Box::new(nproc::Nproc::default())),
|
||||
@ -116,7 +118,7 @@ pub fn get(name: &str) -> Option<Box<dyn Cmd>> {
|
||||
}
|
||||
}
|
||||
|
||||
pub static COMMANDS: [&str; 42] = [
|
||||
pub static COMMANDS: [&str; 43] = [
|
||||
"base32",
|
||||
"base64",
|
||||
"basename",
|
||||
@ -140,6 +142,7 @@ pub static COMMANDS: [&str; 42] = [
|
||||
"logname",
|
||||
"mkfifo",
|
||||
"mknod",
|
||||
"mktemp",
|
||||
"mountpoint",
|
||||
"nologin",
|
||||
"nproc",
|
||||
|
@ -1,13 +1,13 @@
|
||||
use super::Cmd;
|
||||
use crate::bitflags::BitFlags;
|
||||
use clap::{Arg, ArgMatches, Command, ArgAction};
|
||||
use clap::{Arg, ArgAction, ArgMatches, Command};
|
||||
use std::{
|
||||
cmp,
|
||||
error::Error,
|
||||
fmt::{self, Write},
|
||||
fs,
|
||||
io::{self, stdin, Read},
|
||||
ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, AddAssign},
|
||||
ops::{AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign},
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
@ -73,7 +73,9 @@ impl Cmd for Wc {
|
||||
name: "Total",
|
||||
..Values::default()
|
||||
};
|
||||
files.iter().try_for_each(|f| get_values(f, &mut totals, flags))?;
|
||||
files
|
||||
.iter()
|
||||
.try_for_each(|f| get_values(f, &mut totals, flags))?;
|
||||
if files.len() > 1 {
|
||||
totals.print_values(flags)?;
|
||||
}
|
||||
@ -85,7 +87,11 @@ impl Cmd for Wc {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_values<'a>(file: &'a str, totals: &mut Values<'a>, flags: u32) -> Result<(), Box<dyn Error>> {
|
||||
fn get_values<'a>(
|
||||
file: &'a str,
|
||||
totals: &mut Values<'a>,
|
||||
flags: u32,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
let contents = if file == "-" {
|
||||
let mut buf = String::new();
|
||||
stdin().read_to_string(&mut buf)?;
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::{bitflags::BitFlags, mode::Bit};
|
||||
use super::Cmd;
|
||||
use crate::{bitflags::BitFlags, mode::Bit};
|
||||
use clap::{Arg, Command};
|
||||
use std::{env, fs::File, io, os::unix::prelude::MetadataExt, path::PathBuf, process};
|
||||
|
||||
|
@ -96,4 +96,3 @@ impl Bit {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,11 @@ mod parser;
|
||||
mod who;
|
||||
use std::fmt::{self, Write};
|
||||
|
||||
pub use {bit::Bit, parser::{ParseError, Parser}, who::Who};
|
||||
pub use {
|
||||
bit::Bit,
|
||||
parser::{ParseError, Parser},
|
||||
who::Who,
|
||||
};
|
||||
|
||||
/// Gets the umask for the current user
|
||||
#[must_use]
|
||||
|
@ -1,10 +1,6 @@
|
||||
use crate::bitflags::BitFlags;
|
||||
use super::{get_umask, Bit, Who};
|
||||
use std::{
|
||||
error,
|
||||
fmt::Display,
|
||||
num::ParseIntError,
|
||||
};
|
||||
use crate::bitflags::BitFlags;
|
||||
use std::{error, fmt::Display, num::ParseIntError};
|
||||
|
||||
/// Errors which might occur when parsing Unix permissions from a string
|
||||
#[derive(Debug, PartialEq)]
|
||||
|
@ -46,4 +46,3 @@ impl BitOrAssign<Who> for u32 {
|
||||
*self = *self | rhs;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user