use crate::info;
use crate::target::os::syscall;
pub mod entry;
pub use entry::*;
#[repr(C)]
#[derive(Debug)]
pub struct List {
pub counter: usize,
pub former: *mut Entry,
pub latter: *mut Entry,
}
impl Default for List {
fn default() -> List {
List {
counter: 0,
former: core::ptr::null_mut(),
latter: core::ptr::null_mut(),
}
}
}
use crate::target::arch::{Pointer, PointerType};
impl List {
#[rustfmt::skip]
pub fn from_pointer(environment_pointer: Pointer) -> (List, Pointer) {
let environment_pointer: *mut PointerType = environment_pointer.0 as *mut PointerType;
let mut counter = 0;
unsafe {
while !(*environment_pointer.add(counter)).is_null() {
counter += 1;
}
}
let auxiliary_pointer = unsafe { (environment_pointer as PointerType).add(1 + counter) };
if counter == 0 {
return (List::default(), Pointer(auxiliary_pointer));
}
let list_pointer = crate::memory::alloc::<Entry>(counter);
unsafe {
for a in 0..counter {
let entry_pointer = *(environment_pointer.add(a));
let entry = Entry::from_pointer(Pointer(entry_pointer));
core::ptr::write(list_pointer.add(a), entry);
}
for a in 0..counter {
let entry = list_pointer.add(a);
(*entry).prev = if a == 0 { core::ptr::null_mut() } else { list_pointer.add(a - 1) };
(*entry).next = if a + 1 == counter { core::ptr::null_mut() } else { list_pointer.add(a + 1) };
}
}
let list = List {
counter,
former: list_pointer,
latter: unsafe { list_pointer.add(counter - 1) },
};
(list, Pointer(auxiliary_pointer))
}
pub fn print(&self) {
info!("Environment {{\n");
for a in 0..self.counter {
if let Some(e) = self.get(a) {
info!(
"\t{:?} @ {:?}\n",
unsafe { Pointer(self.former.add(a) as PointerType) },
e
);
}
}
info!("}} Environment \n");
}
pub fn print_arguments(&self) {
info!("Environment count: {}\n", self.counter);
for a in 0..self.counter {
if let Some(entry) = self.get(a) {
info!("Arg {}: '{:?}'\n", a, entry.pointer);
}
}
}
pub fn get(&self, index: usize) -> Option<&Entry> {
if index >= self.counter || self.former.is_null() {
return None;
}
unsafe { Some(&*self.former.add(index)) }
}
pub fn get_mut(&mut self, index: usize) -> Option<&mut Entry> {
if index >= self.counter || self.former.is_null() {
return None;
}
unsafe { Some(&mut *self.former.add(index)) }
}
pub fn len(&self) -> usize {
self.counter
}
pub fn is_empty(&self) -> bool {
self.counter == 0
}
}
pub struct Iter<'l> {
list: &'l List,
index: usize,
}
impl Drop for List {
fn drop(&mut self) {
if !self.former.is_null() && self.counter > 0 {
unsafe {
for a in 0..self.counter {
let entry_ptr = self.former.add(a);
core::ptr::drop_in_place(entry_ptr);
}
let total_size = core::mem::size_of::<Entry>() * self.counter as usize;
let aligned_size =
(total_size + crate::memory::page::SIZE - 1) & !(crate::memory::page::SIZE - 1);
let _ = syscall::munmap(self.former as *mut u8, aligned_size);
self.former = core::ptr::null_mut();
self.latter = core::ptr::null_mut();
self.counter = 0;
}
}
}
}
impl<'l> Iterator for Iter<'l> {
type Item = &'l Entry;
fn next(&mut self) -> Option<Self::Item> {
if self.index >= self.list.counter as usize {
return None;
}
let item = self.list.get(self.index);
self.index += 1;
item
}
}