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