mod.rs 7.7 KB

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