summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordalance <dalance@gmail.com>2020-09-25 17:39:30 +0900
committerdalance <dalance@gmail.com>2020-09-25 17:39:30 +0900
commitc54054338cf1967ac7e71a816b60e386a96af58a (patch)
tree6c0e0372a9568364ba9863d52bbe03bd226e943c
parente25904f53e35415e9bd90f2fa609ee12868247b7 (diff)
Add environment variables support
-rw-r--r--src/lib.rs21
-rw-r--r--src/utils.rs24
2 files changed, 43 insertions, 2 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 80e2677..8c4c814 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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 {
diff --git a/src/utils.rs b/src/utils.rs
index a826e45..65bd8f8 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -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);
}