|
|
@ -81,6 +81,12 @@ pub unsafe extern "C" fn main( |
|
|
|
} |
|
|
|
state.args = Some(slice::from_raw_parts(args_ptr, args_len)); |
|
|
|
|
|
|
|
// Initialize `arg_preopens`.
|
|
|
|
let preopens: &'static [Preopen] = |
|
|
|
unsafe { std::slice::from_raw_parts(preopens.base, preopens.len) }; |
|
|
|
state.process_preopens(&preopens); |
|
|
|
state.arg_preopens.set(Some(preopens)); |
|
|
|
|
|
|
|
Ok(()) |
|
|
|
}); |
|
|
|
|
|
|
@ -2289,9 +2295,13 @@ struct State { |
|
|
|
/// to take care of initialization.
|
|
|
|
env_vars: Cell<Option<&'static [StrTuple]>>, |
|
|
|
|
|
|
|
/// Preopened directories passed along with `main` args. Access with
|
|
|
|
/// `State::get_preopens` to take care of initialization.
|
|
|
|
arg_preopens: Cell<Option<&'static [Preopen]>>, |
|
|
|
|
|
|
|
/// Preopened directories. Initialized lazily. Access with `State::get_preopens`
|
|
|
|
/// to take care of initialization.
|
|
|
|
preopens: Cell<Option<&'static [Preopen]>>, |
|
|
|
env_preopens: Cell<Option<&'static [Preopen]>>, |
|
|
|
|
|
|
|
/// Cache for the `fd_readdir` call for a final `wasi::Dirent` plus path
|
|
|
|
/// name that didn't fit into the caller's buffer.
|
|
|
@ -2369,7 +2379,7 @@ const fn bump_arena_size() -> usize { |
|
|
|
start -= size_of::<DirentCache>(); |
|
|
|
|
|
|
|
// Remove miscellaneous metadata also stored in state.
|
|
|
|
start -= 24 * size_of::<usize>(); |
|
|
|
start -= 25 * size_of::<usize>(); |
|
|
|
|
|
|
|
// Everything else is the `command_data` allocation.
|
|
|
|
start |
|
|
@ -2478,7 +2488,8 @@ impl State { |
|
|
|
long_lived_arena: BumpArena::new(), |
|
|
|
args: None, |
|
|
|
env_vars: Cell::new(None), |
|
|
|
preopens: Cell::new(None), |
|
|
|
arg_preopens: Cell::new(None), |
|
|
|
env_preopens: Cell::new(None), |
|
|
|
dirent_cache: DirentCache { |
|
|
|
stream: Cell::new(None), |
|
|
|
for_fd: Cell::new(0), |
|
|
@ -2678,8 +2689,9 @@ impl State { |
|
|
|
self.env_vars.get().trapping_unwrap() |
|
|
|
} |
|
|
|
|
|
|
|
fn get_preopens(&self) -> &[Preopen] { |
|
|
|
if self.preopens.get().is_none() { |
|
|
|
fn get_preopens(&self) -> (Option<&[Preopen]>, &[Preopen]) { |
|
|
|
// Lazily initialize `env_preopens`.
|
|
|
|
if self.env_preopens.get().is_none() { |
|
|
|
#[link(wasm_import_module = "environment-preopens")] |
|
|
|
extern "C" { |
|
|
|
#[link_name = "preopens"] |
|
|
@ -2698,26 +2710,47 @@ impl State { |
|
|
|
// cast this to a &'static slice:
|
|
|
|
std::slice::from_raw_parts(list.base, list.len) |
|
|
|
}; |
|
|
|
for preopen in preopens { |
|
|
|
// Expectation is that the descriptor index is initialized with
|
|
|
|
// stdio (0,1,2) and no others, so that preopens are 3..
|
|
|
|
self.push_desc(Descriptor::Streams(Streams { |
|
|
|
input: Cell::new(None), |
|
|
|
output: Cell::new(None), |
|
|
|
type_: StreamType::File(File { |
|
|
|
fd: preopen.descriptor, |
|
|
|
position: Cell::new(0), |
|
|
|
append: false, |
|
|
|
}), |
|
|
|
})) |
|
|
|
.trapping_unwrap(); |
|
|
|
} |
|
|
|
self.preopens.set(Some(preopens)); |
|
|
|
self.process_preopens(preopens); |
|
|
|
self.env_preopens.set(Some(preopens)); |
|
|
|
} |
|
|
|
self.preopens.get().trapping_unwrap() |
|
|
|
|
|
|
|
let arg_preopens = self.arg_preopens.get(); |
|
|
|
let env_preopens = self.env_preopens.get().trapping_unwrap(); |
|
|
|
(arg_preopens, env_preopens) |
|
|
|
} |
|
|
|
|
|
|
|
fn get_preopen(&self, fd: Fd) -> Option<&Preopen> { |
|
|
|
self.get_preopens().get(fd.checked_sub(3)? as usize) |
|
|
|
// Lazily initialize the preopens and obtain the two slices.
|
|
|
|
let (arg_preopens, env_preopens) = self.get_preopens(); |
|
|
|
|
|
|
|
// Subtract 3 or the stdio indices to compute the preopen index.
|
|
|
|
let index = fd.checked_sub(3)? as usize; |
|
|
|
|
|
|
|
// Index into the conceptually concatenated preopen slices.
|
|
|
|
if let Some(arg_preopens) = arg_preopens { |
|
|
|
if let Some(preopen) = arg_preopens.get(index) { |
|
|
|
return Some(preopen); |
|
|
|
} |
|
|
|
env_preopens.get(index - arg_preopens.len()) |
|
|
|
} else { |
|
|
|
env_preopens.get(index) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
fn process_preopens(&self, preopens: &[Preopen]) { |
|
|
|
for preopen in preopens { |
|
|
|
// Expectation is that the descriptor index is initialized with
|
|
|
|
// stdio (0,1,2) and no others, so that preopens are 3..
|
|
|
|
self.push_desc(Descriptor::Streams(Streams { |
|
|
|
input: Cell::new(None), |
|
|
|
output: Cell::new(None), |
|
|
|
type_: StreamType::File(File { |
|
|
|
fd: preopen.descriptor, |
|
|
|
position: Cell::new(0), |
|
|
|
append: false, |
|
|
|
}), |
|
|
|
})) |
|
|
|
.trapping_unwrap(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|