sys_epoll_ctl.rs 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. //! System call handler for epoll_ctl.
  2. use crate::arch::syscall::nr::SYS_EPOLL_CTL;
  3. use crate::filesystem::epoll::event_poll::EventPoll;
  4. use crate::filesystem::epoll::EPollCtlOption;
  5. use crate::filesystem::epoll::EPollEvent;
  6. use crate::mm::VirtAddr;
  7. use crate::syscall::table::FormattedSyscallParam;
  8. use crate::syscall::table::Syscall;
  9. use crate::syscall::user_access::UserBufferReader;
  10. use alloc::vec::Vec;
  11. use system_error::SystemError;
  12. pub struct SysEpollCtlHandle;
  13. impl Syscall for SysEpollCtlHandle {
  14. fn num_args(&self) -> usize {
  15. 4
  16. }
  17. fn handle(&self, args: &[usize], _from_user: bool) -> Result<usize, SystemError> {
  18. let op = EPollCtlOption::from_op_num(Self::op(args))?;
  19. let mut epds = EPollEvent::default();
  20. let event = Self::event(args);
  21. let epfd = Self::epfd(args);
  22. let fd = Self::fd(args);
  23. if op != EPollCtlOption::Del {
  24. // 不为EpollCtlDel时不允许传入空指针
  25. if event.is_null() {
  26. return Err(SystemError::EFAULT);
  27. }
  28. // 还是一样的问题,C标准的epoll_event大小为12字节,而内核实现的epoll_event内存对齐后为16字节
  29. // 这样分别拷贝其实和整体拷贝差别不大,内核使用内存对其版本甚至可能提升性能
  30. let epds_reader = UserBufferReader::new(
  31. event.as_ptr::<EPollEvent>(),
  32. core::mem::size_of::<EPollEvent>(),
  33. true,
  34. )?;
  35. // 拷贝到内核
  36. epds_reader.copy_one_from_user(&mut epds, 0)?;
  37. }
  38. return EventPoll::epoll_ctl_with_epfd(epfd, op, fd, epds, false);
  39. }
  40. fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
  41. vec![
  42. FormattedSyscallParam::new("epfd", format!("{:#x}", Self::epfd(args) as usize)),
  43. FormattedSyscallParam::new("op", format!("{:#x}", Self::op(args))),
  44. FormattedSyscallParam::new("fd", format!("{:#x}", Self::fd(args) as usize)),
  45. FormattedSyscallParam::new("event", format!("{:#x}", Self::event(args).data())),
  46. ]
  47. }
  48. }
  49. impl SysEpollCtlHandle {
  50. fn epfd(args: &[usize]) -> i32 {
  51. args[0] as i32
  52. }
  53. fn op(args: &[usize]) -> usize {
  54. args[1]
  55. }
  56. fn fd(args: &[usize]) -> i32 {
  57. args[2] as i32
  58. }
  59. fn event(args: &[usize]) -> VirtAddr {
  60. VirtAddr::new(args[3])
  61. }
  62. }
  63. syscall_table_macros::declare_syscall!(SYS_EPOLL_CTL, SysEpollCtlHandle);