You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
125 lines
2.4 KiB
125 lines
2.4 KiB
use super::*;
|
|
use std::{
|
|
path::{Path,PathBuf,},
|
|
};
|
|
|
|
impl ProcessArgs
|
|
{
|
|
pub fn parse<T, U>(string: &mut T, not_last: &mut bool) -> Result<Self, &'static str>
|
|
where T: Iterator<Item=U>,
|
|
U: AsRef<str>
|
|
{
|
|
let name = string.next().ok_or("No process name")?.as_ref().to_owned();
|
|
let mut args = Vec::new();
|
|
*not_last = false;
|
|
while let Some(arg) = string.next() {
|
|
let arg = arg.as_ref();
|
|
let mut chars = arg.chars();
|
|
if let Some(BROKEN_PIPE) = chars.next() {
|
|
*not_last = true;
|
|
break;
|
|
} else {
|
|
args.push(arg.to_owned());
|
|
}
|
|
}
|
|
|
|
Ok(Self{
|
|
name,
|
|
args,
|
|
name_real: None,
|
|
})
|
|
}
|
|
|
|
pub fn name_path(&self) -> Result<&Path, &'static str>
|
|
{
|
|
if let Some(buf) = &self.name_real {
|
|
Ok(buf.as_ref())
|
|
} else {
|
|
Err("No name_path specified, have you called `verify()`?")
|
|
}
|
|
}
|
|
|
|
pub fn verify(&self) -> Result<PathBuf, &'static str>
|
|
{
|
|
if let Ok(spath) = std::env::var("LEAKY_PIPE_PATH") {
|
|
if let Some(path) = find_somewhere(&self.name, spath.split(':')) {
|
|
return Ok(path)
|
|
}
|
|
}
|
|
|
|
if let Ok(spath) = std::env::var("PATH") {
|
|
if let Some(path) = find_somewhere(&self.name, spath.split(':')) {
|
|
Ok(path)
|
|
} else {
|
|
Err("File not found")
|
|
}
|
|
} else {
|
|
match Path::new(&self.name) {
|
|
path if path.exists() => Ok(Path::new(&self.name).to_owned()),
|
|
_ => Err("File not found and $PATH not found.")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn find_somewhere<T,U,V>(name: T, places: U) -> Option<PathBuf>
|
|
where T: AsRef<str>,
|
|
U: IntoIterator<Item=V>,
|
|
V: AsRef<str>
|
|
{
|
|
let name = name.as_ref();
|
|
|
|
for place in places.into_iter()
|
|
{
|
|
let place = place.as_ref();
|
|
|
|
let pbuf = Path::new(&place).join(&name);
|
|
if pbuf.exists() {
|
|
return Some(pbuf);
|
|
}
|
|
}
|
|
|
|
None
|
|
}
|
|
|
|
fn escape<T>(s: &T) -> String
|
|
where T: AsRef<str> + ?Sized
|
|
{
|
|
let s = s.as_ref();
|
|
let mut o = String::with_capacity(s.len());
|
|
|
|
for c in s.chars() {
|
|
match c {
|
|
'\\' => {
|
|
o.push('\\');
|
|
o.push('\\');
|
|
},
|
|
'\'' => {
|
|
o.push('\\');
|
|
o.push('\'');
|
|
},
|
|
other => o.push(other),
|
|
};
|
|
}
|
|
|
|
o
|
|
}
|
|
|
|
use std::fmt;
|
|
impl fmt::Display for ProcessArgs
|
|
{
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
|
|
{
|
|
write!(f, "{} ", self.name)?;
|
|
let len = self.args.len();
|
|
for (i,x) in (0..len).zip(self.args.iter()) {
|
|
write!(f, "{}", &x)?;
|
|
if i < len-1 {
|
|
write!(f, " ")?;
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
}
|