signal.c 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. #include <signal.h>
  2. #include <printf.h>
  3. #include <stddef.h>
  4. #include <libsystem/syscall.h>
  5. #pragma GCC push_options
  6. #pragma GCC optimize("O0")
  7. void __libc_sa_restorer()
  8. {
  9. // 在这里发起sigreturn,请注意,由于内核需要读取到原来的do_signal时保存的栈帧,因此这里不能发生函数调用(会导致函数压栈),只能够这样来完成sigreturn
  10. __asm__ __volatile__("int $0x80 \n\t" ::"a"(SYS_RT_SIGRETURN) : "memory");
  11. }
  12. #pragma GCC pop_options
  13. /**
  14. * @brief 设置信号处理动作(简单版本)
  15. *
  16. * @param signum
  17. * @param handler
  18. * @return int
  19. */
  20. int signal(int signum, __sighandler_t handler)
  21. {
  22. struct sigaction sa = {0};
  23. sa.sa_handler = handler;
  24. // 由于DragonOS必须由用户程序指定一个sa_restorer,因此这里设置为libc的sa_restorer
  25. sa.sa_restorer = &__libc_sa_restorer;
  26. // printf("handler address: %#018lx\n", handler);
  27. // printf("restorer address: %#018lx\n", &__libc_sa_restorer);
  28. sigaction(signum, &sa, NULL);
  29. }
  30. /**
  31. * @brief 设置信号处理动作
  32. *
  33. * @param signum 信号
  34. * @param act 处理动作(不可为NULL)
  35. * @param oldact 返回的旧的处理动作(若为NULL,则不返回)
  36. * @return int 错误码(遵循posix)
  37. */
  38. int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
  39. {
  40. return syscall_invoke(SYS_SIGACTION, (uint64_t)signum, (uint64_t)act, (uint64_t)oldact, 0, 0, 0, 0, 0);
  41. }
  42. /**
  43. * @brief 向当前进程发送一个信号
  44. *
  45. * @param sig signal number
  46. * @return int 错误码
  47. */
  48. int raise(int sig)
  49. {
  50. return kill(getpid(), sig);
  51. }
  52. /**
  53. * @brief
  54. *
  55. * @param pid 进程的标识符
  56. * @param sig signal number
  57. * @return int 错误码
  58. */
  59. int kill(pid_t pid, int sig)
  60. {
  61. syscall_invoke(SYS_KILL, pid, sig, 0, 0, 0, 0, 0, 0);
  62. }