mod.rs 8.3 KB

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