Commit c5405433 authored by dalance's avatar dalance

Add environment variables support

parent e25904f5
Pipeline #213259556 passed with stage
in 1 minute and 13 seconds
......@@ -77,7 +77,10 @@
//! reflect the fact that no Pager is active.
#![doc(html_root_url = "https://docs.rs/pager/0.15.0")]
#![cfg_attr(all(feature = "cargo-clippy", feature = "pedantic"), warn(clippy_pedantic))]
#![cfg_attr(
all(feature = "cargo-clippy", feature = "pedantic"),
warn(clippy_pedantic)
)]
extern crate errno;
extern crate libc;
......@@ -101,6 +104,7 @@ const DEFAULT_PAGER: &str = "more";
pub struct Pager {
default_pager: Option<OsString>,
pager: Option<OsString>,
envs: Vec<OsString>,
on: bool,
skip_on_notty: bool,
}
......@@ -110,6 +114,7 @@ impl Default for Pager {
Self {
default_pager: None,
pager: env::var_os(DEFAULT_PAGER_ENV),
envs: Vec::new(),
on: true,
skip_on_notty: true,
}
......@@ -155,6 +160,14 @@ impl Pager {
}
}
/// Launch pager with the specified environment variables
pub fn set_pager_envs(self, envs: &[&str]) -> Self {
Self {
envs: envs.into_iter().map(|x| x.into()).collect(),
..self
}
}
/// Instructs `Pager` to bypass invoking pager if output is not a `tty`
#[deprecated(since = "0.14.0", note = "'skip_on_notty' is default now")]
pub fn skip_on_notty(self) -> Self {
......@@ -208,7 +221,11 @@ impl Pager {
// I am parent
utils::dup2(pager_stdin, libc::STDIN_FILENO);
utils::close(main_stdout);
utils::execvp(pager);
if self.envs.is_empty() {
utils::execvp(pager);
} else {
utils::execvpe(pager, &self.envs);
}
}
}
} else {
......
......@@ -32,6 +32,30 @@ pub fn execvp(cmd: &OsString) {
unsafe { libc::execvp(args[0], args.as_ptr()) };
}
pub fn execvpe(cmd: &OsString, envs: &[OsString]) {
let cstrings = split_string(cmd)
.into_iter()
.map(osstring2cstring)
.collect::<Vec<_>>();
let mut args = cstrings.iter().map(|c| c.as_ptr()).collect::<Vec<_>>();
args.push(ptr::null());
let mut cstrings_envs = envs
.into_iter()
.map(|s| osstring2cstring(s.clone()))
.collect::<Vec<_>>();
for (mut k, v) in std::env::vars_os() {
k.push("=");
k.push(v);
cstrings_envs.push(osstring2cstring(k));
}
let mut envs = cstrings_envs.iter().map(|c| c.as_ptr()).collect::<Vec<_>>();
envs.push(ptr::null());
errno::set_errno(errno::Errno(0));
unsafe { libc::execvpe(args[0], args.as_ptr(), envs.as_ptr()) };
}
pub fn dup2(fd1: i32, fd2: i32) {
assert!(unsafe { libc::dup2(fd1, fd2) } > -1);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment