add environment variable configuration
This commit is contained in:
parent
f5273c1fd3
commit
795bdbe4d7
|
@ -1,3 +1,8 @@
|
|||
use std::{
|
||||
io::{BufRead, BufReader},
|
||||
path::PathBuf,
|
||||
};
|
||||
|
||||
use crate::platform::{self, Platform};
|
||||
use crate::result::{Context, Result};
|
||||
|
||||
|
@ -12,6 +17,31 @@ pub struct Config {
|
|||
pub platform: Option<Box<dyn Platform>>,
|
||||
pub mode: Mode,
|
||||
pub target: String,
|
||||
pub environment: Vec<String>,
|
||||
}
|
||||
|
||||
pub fn get_environment() -> Result<Vec<String>> {
|
||||
let mut environment = vec![];
|
||||
let environment_file = PathBuf::from("/etc/environment");
|
||||
|
||||
// NOTE: We should never have to care about permissions. Therefore, we don't use .try_exists()
|
||||
// As for TOCTOU... we're init, and this is the first code to run.
|
||||
if environment_file.exists() {
|
||||
let file = std::fs::File::open(&environment_file).context(format_args!(
|
||||
"could not open: {environment_file}",
|
||||
environment_file = environment_file.display(),
|
||||
))?;
|
||||
let reader = BufReader::new(file);
|
||||
for line in reader.lines() {
|
||||
let line = line.context(format_args!(
|
||||
"could not read line from: {environment_file}",
|
||||
environment_file = environment_file.display()
|
||||
))?;
|
||||
environment.push(line);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(environment)
|
||||
}
|
||||
|
||||
pub fn get_config() -> Result<Config> {
|
||||
|
@ -39,7 +69,16 @@ pub fn get_config() -> Result<Config> {
|
|||
|
||||
let platform = platform::get_current_platform(values.remove("platform").as_deref())?;
|
||||
|
||||
let target = values.remove("target").unwrap_or(String::from("/usr/bin/hello"));
|
||||
let target = values
|
||||
.remove("target")
|
||||
.unwrap_or(String::from("/usr/bin/hello"));
|
||||
|
||||
Ok(Config { platform, mode, target })
|
||||
let environment = get_environment()?;
|
||||
|
||||
Ok(Config {
|
||||
platform,
|
||||
mode,
|
||||
target,
|
||||
environment,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ fn main() {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
extern "C" fn handle_sigchld(_sig: i32) {
|
||||
// wait on all dead processes
|
||||
while system::syscall::waitpid(-1, libc::WNOHANG).is_ok() {
|
||||
|
@ -66,7 +67,8 @@ fn init() -> Result<()> {
|
|||
}
|
||||
config::Mode::Exec => {
|
||||
dmesg(format!("pivoting to {command}"));
|
||||
system::syscall::execv(command, &[])?;
|
||||
let envs = config.environment.iter().map(|e| &**e).collect::<Vec<_>>();
|
||||
system::syscall::execve(command, &[], &envs)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -193,7 +193,7 @@ pub fn close(fd: RawFd) -> Result<()> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn execv(command: impl AsRef<Path>, args: &[&str]) -> Result<()> {
|
||||
pub fn execve(command: impl AsRef<Path>, args: &[&str], envs: &[&str]) -> Result<()> {
|
||||
let command = command.as_ref();
|
||||
|
||||
let command_cstr = CString::new(command.as_os_str().as_encoded_bytes())
|
||||
|
@ -213,7 +213,21 @@ pub fn execv(command: impl AsRef<Path>, args: &[&str]) -> Result<()> {
|
|||
.chain(std::iter::once(std::ptr::null()))
|
||||
.collect();
|
||||
|
||||
if unsafe { libc::execv(command_cstr.as_ptr().cast(), args_ptrs.as_ptr().cast()) } == -1 {
|
||||
let mut envs_cstr = vec![command_cstr.clone()];
|
||||
for env in envs {
|
||||
let cur_env_cstr = CString::new(env.as_bytes()).context(format_args!("bad env: {env}"))?;
|
||||
envs_cstr.push(cur_env_cstr);
|
||||
}
|
||||
|
||||
// NOTE: The last env must be a null pointer, but we can't construct a CString from nullptr, so
|
||||
// we construct an array of pointers and use that
|
||||
let envs_ptrs: Vec<_> = envs_cstr
|
||||
.iter()
|
||||
.map(|s| s.as_ptr())
|
||||
.chain(std::iter::once(std::ptr::null()))
|
||||
.collect();
|
||||
|
||||
if unsafe { libc::execve(command_cstr.as_ptr().cast(), args_ptrs.as_ptr().cast(), envs_ptrs.as_ptr().cast()) } == -1 {
|
||||
return ctx_os_error(format_args!(
|
||||
"error calling exec({command}, {args:?})",
|
||||
command = command.display()
|
||||
|
|
Loading…
Reference in New Issue