sysinfo.rs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. use crate::{
  2. io::Buffer as _,
  3. kernel::{
  4. constants::{CLOCK_MONOTONIC, CLOCK_REALTIME, EINTR, EINVAL},
  5. task::Thread,
  6. timer::{Instant, Ticks},
  7. user::{UserBuffer, UserPointerMut},
  8. },
  9. prelude::*,
  10. };
  11. use posix_types::{
  12. stat::{TimeSpec, TimeVal},
  13. syscall_no::*,
  14. };
  15. #[derive(Clone, Copy)]
  16. struct NewUTSName {
  17. sysname: [u8; 65],
  18. nodename: [u8; 65],
  19. release: [u8; 65],
  20. version: [u8; 65],
  21. machine: [u8; 65],
  22. domainname: [u8; 65],
  23. }
  24. fn copy_cstr_to_array(cstr: &[u8], array: &mut [u8]) {
  25. let len = cstr.len().min(array.len() - 1);
  26. array[..len].copy_from_slice(&cstr[..len]);
  27. array[len] = 0;
  28. }
  29. #[eonix_macros::define_syscall(SYS_NEWUNAME)]
  30. fn newuname(buffer: *mut NewUTSName) -> KResult<()> {
  31. let buffer = UserPointerMut::new(buffer)?;
  32. let mut uname = NewUTSName {
  33. sysname: [0; 65],
  34. nodename: [0; 65],
  35. release: [0; 65],
  36. version: [0; 65],
  37. machine: [0; 65],
  38. domainname: [0; 65],
  39. };
  40. // Linux compatible
  41. copy_cstr_to_array(b"Linux", &mut uname.sysname);
  42. copy_cstr_to_array(b"(none)", &mut uname.nodename);
  43. copy_cstr_to_array(b"5.17.1", &mut uname.release);
  44. copy_cstr_to_array(b"eonix 1.1.4", &mut uname.version);
  45. #[cfg(target_arch = "x86_64")]
  46. copy_cstr_to_array(b"x86", &mut uname.machine);
  47. #[cfg(target_arch = "riscv64")]
  48. copy_cstr_to_array(b"riscv64", &mut uname.machine);
  49. copy_cstr_to_array(b"(none)", &mut uname.domainname);
  50. buffer.write(uname)
  51. }
  52. #[eonix_macros::define_syscall(SYS_GETTIMEOFDAY)]
  53. fn gettimeofday(timeval: *mut TimeVal, timezone: *mut ()) -> KResult<()> {
  54. if !timezone.is_null() {
  55. return Err(EINVAL);
  56. }
  57. if !timeval.is_null() {
  58. let timeval = UserPointerMut::new(timeval)?;
  59. let now = Instant::now();
  60. let since_epoch = now.since_epoch();
  61. timeval.write(TimeVal {
  62. tv_sec: since_epoch.as_secs(),
  63. tv_usec: since_epoch.subsec_micros(),
  64. })?;
  65. }
  66. Ok(())
  67. }
  68. fn do_clock_gettime64(_thread: &Thread, clock_id: u32, timespec: *mut TimeSpec) -> KResult<()> {
  69. if clock_id != CLOCK_REALTIME && clock_id != CLOCK_MONOTONIC {
  70. unimplemented!("Unsupported clock_id: {}", clock_id);
  71. }
  72. let timespec = UserPointerMut::new(timespec)?;
  73. let now = Instant::now();
  74. let since_epoch = now.since_epoch();
  75. timespec.write(TimeSpec {
  76. tv_sec: since_epoch.as_secs(),
  77. tv_nsec: since_epoch.subsec_nanos(),
  78. })
  79. }
  80. #[cfg(not(target_arch = "x86_64"))]
  81. #[eonix_macros::define_syscall(SYS_CLOCK_GETTIME)]
  82. fn clock_gettime(clock_id: u32, timespec: *mut TimeSpec) -> KResult<()> {
  83. do_clock_gettime64(thread, clock_id, timespec)
  84. }
  85. #[cfg(target_arch = "x86_64")]
  86. #[eonix_macros::define_syscall(SYS_CLOCK_GETTIME64)]
  87. fn clock_gettime64(clock_id: u32, timespec: *mut TimeSpec) -> KResult<()> {
  88. do_clock_gettime64(thread, clock_id, timespec)
  89. }
  90. #[repr(C)]
  91. #[derive(Clone, Copy)]
  92. struct Sysinfo {
  93. uptime: u32,
  94. loads: [u32; 3],
  95. totalram: u32,
  96. freeram: u32,
  97. sharedram: u32,
  98. bufferram: u32,
  99. totalswap: u32,
  100. freeswap: u32,
  101. procs: u16,
  102. totalhigh: u32,
  103. freehigh: u32,
  104. mem_unit: u32,
  105. _padding: [u8; 8],
  106. }
  107. #[eonix_macros::define_syscall(SYS_SYSINFO)]
  108. fn sysinfo(info: *mut Sysinfo) -> KResult<()> {
  109. let info = UserPointerMut::new(info)?;
  110. info.write(Sysinfo {
  111. uptime: Ticks::since_boot().as_secs() as u32,
  112. loads: [0; 3],
  113. totalram: 100,
  114. freeram: 50,
  115. sharedram: 0,
  116. bufferram: 0,
  117. totalswap: 0,
  118. freeswap: 0,
  119. procs: 10,
  120. totalhigh: 0,
  121. freehigh: 0,
  122. mem_unit: 1024,
  123. _padding: [0; 8],
  124. })
  125. }
  126. #[repr(C)]
  127. #[derive(Clone, Copy)]
  128. struct TMS {
  129. tms_utime: u32,
  130. tms_stime: u32,
  131. tms_cutime: u32,
  132. tms_cstime: u32,
  133. }
  134. #[eonix_macros::define_syscall(SYS_TIMES)]
  135. fn times(tms: *mut TMS) -> KResult<()> {
  136. let tms = UserPointerMut::new(tms)?;
  137. tms.write(TMS {
  138. tms_utime: 0,
  139. tms_stime: 0,
  140. tms_cutime: 0,
  141. tms_cstime: 0,
  142. })
  143. }
  144. #[eonix_macros::define_syscall(SYS_GETRANDOM)]
  145. fn get_random(buf: *mut u8, len: usize, flags: u32) -> KResult<usize> {
  146. if flags != 0 {
  147. return Err(EINVAL);
  148. }
  149. let mut buffer = UserBuffer::new(buf, len)?;
  150. for i in (0u8..=255).cycle().step_by(53) {
  151. let _ = buffer.fill(&[i])?;
  152. if Thread::current().signal_list.has_pending_signal() {
  153. return Err(EINTR);
  154. }
  155. }
  156. Ok(len)
  157. }
  158. pub fn keep_alive() {}