lib.rs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. #![no_std]
  2. #![allow(non_camel_case_types)]
  3. #![feature(alloc, allocator_api, const_vec_new)]
  4. //TODO #![feature(thread_local)]
  5. #[cfg_attr(target_os = "redox", macro_use)]
  6. extern crate alloc;
  7. #[cfg(all(not(feature = "no_std"), target_os = "linux"))]
  8. #[macro_use]
  9. extern crate sc;
  10. #[cfg(all(not(feature = "no_std"), target_os = "redox"))]
  11. pub extern crate syscall;
  12. pub use allocator::*;
  13. #[cfg(not(feature = "ralloc"))]
  14. #[path = "allocator/dlmalloc.rs"]
  15. mod allocator;
  16. #[cfg(feature = "ralloc")]
  17. #[path = "allocator/ralloc.rs"]
  18. mod allocator;
  19. pub use sys::*;
  20. #[cfg(all(not(feature = "no_std"), target_os = "linux"))]
  21. #[path = "linux/mod.rs"]
  22. mod sys;
  23. #[cfg(all(not(feature = "no_std"), target_os = "redox"))]
  24. #[path = "redox/mod.rs"]
  25. mod sys;
  26. pub mod types;
  27. use alloc::Vec;
  28. use core::{fmt, ptr};
  29. use types::*;
  30. #[global_allocator]
  31. static ALLOCATOR: Allocator = Allocator;
  32. pub const AF_INET: c_int = 2;
  33. pub const SOCK_STREAM: c_int = 1;
  34. pub const SOCK_DGRAM: c_int = 2;
  35. pub const SOCK_NONBLOCK: c_int = 0o4000;
  36. pub const SOCK_CLOEXEC: c_int = 0o2000000;
  37. pub type in_addr_t = [u8; 4];
  38. pub type in_port_t = u16;
  39. pub type sa_family_t = u16;
  40. pub type socklen_t = u32;
  41. pub struct sockaddr {
  42. pub sa_family: sa_family_t,
  43. pub data: [c_char; 14],
  44. }
  45. //TODO #[thread_local]
  46. #[allow(non_upper_case_globals)]
  47. #[no_mangle]
  48. pub static mut errno: c_int = 0;
  49. #[allow(non_upper_case_globals)]
  50. #[no_mangle]
  51. pub static mut environ: *mut *mut c_char = ptr::null_mut();
  52. #[allow(non_upper_case_globals)]
  53. pub static mut inner_environ: Vec<*mut c_char> = Vec::new();
  54. pub unsafe fn c_str_mut<'a>(s: *mut c_char) -> &'a mut [u8] {
  55. use core::usize;
  56. c_str_n_mut(s, usize::MAX)
  57. }
  58. pub unsafe fn c_str_n_mut<'a>(s: *mut c_char, n: usize) -> &'a mut [u8] {
  59. use core::slice;
  60. let mut size = 0;
  61. for _ in 0..n {
  62. if *s.offset(size) == 0 {
  63. break;
  64. }
  65. size += 1;
  66. }
  67. slice::from_raw_parts_mut(s as *mut u8, size as usize)
  68. }
  69. pub unsafe fn c_str<'a>(s: *const c_char) -> &'a [u8] {
  70. use core::usize;
  71. c_str_n(s, usize::MAX)
  72. }
  73. pub unsafe fn c_str_n<'a>(s: *const c_char, n: usize) -> &'a [u8] {
  74. use core::slice;
  75. let mut size = 0;
  76. for _ in 0..n {
  77. if *s.offset(size) == 0 {
  78. break;
  79. }
  80. size += 1;
  81. }
  82. slice::from_raw_parts(s as *const u8, size as usize)
  83. }
  84. pub unsafe fn cstr_from_bytes_with_nul_unchecked(bytes: &[u8]) -> *const c_char {
  85. bytes.as_ptr() as *const c_char
  86. }
  87. // NOTE: defined here rather than in string because memcpy() is useful in multiple crates
  88. pub unsafe fn memcpy(s1: *mut c_void, s2: *const c_void, n: usize) -> *mut c_void {
  89. let mut i = 0;
  90. while i + 7 < n {
  91. *(s1.offset(i as isize) as *mut u64) = *(s2.offset(i as isize) as *const u64);
  92. i += 8;
  93. }
  94. while i < n {
  95. *(s1 as *mut u8).offset(i as isize) = *(s2 as *const u8).offset(i as isize);
  96. i += 1;
  97. }
  98. s1
  99. }
  100. pub trait Write: fmt::Write {
  101. fn write_u8(&mut self, byte: u8) -> fmt::Result;
  102. }
  103. impl<'a, W: Write> Write for &'a mut W {
  104. fn write_u8(&mut self, byte: u8) -> fmt::Result {
  105. (**self).write_u8(byte)
  106. }
  107. }
  108. pub trait Read {
  109. fn read_u8(&mut self, byte: &mut u8) -> bool;
  110. }
  111. impl<'a, R: Read> Read for &'a mut R {
  112. fn read_u8(&mut self, byte: &mut u8) -> bool {
  113. (**self).read_u8(byte)
  114. }
  115. }
  116. pub struct FileWriter(pub c_int);
  117. impl FileWriter {
  118. pub fn write(&mut self, buf: &[u8]) -> isize {
  119. write(self.0, buf)
  120. }
  121. }
  122. impl fmt::Write for FileWriter {
  123. fn write_str(&mut self, s: &str) -> fmt::Result {
  124. self.write(s.as_bytes());
  125. Ok(())
  126. }
  127. }
  128. impl Write for FileWriter {
  129. fn write_u8(&mut self, byte: u8) -> fmt::Result {
  130. self.write(&[byte]);
  131. Ok(())
  132. }
  133. }
  134. pub struct FileReader(pub c_int);
  135. impl FileReader {
  136. pub fn read(&mut self, buf: &mut [u8]) -> isize {
  137. read(self.0, buf)
  138. }
  139. }
  140. impl Read for FileReader {
  141. fn read_u8(&mut self, byte: &mut u8) -> bool {
  142. let mut buf = [*byte];
  143. let n = self.read(&mut buf);
  144. *byte = buf[0];
  145. n > 0
  146. }
  147. }
  148. pub struct StringWriter(pub *mut u8, pub usize);
  149. impl StringWriter {
  150. pub unsafe fn write(&mut self, buf: &[u8]) {
  151. if self.1 > 0 {
  152. let copy_size = buf.len().min(self.1 - 1);
  153. memcpy(
  154. self.0 as *mut c_void,
  155. buf.as_ptr() as *const c_void,
  156. copy_size,
  157. );
  158. *self.0.offset(copy_size as isize) = b'\0';
  159. // XXX: i believe this correctly mimics the behavior from before, but it seems
  160. // incorrect (the next write will write after the NUL)
  161. self.0 = self.0.offset(copy_size as isize + 1);
  162. self.1 -= copy_size + 1;
  163. }
  164. }
  165. }
  166. impl fmt::Write for StringWriter {
  167. fn write_str(&mut self, s: &str) -> fmt::Result {
  168. unsafe { self.write(s.as_bytes()) };
  169. Ok(())
  170. }
  171. }
  172. impl Write for StringWriter {
  173. fn write_u8(&mut self, byte: u8) -> fmt::Result {
  174. unsafe { self.write(&[byte]) };
  175. Ok(())
  176. }
  177. }
  178. pub struct UnsafeStringWriter(pub *mut u8);
  179. impl UnsafeStringWriter {
  180. pub unsafe fn write(&mut self, buf: &[u8]) {
  181. memcpy(
  182. self.0 as *mut c_void,
  183. buf.as_ptr() as *const c_void,
  184. buf.len(),
  185. );
  186. *self.0.offset(buf.len() as isize) = b'\0';
  187. self.0 = self.0.offset(buf.len() as isize);
  188. }
  189. }
  190. impl fmt::Write for UnsafeStringWriter {
  191. fn write_str(&mut self, s: &str) -> fmt::Result {
  192. unsafe { self.write(s.as_bytes()) };
  193. Ok(())
  194. }
  195. }
  196. impl Write for UnsafeStringWriter {
  197. fn write_u8(&mut self, byte: u8) -> fmt::Result {
  198. unsafe { self.write(&[byte]) };
  199. Ok(())
  200. }
  201. }
  202. pub struct StringReader<'a>(pub &'a [u8]);
  203. impl<'a> Read for StringReader<'a> {
  204. fn read_u8(&mut self, byte: &mut u8) -> bool {
  205. if self.0.is_empty() {
  206. false
  207. } else {
  208. *byte = self.0[0];
  209. self.0 = &self.0[1..];
  210. true
  211. }
  212. }
  213. }
  214. pub struct UnsafeStringReader(pub *const u8);
  215. impl Read for UnsafeStringReader {
  216. fn read_u8(&mut self, byte: &mut u8) -> bool {
  217. unsafe {
  218. if *self.0 == 0 {
  219. false
  220. } else {
  221. *byte = *self.0;
  222. self.0 = self.0.offset(1);
  223. true
  224. }
  225. }
  226. }
  227. }