mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-27 10:13:28 +04:00
63 lines
1.8 KiB
Rust
63 lines
1.8 KiB
Rust
|
use alloc::string::String;
|
||
|
use alloc::vec::Vec;
|
||
|
use alloc::collections::btree_map::BTreeMap;
|
||
|
use core::ptr::null;
|
||
|
|
||
|
pub struct ProcInitInfo {
|
||
|
pub args: Vec<String>,
|
||
|
pub envs: BTreeMap<String, String>,
|
||
|
// pub auxv: Vec<String>,
|
||
|
}
|
||
|
|
||
|
impl ProcInitInfo {
|
||
|
pub unsafe fn push_at(&self, stack_top: usize) -> usize {
|
||
|
let mut writer = StackWriter { sp: stack_top };
|
||
|
// from stack_top:
|
||
|
// program name
|
||
|
writer.push_str(&self.args[0]);
|
||
|
// environment strings
|
||
|
let envs: Vec<_> = self.envs.iter().map(|(key, value)| {
|
||
|
writer.push_str(value.as_str());
|
||
|
writer.push_slice(&[b"="]);
|
||
|
writer.push_slice(key.as_bytes());
|
||
|
writer.sp
|
||
|
}).collect();
|
||
|
// argv strings
|
||
|
let argv: Vec<_> = self.args.iter().map(|arg| {
|
||
|
writer.push_str(arg.as_str());
|
||
|
writer.sp
|
||
|
}).collect();
|
||
|
// TODO: auxiliary vector entries
|
||
|
writer.push_slice(&[null::<u8>()]);
|
||
|
// envionment pointers
|
||
|
writer.push_slice(&[null::<u8>()]);
|
||
|
writer.push_slice(envs.as_slice());
|
||
|
// argv pointers
|
||
|
writer.push_slice(&[null::<u8>()]);
|
||
|
writer.push_slice(argv.as_slice());
|
||
|
// argc
|
||
|
writer.push_slice(&[argv.len()]);
|
||
|
writer.sp
|
||
|
}
|
||
|
}
|
||
|
|
||
|
struct StackWriter {
|
||
|
sp: usize,
|
||
|
}
|
||
|
|
||
|
impl StackWriter {
|
||
|
fn push_slice<T: Copy>(&mut self, vs: &[T]) {
|
||
|
use core::{mem::{size_of, align_of}, slice};
|
||
|
self.sp -= vs.len() * size_of::<T>();
|
||
|
self.sp -= self.sp % align_of::<T>();
|
||
|
unsafe { slice::from_raw_parts_mut(self.sp as *mut T, vs.len()) }
|
||
|
.copy_from_slice(vs);
|
||
|
}
|
||
|
fn push_str(&mut self, s: &str) {
|
||
|
self.push_slice(&[b'\0']);
|
||
|
self.push_slice(s.as_bytes());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|