1 use crate::io::{self, Read, Write}; 2 use alloc::{boxed::Box, vec::Vec}; 3 use core::{fmt, ptr}; 4 5 pub use self::allocator::*; 6 7 #[cfg(not(feature = "ralloc"))] 8 #[path = "allocator/dlmalloc.rs"] 9 mod allocator; 10 11 #[cfg(feature = "ralloc")] 12 #[path = "allocator/ralloc.rs"] 13 mod allocator; 14 15 pub use self::pal::{Pal, PalEpoll, PalPtrace, PalSignal, PalSocket}; 16 17 mod pal; 18 19 pub use self::sys::{e, Sys}; 20 21 #[cfg(all(not(feature = "no_std"), target_os = "linux"))] 22 #[path = "linux/mod.rs"] 23 pub(crate) mod sys; 24 25 #[cfg(all(not(feature = "no_std"), target_os = "dragonos"))] 26 #[path = "dragonos/mod.rs"] 27 pub(crate) mod sys; 28 29 #[cfg(all(not(feature = "no_std"), target_os = "redox"))] 30 #[path = "redox/mod.rs"] 31 pub(crate) mod sys; 32 33 #[cfg(test)] 34 mod test; 35 36 mod pte; 37 38 pub use self::rlb::{Line, RawLineBuffer}; 39 pub mod rlb; 40 41 #[cfg(target_os = "linux")] 42 pub mod auxv_defs; 43 44 #[cfg(target_os = "dragonos")] 45 pub mod auxv_defs; 46 47 #[cfg(target_os = "redox")] 48 pub use redox_exec::auxv_defs; 49 50 use self::types::*; 51 pub mod types; 52 53 #[thread_local] 54 #[allow(non_upper_case_globals)] 55 #[no_mangle] 56 pub static mut errno: c_int = 0; 57 58 #[allow(non_upper_case_globals)] 59 pub static mut argv: *mut *mut c_char = ptr::null_mut(); 60 #[allow(non_upper_case_globals)] 61 pub static mut inner_argv: Vec<*mut c_char> = Vec::new(); 62 #[allow(non_upper_case_globals)] 63 pub static mut program_invocation_name: *mut c_char = ptr::null_mut(); 64 #[allow(non_upper_case_globals)] 65 pub static mut program_invocation_short_name: *mut c_char = ptr::null_mut(); 66 67 #[allow(non_upper_case_globals)] 68 #[no_mangle] 69 pub static mut environ: *mut *mut c_char = ptr::null_mut(); 70 71 pub static mut OUR_ENVIRON: Vec<*mut c_char> = Vec::new(); 72 73 pub fn environ_iter() -> impl Iterator<Item = *mut c_char> + 'static { 74 unsafe { 75 let mut ptrs = environ; 76 77 core::iter::from_fn(move || { 78 let ptr = ptrs.read(); 79 if ptr.is_null() { 80 None 81 } else { 82 ptrs = ptrs.add(1); 83 Some(ptr) 84 } 85 }) 86 } 87 } 88 89 pub trait WriteByte: fmt::Write { 90 fn write_u8(&mut self, byte: u8) -> fmt::Result; 91 } 92 93 impl<'a, W: WriteByte> WriteByte for &'a mut W { 94 fn write_u8(&mut self, byte: u8) -> fmt::Result { 95 (**self).write_u8(byte) 96 } 97 } 98 99 pub struct FileWriter(pub c_int); 100 101 impl FileWriter { 102 pub fn write(&mut self, buf: &[u8]) -> isize { 103 Sys::write(self.0, buf) 104 } 105 } 106 107 impl fmt::Write for FileWriter { 108 fn write_str(&mut self, s: &str) -> fmt::Result { 109 self.write(s.as_bytes()); 110 Ok(()) 111 } 112 } 113 114 impl WriteByte for FileWriter { 115 fn write_u8(&mut self, byte: u8) -> fmt::Result { 116 self.write(&[byte]); 117 Ok(()) 118 } 119 } 120 121 pub struct FileReader(pub c_int); 122 123 impl FileReader { 124 pub fn read(&mut self, buf: &mut [u8]) -> isize { 125 Sys::read(self.0, buf) 126 } 127 } 128 129 impl Read for FileReader { 130 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { 131 let i = Sys::read(self.0, buf); 132 if i >= 0 { 133 Ok(i as usize) 134 } else { 135 Err(io::Error::from_raw_os_error(-i as i32)) 136 } 137 } 138 } 139 140 pub struct StringWriter(pub *mut u8, pub usize); 141 impl Write for StringWriter { 142 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 143 if self.1 > 1 { 144 let copy_size = buf.len().min(self.1 - 1); 145 unsafe { 146 ptr::copy_nonoverlapping(buf.as_ptr(), self.0, copy_size); 147 self.1 -= copy_size; 148 149 self.0 = self.0.add(copy_size); 150 *self.0 = 0; 151 } 152 } 153 154 // Pretend the entire slice was written. This is because many functions 155 // (like snprintf) expects a return value that reflects how many bytes 156 // *would have* been written. So keeping track of this information is 157 // good, and then if we want the *actual* written size we can just go 158 // `cmp::min(written, maxlen)`. 159 Ok(buf.len()) 160 } 161 fn flush(&mut self) -> io::Result<()> { 162 Ok(()) 163 } 164 } 165 impl fmt::Write for StringWriter { 166 fn write_str(&mut self, s: &str) -> fmt::Result { 167 // can't fail 168 self.write(s.as_bytes()).unwrap(); 169 Ok(()) 170 } 171 } 172 impl WriteByte for StringWriter { 173 fn write_u8(&mut self, byte: u8) -> fmt::Result { 174 // can't fail 175 self.write(&[byte]).unwrap(); 176 Ok(()) 177 } 178 } 179 180 pub struct UnsafeStringWriter(pub *mut u8); 181 impl Write for UnsafeStringWriter { 182 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 183 unsafe { 184 ptr::copy_nonoverlapping(buf.as_ptr(), self.0, buf.len()); 185 self.0 = self.0.add(buf.len()); 186 *self.0 = b'\0'; 187 } 188 Ok(buf.len()) 189 } 190 fn flush(&mut self) -> io::Result<()> { 191 Ok(()) 192 } 193 } 194 impl fmt::Write for UnsafeStringWriter { 195 fn write_str(&mut self, s: &str) -> fmt::Result { 196 // can't fail 197 self.write(s.as_bytes()).unwrap(); 198 Ok(()) 199 } 200 } 201 impl WriteByte for UnsafeStringWriter { 202 fn write_u8(&mut self, byte: u8) -> fmt::Result { 203 // can't fail 204 self.write(&[byte]).unwrap(); 205 Ok(()) 206 } 207 } 208 209 pub struct UnsafeStringReader(pub *const u8); 210 impl Read for UnsafeStringReader { 211 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { 212 unsafe { 213 for i in 0..buf.len() { 214 if *self.0 == 0 { 215 return Ok(i); 216 } 217 218 buf[i] = *self.0; 219 self.0 = self.0.offset(1); 220 } 221 Ok(buf.len()) 222 } 223 } 224 } 225 226 pub struct CountingWriter<T> { 227 pub inner: T, 228 pub written: usize, 229 } 230 impl<T> CountingWriter<T> { 231 pub fn new(writer: T) -> Self { 232 Self { 233 inner: writer, 234 written: 0, 235 } 236 } 237 } 238 impl<T: fmt::Write> fmt::Write for CountingWriter<T> { 239 fn write_str(&mut self, s: &str) -> fmt::Result { 240 self.written += s.len(); 241 self.inner.write_str(s) 242 } 243 } 244 impl<T: WriteByte> WriteByte for CountingWriter<T> { 245 fn write_u8(&mut self, byte: u8) -> fmt::Result { 246 self.written += 1; 247 self.inner.write_u8(byte) 248 } 249 } 250 impl<T: Write> Write for CountingWriter<T> { 251 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 252 let res = self.inner.write(buf); 253 if let Ok(written) = res { 254 self.written += written; 255 } 256 res 257 } 258 fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { 259 match self.inner.write_all(&buf) { 260 Ok(()) => (), 261 Err(ref err) if err.kind() == io::ErrorKind::WriteZero => (), 262 Err(err) => return Err(err), 263 } 264 self.written += buf.len(); 265 Ok(()) 266 } 267 fn flush(&mut self) -> io::Result<()> { 268 self.inner.flush() 269 } 270 } 271 272 // TODO: Set a global variable once get_auxvs is called, and then implement getauxval based on 273 // get_auxv. 274 275 #[cold] 276 pub unsafe fn get_auxvs(mut ptr: *const usize) -> Box<[[usize; 2]]> { 277 //traverse the stack and collect argument environment variables 278 let mut auxvs = Vec::new(); 279 280 while *ptr != self::auxv_defs::AT_NULL { 281 let kind = ptr.read(); 282 ptr = ptr.add(1); 283 let value = ptr.read(); 284 ptr = ptr.add(1); 285 auxvs.push([kind, value]); 286 } 287 288 auxvs.sort_unstable_by_key(|[kind, _]| *kind); 289 auxvs.into_boxed_slice() 290 } 291 pub fn get_auxv(auxvs: &[[usize; 2]], key: usize) -> Option<usize> { 292 auxvs 293 .binary_search_by_key(&key, |[entry_key, _]| *entry_key) 294 .ok() 295 .map(|idx| auxvs[idx][1]) 296 } 297 298 #[cold] 299 #[cfg(target_os = "redox")] 300 pub fn init(auxvs: Box<[[usize; 2]]>) { 301 use self::auxv_defs::*; 302 303 if let (Some(cwd_ptr), Some(cwd_len)) = ( 304 get_auxv(&auxvs, AT_REDOX_INITIALCWD_PTR), 305 get_auxv(&auxvs, AT_REDOX_INITIALCWD_LEN), 306 ) { 307 let cwd_bytes: &'static [u8] = 308 unsafe { core::slice::from_raw_parts(cwd_ptr as *const u8, cwd_len) }; 309 if let Ok(cwd) = core::str::from_utf8(cwd_bytes) { 310 self::sys::path::setcwd_manual(cwd.into()); 311 } 312 } 313 } 314 #[cfg(not(target_os = "redox"))] 315 pub fn init(auxvs: Box<[[usize; 2]]>) {} 316