procops.rs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804
  1. use super::SyscallNoReturn;
  2. use crate::io::Buffer;
  3. use crate::kernel::constants::{EINVAL, ENOENT, ENOTDIR, ERANGE, ESRCH};
  4. use crate::kernel::constants::{
  5. ENOSYS, PR_GET_NAME, PR_SET_NAME, RLIMIT_STACK, SIG_BLOCK, SIG_SETMASK, SIG_UNBLOCK,
  6. };
  7. use crate::kernel::mem::PageBuffer;
  8. use crate::kernel::task::{
  9. do_clone, futex_wait, futex_wake, FutexFlags, FutexOp, ProcessList, ProgramLoader,
  10. RobustListHead, SignalAction, Thread, WaitType,
  11. };
  12. use crate::kernel::task::{parse_futexop, CloneArgs};
  13. use crate::kernel::timer::sleep;
  14. use crate::kernel::user::dataflow::{CheckedUserPointer, UserString};
  15. use crate::kernel::user::{UserPointer, UserPointerMut};
  16. use crate::kernel::vfs::{self, dentry::Dentry};
  17. use crate::path::Path;
  18. use crate::{kernel::user::dataflow::UserBuffer, prelude::*};
  19. use alloc::borrow::ToOwned;
  20. use alloc::ffi::CString;
  21. use bitflags::bitflags;
  22. use core::ptr::NonNull;
  23. use core::time::Duration;
  24. use eonix_hal::processor::UserTLS;
  25. use eonix_hal::traits::trap::RawTrapContext;
  26. use eonix_mm::address::{Addr as _, VAddr};
  27. use eonix_runtime::task::Task;
  28. use eonix_sync::AsProof as _;
  29. use posix_types::constants::{P_ALL, P_PID};
  30. use posix_types::ctypes::PtrT;
  31. use posix_types::signal::{SigAction, SigInfo, SigSet, Signal};
  32. use posix_types::stat::TimeVal;
  33. use posix_types::{syscall_no::*, SIGNAL_NOW};
  34. #[repr(C)]
  35. #[derive(Debug, Clone, Copy)]
  36. struct RLimit {
  37. rlim_cur: u64,
  38. rlim_max: u64,
  39. }
  40. bitflags! {
  41. pub struct UserWaitOptions: u32 {
  42. const WNOHANG = 1;
  43. const WUNTRACED = 2;
  44. const WCONTINUED = 8;
  45. }
  46. }
  47. #[eonix_macros::define_syscall(SYS_NANOSLEEP)]
  48. fn nanosleep(req: *const (u32, u32), rem: *mut (u32, u32)) -> KResult<usize> {
  49. let req = UserPointer::new(req)?.read()?;
  50. let rem = if rem.is_null() {
  51. None
  52. } else {
  53. Some(UserPointerMut::new(rem)?)
  54. };
  55. let duration = Duration::from_secs(req.0 as u64) + Duration::from_nanos(req.1 as u64);
  56. Task::block_on(sleep(duration));
  57. if let Some(rem) = rem {
  58. rem.write((0, 0))?;
  59. }
  60. Ok(0)
  61. }
  62. #[eonix_macros::define_syscall(SYS_UMASK)]
  63. fn umask(mask: u32) -> KResult<u32> {
  64. let mut umask = thread.fs_context.umask.lock();
  65. let old = *umask;
  66. *umask = mask & 0o777;
  67. Ok(old)
  68. }
  69. #[eonix_macros::define_syscall(SYS_GETCWD)]
  70. fn getcwd(buffer: *mut u8, bufsize: usize) -> KResult<usize> {
  71. let mut user_buffer = UserBuffer::new(buffer, bufsize)?;
  72. let mut buffer = PageBuffer::new();
  73. let cwd = thread.fs_context.cwd.lock().clone();
  74. cwd.get_path(&thread.fs_context, &mut buffer)?;
  75. user_buffer.fill(buffer.data())?.ok_or(ERANGE)?;
  76. Ok(buffer.wrote())
  77. }
  78. #[eonix_macros::define_syscall(SYS_CHDIR)]
  79. fn chdir(path: *const u8) -> KResult<()> {
  80. let path = UserString::new(path)?;
  81. let path = Path::new(path.as_cstr().to_bytes())?;
  82. let dentry = Dentry::open(&thread.fs_context, path, true)?;
  83. if !dentry.is_valid() {
  84. return Err(ENOENT);
  85. }
  86. if !dentry.is_directory() {
  87. return Err(ENOTDIR);
  88. }
  89. *thread.fs_context.cwd.lock() = dentry;
  90. Ok(())
  91. }
  92. #[eonix_macros::define_syscall(SYS_MOUNT)]
  93. fn mount(source: *const u8, target: *const u8, fstype: *const u8, flags: usize) -> KResult<()> {
  94. let source = UserString::new(source)?;
  95. let target = UserString::new(target)?;
  96. let fstype = UserString::new(fstype)?;
  97. let mountpoint = Dentry::open(
  98. &thread.fs_context,
  99. Path::new(target.as_cstr().to_bytes())?,
  100. true,
  101. )?;
  102. if !mountpoint.is_valid() {
  103. return Err(ENOENT);
  104. }
  105. vfs::mount::do_mount(
  106. &mountpoint,
  107. source.as_cstr().to_str().map_err(|_| EINVAL)?,
  108. target.as_cstr().to_str().map_err(|_| EINVAL)?,
  109. fstype.as_cstr().to_str().map_err(|_| EINVAL)?,
  110. flags as u64,
  111. )
  112. }
  113. fn get_strings(mut ptr_strings: UserPointer<'_, PtrT>) -> KResult<Vec<CString>> {
  114. let mut strings = Vec::new();
  115. loop {
  116. let ptr = ptr_strings.read()?;
  117. if ptr.is_null() {
  118. break;
  119. }
  120. let user_string = UserString::new(ptr.addr() as *const u8)?;
  121. strings.push(user_string.as_cstr().to_owned());
  122. ptr_strings = ptr_strings.offset(1)?;
  123. }
  124. Ok(strings)
  125. }
  126. #[eonix_macros::define_syscall(SYS_EXECVE)]
  127. fn execve(exec: *const u8, argv: *const PtrT, envp: *const PtrT) -> KResult<SyscallNoReturn> {
  128. let exec = UserString::new(exec)?;
  129. let exec = exec.as_cstr().to_owned();
  130. let argv = get_strings(UserPointer::new(argv)?)?;
  131. let envp = get_strings(UserPointer::new(envp)?)?;
  132. let dentry = Dentry::open(&thread.fs_context, Path::new(exec.as_bytes())?, true)?;
  133. if !dentry.is_valid() {
  134. Err(ENOENT)?;
  135. }
  136. // TODO: When `execve` is called by one of the threads in a process, the other threads
  137. // should be terminated and `execve` is performed in the thread group leader.
  138. let load_info =
  139. ProgramLoader::parse(&thread.fs_context, exec, dentry.clone(), argv, envp)?.load()?;
  140. if let Some(robust_list) = thread.get_robust_list() {
  141. let _ = Task::block_on(robust_list.wake_all());
  142. thread.set_robust_list(None);
  143. }
  144. unsafe {
  145. // SAFETY: We are doing execve, all other threads are terminated.
  146. thread.process.mm_list.replace(Some(load_info.mm_list));
  147. }
  148. thread.files.on_exec();
  149. thread.signal_list.clear_non_ignore();
  150. thread.set_name(dentry.get_name());
  151. let mut trap_ctx = thread.trap_ctx.borrow();
  152. trap_ctx.set_program_counter(load_info.entry_ip.addr());
  153. trap_ctx.set_stack_pointer(load_info.sp.addr());
  154. Ok(SyscallNoReturn)
  155. }
  156. #[eonix_macros::define_syscall(SYS_EXIT)]
  157. fn exit(status: u32) -> SyscallNoReturn {
  158. unsafe {
  159. let mut procs = Task::block_on(ProcessList::get().write());
  160. Task::block_on(procs.do_exit(&thread, WaitType::Exited(status), false));
  161. }
  162. SyscallNoReturn
  163. }
  164. #[eonix_macros::define_syscall(SYS_EXIT_GROUP)]
  165. fn exit_group(status: u32) -> SyscallNoReturn {
  166. unsafe {
  167. let mut procs = Task::block_on(ProcessList::get().write());
  168. Task::block_on(procs.do_exit(&thread, WaitType::Exited(status), true));
  169. }
  170. SyscallNoReturn
  171. }
  172. enum WaitInfo {
  173. SigInfo(NonNull<SigInfo>),
  174. Status(NonNull<u32>),
  175. None,
  176. }
  177. fn do_waitid(
  178. thread: &Thread,
  179. id_type: u32,
  180. _id: u32,
  181. info: WaitInfo,
  182. options: u32,
  183. rusage: *mut RUsage,
  184. ) -> KResult<u32> {
  185. if id_type != P_ALL {
  186. unimplemented!("waitid with id_type {id_type}");
  187. }
  188. if !rusage.is_null() {
  189. unimplemented!("waitid with rusage pointer");
  190. }
  191. let options = match UserWaitOptions::from_bits(options) {
  192. None => unimplemented!("waitpid with options {options}"),
  193. Some(options) => options,
  194. };
  195. let Some(wait_object) = Task::block_on(thread.process.wait(
  196. options.contains(UserWaitOptions::WNOHANG),
  197. options.contains(UserWaitOptions::WUNTRACED),
  198. options.contains(UserWaitOptions::WCONTINUED),
  199. ))?
  200. else {
  201. return Ok(0);
  202. };
  203. match info {
  204. WaitInfo::SigInfo(siginfo_ptr) => {
  205. let (status, code) = wait_object.code.to_status_code();
  206. let mut siginfo = SigInfo::default();
  207. siginfo.si_pid = wait_object.pid;
  208. siginfo.si_uid = 0; // All users are root for now.
  209. siginfo.si_signo = Signal::SIGCHLD.into_raw();
  210. siginfo.si_status = status;
  211. siginfo.si_code = code;
  212. UserPointerMut::new(siginfo_ptr.as_ptr())?.write(siginfo)?;
  213. Ok(0)
  214. }
  215. WaitInfo::Status(status_ptr) => {
  216. UserPointerMut::new(status_ptr.as_ptr())?.write(wait_object.code.to_wstatus())?;
  217. Ok(wait_object.pid)
  218. }
  219. WaitInfo::None => Ok(wait_object.pid),
  220. }
  221. }
  222. #[eonix_macros::define_syscall(SYS_WAITID)]
  223. fn waitid(
  224. id_type: u32,
  225. id: u32,
  226. info: *mut SigInfo,
  227. options: u32,
  228. rusage: *mut RUsage,
  229. ) -> KResult<u32> {
  230. if let Some(info) = NonNull::new(info) {
  231. do_waitid(
  232. thread,
  233. id_type,
  234. id,
  235. WaitInfo::SigInfo(info),
  236. options,
  237. rusage,
  238. )
  239. } else {
  240. /*
  241. * According to POSIX.1-2008, an application calling waitid() must
  242. * ensure that infop points to a siginfo_t structure (i.e., that it
  243. * is a non-null pointer). On Linux, if infop is NULL, waitid()
  244. * succeeds, and returns the process ID of the waited-for child.
  245. * Applications should avoid relying on this inconsistent,
  246. * nonstandard, and unnecessary feature.
  247. */
  248. unimplemented!("waitid with null info pointer");
  249. }
  250. }
  251. #[eonix_macros::define_syscall(SYS_WAIT4)]
  252. fn wait4(waitpid: u32, arg1: *mut u32, options: u32, rusage: *mut RUsage) -> KResult<u32> {
  253. let waitinfo = if let Some(status) = NonNull::new(arg1) {
  254. WaitInfo::Status(status)
  255. } else {
  256. WaitInfo::None
  257. };
  258. let idtype = match waitpid {
  259. u32::MAX => P_ALL,
  260. _ => P_PID,
  261. };
  262. do_waitid(thread, idtype, waitpid, waitinfo, options, rusage)
  263. }
  264. #[cfg(target_arch = "x86_64")]
  265. #[eonix_macros::define_syscall(SYS_WAITPID)]
  266. fn waitpid(waitpid: u32, arg1: *mut u32, options: u32) -> KResult<u32> {
  267. sys_wait4(thread, waitpid, arg1, options, core::ptr::null_mut())
  268. }
  269. #[eonix_macros::define_syscall(SYS_SETSID)]
  270. fn setsid() -> KResult<u32> {
  271. thread.process.setsid()
  272. }
  273. #[eonix_macros::define_syscall(SYS_SETPGID)]
  274. fn setpgid(pid: u32, pgid: i32) -> KResult<()> {
  275. let pid = if pid == 0 { thread.process.pid } else { pid };
  276. let pgid = match pgid {
  277. 0 => pid,
  278. 1.. => pgid as u32,
  279. _ => return Err(EINVAL),
  280. };
  281. thread.process.setpgid(pid, pgid)
  282. }
  283. #[eonix_macros::define_syscall(SYS_GETSID)]
  284. fn getsid(pid: u32) -> KResult<u32> {
  285. if pid == 0 {
  286. Ok(thread.process.session_rcu().sid)
  287. } else {
  288. let procs = Task::block_on(ProcessList::get().read());
  289. procs
  290. .try_find_process(pid)
  291. .map(|proc| proc.session(procs.prove()).sid)
  292. .ok_or(ESRCH)
  293. }
  294. }
  295. #[eonix_macros::define_syscall(SYS_GETPGID)]
  296. fn getpgid(pid: u32) -> KResult<u32> {
  297. if pid == 0 {
  298. Ok(thread.process.pgroup_rcu().pgid)
  299. } else {
  300. let procs = Task::block_on(ProcessList::get().read());
  301. procs
  302. .try_find_process(pid)
  303. .map(|proc| proc.pgroup(procs.prove()).pgid)
  304. .ok_or(ESRCH)
  305. }
  306. }
  307. #[eonix_macros::define_syscall(SYS_GETPID)]
  308. fn getpid() -> KResult<u32> {
  309. Ok(thread.process.pid)
  310. }
  311. #[eonix_macros::define_syscall(SYS_GETPPID)]
  312. fn getppid() -> KResult<u32> {
  313. Ok(thread.process.parent_rcu().map_or(0, |x| x.pid))
  314. }
  315. fn do_geteuid(_thread: &Thread) -> KResult<u32> {
  316. // All users are root for now.
  317. Ok(0)
  318. }
  319. fn do_getuid(_thread: &Thread) -> KResult<u32> {
  320. // All users are root for now.
  321. Ok(0)
  322. }
  323. #[cfg(target_arch = "x86_64")]
  324. #[eonix_macros::define_syscall(SYS_GETUID32)]
  325. fn getuid32() -> KResult<u32> {
  326. do_getuid(thread)
  327. }
  328. #[eonix_macros::define_syscall(SYS_GETUID)]
  329. fn getuid() -> KResult<u32> {
  330. do_getuid(thread)
  331. }
  332. #[cfg(target_arch = "x86_64")]
  333. #[eonix_macros::define_syscall(SYS_GETEUID32)]
  334. fn geteuid32() -> KResult<u32> {
  335. do_geteuid(thread)
  336. }
  337. #[eonix_macros::define_syscall(SYS_GETEUID)]
  338. fn geteuid() -> KResult<u32> {
  339. do_geteuid(thread)
  340. }
  341. #[eonix_macros::define_syscall(SYS_GETGID)]
  342. fn getgid() -> KResult<u32> {
  343. // All users are root for now.
  344. Ok(0)
  345. }
  346. #[cfg(target_arch = "x86_64")]
  347. #[eonix_macros::define_syscall(SYS_GETGID32)]
  348. fn getgid32() -> KResult<u32> {
  349. sys_getgid(thread)
  350. }
  351. #[eonix_macros::define_syscall(SYS_GETTID)]
  352. fn gettid() -> KResult<u32> {
  353. Ok(thread.tid)
  354. }
  355. pub fn parse_user_tls(arch_tls: usize) -> KResult<UserTLS> {
  356. #[cfg(target_arch = "x86_64")]
  357. {
  358. let desc = arch_tls as *mut posix_types::x86_64::UserDescriptor;
  359. let desc_pointer = UserPointerMut::new(desc)?;
  360. let mut desc = desc_pointer.read()?;
  361. // Clear the TLS area if it is not present.
  362. if desc.flags.is_read_exec_only() && !desc.flags.is_present() {
  363. if desc.limit != 0 && desc.base != 0 {
  364. let len = if desc.flags.is_limit_in_pages() {
  365. (desc.limit as usize) << 12
  366. } else {
  367. desc.limit as usize
  368. };
  369. CheckedUserPointer::new(desc.base as _, len)?.zero()?;
  370. }
  371. }
  372. let (new_tls, entry) =
  373. UserTLS::new32(desc.base, desc.limit, desc.flags.is_limit_in_pages());
  374. desc.entry = entry;
  375. desc_pointer.write(desc)?;
  376. Ok(new_tls)
  377. }
  378. #[cfg(target_arch = "riscv64")]
  379. {
  380. Ok(UserTLS::new(arch_tls as u64))
  381. }
  382. }
  383. #[cfg(target_arch = "x86_64")]
  384. #[eonix_macros::define_syscall(SYS_SET_THREAD_AREA)]
  385. fn set_thread_area(arch_tls: usize) -> KResult<()> {
  386. thread.set_user_tls(parse_user_tls(arch_tls)?)?;
  387. // SAFETY: Preemption is disabled on calling `load_thread_area32()`.
  388. unsafe {
  389. eonix_preempt::disable();
  390. thread.load_thread_area32();
  391. eonix_preempt::enable();
  392. }
  393. Ok(())
  394. }
  395. #[eonix_macros::define_syscall(SYS_SET_TID_ADDRESS)]
  396. fn set_tid_address(tidptr: usize) -> KResult<u32> {
  397. thread.clear_child_tid(Some(tidptr));
  398. Ok(thread.tid)
  399. }
  400. #[eonix_macros::define_syscall(SYS_PRCTL)]
  401. fn prctl(option: u32, arg2: usize) -> KResult<()> {
  402. match option {
  403. PR_SET_NAME => {
  404. let name = UserPointer::new(arg2 as *mut [u8; 16])?.read()?;
  405. let len = name.iter().position(|&c| c == 0).unwrap_or(15);
  406. thread.set_name(name[..len].into());
  407. Ok(())
  408. }
  409. PR_GET_NAME => {
  410. let name = thread.get_name();
  411. let len = name.len().min(15);
  412. let name: [u8; 16] = core::array::from_fn(|i| if i < len { name[i] } else { 0 });
  413. UserPointerMut::new(arg2 as *mut [u8; 16])?.write(name)?;
  414. Ok(())
  415. }
  416. _ => Err(EINVAL),
  417. }
  418. }
  419. #[eonix_macros::define_syscall(SYS_KILL)]
  420. fn kill(pid: i32, sig: u32) -> KResult<()> {
  421. let procs = Task::block_on(ProcessList::get().read());
  422. match pid {
  423. // Send signal to every process for which the calling process has
  424. // permission to send signals.
  425. -1 => unimplemented!("kill with pid -1"),
  426. // Send signal to every process in the process group.
  427. 0 => thread
  428. .process
  429. .pgroup(procs.prove())
  430. .raise(Signal::try_from_raw(sig)?, procs.prove()),
  431. // Send signal to the process with the specified pid.
  432. 1.. => procs
  433. .try_find_process(pid as u32)
  434. .ok_or(ESRCH)?
  435. .raise(Signal::try_from_raw(sig)?, procs.prove()),
  436. // Send signal to the process group with the specified pgid equals to `-pid`.
  437. ..-1 => procs
  438. .try_find_pgroup((-pid) as u32)
  439. .ok_or(ESRCH)?
  440. .raise(Signal::try_from_raw(sig)?, procs.prove()),
  441. }
  442. Ok(())
  443. }
  444. #[eonix_macros::define_syscall(SYS_TKILL)]
  445. fn tkill(tid: u32, sig: u32) -> KResult<()> {
  446. Task::block_on(ProcessList::get().read())
  447. .try_find_thread(tid)
  448. .ok_or(ESRCH)?
  449. .raise(Signal::try_from_raw(sig)?);
  450. Ok(())
  451. }
  452. #[eonix_macros::define_syscall(SYS_RT_SIGPROCMASK)]
  453. fn rt_sigprocmask(
  454. how: u32,
  455. set: *mut SigSet,
  456. oldset: *mut SigSet,
  457. sigsetsize: usize,
  458. ) -> KResult<()> {
  459. if sigsetsize != size_of::<SigSet>() {
  460. return Err(EINVAL);
  461. }
  462. let old_mask = thread.signal_list.get_mask();
  463. if !oldset.is_null() {
  464. UserPointerMut::new(oldset)?.write(old_mask)?;
  465. }
  466. let new_mask = if !set.is_null() {
  467. UserPointer::new(set)?.read()?
  468. } else {
  469. return Ok(());
  470. };
  471. match how {
  472. SIG_BLOCK => thread.signal_list.mask(new_mask),
  473. SIG_UNBLOCK => thread.signal_list.unmask(new_mask),
  474. SIG_SETMASK => thread.signal_list.set_mask(new_mask),
  475. _ => return Err(EINVAL),
  476. }
  477. Ok(())
  478. }
  479. #[eonix_macros::define_syscall(SYS_RT_SIGACTION)]
  480. fn rt_sigaction(
  481. signum: u32,
  482. act: *const SigAction,
  483. oldact: *mut SigAction,
  484. sigsetsize: usize,
  485. ) -> KResult<()> {
  486. let signal = Signal::try_from_raw(signum)?;
  487. if sigsetsize != size_of::<u64>() {
  488. return Err(EINVAL);
  489. }
  490. // SIGKILL and SIGSTOP MUST not be set for a handler.
  491. if matches!(signal, SIGNAL_NOW!()) {
  492. return Err(EINVAL);
  493. }
  494. let old_action = thread.signal_list.get_action(signal);
  495. if !oldact.is_null() {
  496. UserPointerMut::new(oldact)?.write(old_action.into())?;
  497. }
  498. if !act.is_null() {
  499. let new_action = UserPointer::new(act)?.read()?;
  500. let action: SignalAction = new_action.try_into()?;
  501. thread.signal_list.set_action(signal, action)?;
  502. }
  503. Ok(())
  504. }
  505. #[eonix_macros::define_syscall(SYS_PRLIMIT64)]
  506. fn prlimit64(
  507. pid: u32,
  508. resource: u32,
  509. new_limit: *const RLimit,
  510. old_limit: *mut RLimit,
  511. ) -> KResult<()> {
  512. if pid != 0 {
  513. return Err(ENOSYS);
  514. }
  515. match resource {
  516. RLIMIT_STACK => {
  517. if !old_limit.is_null() {
  518. let old_limit = UserPointerMut::new(old_limit)?;
  519. let rlimit = RLimit {
  520. rlim_cur: 8 * 1024 * 1024,
  521. rlim_max: 8 * 1024 * 1024,
  522. };
  523. old_limit.write(rlimit)?;
  524. }
  525. if !new_limit.is_null() {
  526. return Err(ENOSYS);
  527. }
  528. Ok(())
  529. }
  530. _ => Err(ENOSYS),
  531. }
  532. }
  533. #[eonix_macros::define_syscall(SYS_GETRLIMIT)]
  534. fn getrlimit(resource: u32, rlimit: *mut RLimit) -> KResult<()> {
  535. sys_prlimit64(thread, 0, resource, core::ptr::null(), rlimit)
  536. }
  537. #[repr(C)]
  538. #[derive(Clone, Copy)]
  539. struct RUsage {
  540. ru_utime: TimeVal,
  541. ru_stime: TimeVal,
  542. ru_maxrss: u32,
  543. ru_ixrss: u32,
  544. ru_idrss: u32,
  545. ru_isrss: u32,
  546. ru_minflt: u32,
  547. ru_majflt: u32,
  548. ru_nswap: u32,
  549. ru_inblock: u32,
  550. ru_oublock: u32,
  551. ru_msgsnd: u32,
  552. ru_msgrcv: u32,
  553. ru_nsignals: u32,
  554. ru_nvcsw: u32,
  555. ru_nivcsw: u32,
  556. }
  557. #[eonix_macros::define_syscall(SYS_GETRUSAGE)]
  558. fn getrusage(who: u32, rusage: *mut RUsage) -> KResult<()> {
  559. if who != 0 {
  560. return Err(ENOSYS);
  561. }
  562. let rusage = UserPointerMut::new(rusage)?;
  563. rusage.write(RUsage {
  564. ru_utime: TimeVal::default(),
  565. ru_stime: TimeVal::default(),
  566. ru_maxrss: 0,
  567. ru_ixrss: 0,
  568. ru_idrss: 0,
  569. ru_isrss: 0,
  570. ru_minflt: 0,
  571. ru_majflt: 0,
  572. ru_nswap: 0,
  573. ru_inblock: 0,
  574. ru_oublock: 0,
  575. ru_msgsnd: 0,
  576. ru_msgrcv: 0,
  577. ru_nsignals: 0,
  578. ru_nvcsw: 0,
  579. ru_nivcsw: 0,
  580. })?;
  581. Ok(())
  582. }
  583. #[cfg(target_arch = "x86_64")]
  584. #[eonix_macros::define_syscall(SYS_VFORK)]
  585. fn vfork() -> KResult<u32> {
  586. let clone_args = CloneArgs::for_vfork();
  587. do_clone(thread, clone_args)
  588. }
  589. #[cfg(target_arch = "x86_64")]
  590. #[eonix_macros::define_syscall(SYS_FORK)]
  591. fn fork() -> KResult<u32> {
  592. let clone_args = CloneArgs::for_fork();
  593. do_clone(thread, clone_args)
  594. }
  595. #[eonix_macros::define_syscall(SYS_CLONE)]
  596. fn clone(
  597. clone_flags: usize,
  598. new_sp: usize,
  599. parent_tidptr: usize,
  600. tls: usize,
  601. child_tidptr: usize,
  602. ) -> KResult<u32> {
  603. let clone_args = CloneArgs::for_clone(clone_flags, new_sp, child_tidptr, parent_tidptr, tls)?;
  604. do_clone(thread, clone_args)
  605. }
  606. #[eonix_macros::define_syscall(SYS_FUTEX)]
  607. fn futex(
  608. uaddr: usize,
  609. op: u32,
  610. val: u32,
  611. _time_out: usize,
  612. _uaddr2: usize,
  613. _val3: u32,
  614. ) -> KResult<usize> {
  615. let (futex_op, futex_flag) = parse_futexop(op)?;
  616. let pid = if futex_flag.contains(FutexFlags::FUTEX_PRIVATE) {
  617. Some(thread.process.pid)
  618. } else {
  619. None
  620. };
  621. match futex_op {
  622. FutexOp::FUTEX_WAIT => {
  623. Task::block_on(futex_wait(uaddr, pid, val as u32, None))?;
  624. return Ok(0);
  625. }
  626. FutexOp::FUTEX_WAKE => {
  627. return Task::block_on(futex_wake(uaddr, pid, val as u32));
  628. }
  629. FutexOp::FUTEX_REQUEUE => {
  630. todo!()
  631. }
  632. _ => {
  633. todo!()
  634. }
  635. }
  636. }
  637. #[eonix_macros::define_syscall(SYS_SET_ROBUST_LIST)]
  638. fn set_robust_list(head: usize, len: usize) -> KResult<()> {
  639. if len != size_of::<RobustListHead>() {
  640. return Err(EINVAL);
  641. }
  642. thread.set_robust_list(Some(VAddr::from(head)));
  643. Ok(())
  644. }
  645. #[eonix_macros::define_syscall(SYS_RT_SIGRETURN)]
  646. fn rt_sigreturn() -> KResult<SyscallNoReturn> {
  647. thread
  648. .signal_list
  649. .restore(
  650. &mut thread.trap_ctx.borrow(),
  651. &mut thread.fpu_state.borrow(),
  652. false,
  653. )
  654. .inspect_err(|err| {
  655. println_warn!(
  656. "`rt_sigreturn` failed in thread {} with error {err}!",
  657. thread.tid
  658. );
  659. Task::block_on(thread.force_kill(Signal::SIGSEGV));
  660. })?;
  661. Ok(SyscallNoReturn)
  662. }
  663. #[cfg(target_arch = "x86_64")]
  664. #[eonix_macros::define_syscall(SYS_SIGRETURN)]
  665. fn sigreturn() -> KResult<SyscallNoReturn> {
  666. thread
  667. .signal_list
  668. .restore(
  669. &mut thread.trap_ctx.borrow(),
  670. &mut thread.fpu_state.borrow(),
  671. true,
  672. )
  673. .inspect_err(|err| {
  674. println_warn!(
  675. "`sigreturn` failed in thread {} with error {err}!",
  676. thread.tid
  677. );
  678. Task::block_on(thread.force_kill(Signal::SIGSEGV));
  679. })?;
  680. Ok(SyscallNoReturn)
  681. }
  682. #[cfg(target_arch = "x86_64")]
  683. #[eonix_macros::define_syscall(SYS_ARCH_PRCTL)]
  684. fn arch_prctl(option: u32, addr: u32) -> KResult<u32> {
  685. sys_arch_prctl(thread, option, addr)
  686. }
  687. pub fn keep_alive() {}