lwp_signal.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2020-02-23 Jesven first version.
  9. * 2023-07-06 Shell update the generation, pending and delivery API
  10. * 2023-11-22 Shell support for job control signal
  11. */
  12. #ifndef __LWP_SIGNAL_H__
  13. #define __LWP_SIGNAL_H__
  14. #include "syscall_generic.h"
  15. #include <rtthread.h>
  16. #include <sys/signal.h>
  17. #ifdef __cplusplus
  18. extern "C" {
  19. #endif
  20. #define _USIGNAL_SIGMASK(signo) (1u << ((signo)-1))
  21. #define LWP_SIG_NO_IGN_SET \
  22. (_USIGNAL_SIGMASK(SIGCONT) | _USIGNAL_SIGMASK(SIGSTOP) | \
  23. _USIGNAL_SIGMASK(SIGKILL))
  24. #define LWP_SIG_IGNORE_SET \
  25. (_USIGNAL_SIGMASK(SIGCHLD) | _USIGNAL_SIGMASK(SIGURG) | \
  26. _USIGNAL_SIGMASK(SIGWINCH) /* from 4.3 BSD, not POSIX.1 */)
  27. #define LWP_SIG_JOBCTL_SET \
  28. (_USIGNAL_SIGMASK(SIGCONT) | _USIGNAL_SIGMASK(SIGSTOP) | \
  29. _USIGNAL_SIGMASK(SIGTSTP) | _USIGNAL_SIGMASK(SIGTTIN) | \
  30. _USIGNAL_SIGMASK(SIGTTOU))
  31. #define LWP_SIG_STOP_SET \
  32. (_USIGNAL_SIGMASK(SIGSTOP) | _USIGNAL_SIGMASK(SIGTSTP) | \
  33. _USIGNAL_SIGMASK(SIGTTIN) | _USIGNAL_SIGMASK(SIGTTOU))
  34. #define LWP_SIG_ACT_DFL ((lwp_sighandler_t)0)
  35. #define LWP_SIG_ACT_IGN ((lwp_sighandler_t)1)
  36. #define LWP_SIG_USER_SA_FLAGS \
  37. (SA_NOCLDSTOP | SA_NOCLDWAIT | SA_SIGINFO | SA_ONSTACK | SA_RESTART | \
  38. SA_NODEFER | SA_RESETHAND | SA_EXPOSE_TAGBITS)
  39. #define LWP_SIG_INVALID_TIMER ((timer_t)-1)
  40. typedef enum
  41. {
  42. LWP_SIG_MASK_CMD_BLOCK,
  43. LWP_SIG_MASK_CMD_UNBLOCK,
  44. LWP_SIG_MASK_CMD_SET_MASK,
  45. __LWP_SIG_MASK_CMD_WATERMARK
  46. } lwp_sig_mask_cmd_t;
  47. /**
  48. * LwP implementation of POSIX signal
  49. */
  50. struct lwp_signal
  51. {
  52. timer_t real_timer;
  53. struct lwp_sigqueue sig_queue;
  54. rt_thread_t sig_dispatch_thr[_LWP_NSIG];
  55. lwp_sighandler_t sig_action[_LWP_NSIG];
  56. lwp_sigset_t sig_action_mask[_LWP_NSIG];
  57. lwp_sigset_t sig_action_nodefer;
  58. lwp_sigset_t sig_action_onstack;
  59. lwp_sigset_t sig_action_restart;
  60. lwp_sigset_t sig_action_siginfo;
  61. lwp_sigset_t sig_action_nocldstop;
  62. lwp_sigset_t sig_action_nocldwait;
  63. };
  64. struct rt_lwp;
  65. struct rt_processgroup;
  66. #ifndef ARCH_MM_MMU
  67. void lwp_sighandler_set(int sig, lwp_sighandler_t func);
  68. void lwp_thread_sighandler_set(int sig, lwp_sighandler_t func);
  69. #endif
  70. rt_inline void lwp_sigqueue_init(lwp_sigqueue_t sigq)
  71. {
  72. rt_memset(&sigq->sigset_pending, 0, sizeof(lwp_sigset_t));
  73. rt_list_init(&sigq->siginfo_list);
  74. }
  75. /**
  76. * @brief release the signal queue
  77. *
  78. * @param sigq target signal queue
  79. */
  80. void lwp_sigqueue_clear(lwp_sigqueue_t sigq);
  81. rt_err_t lwp_signal_init(struct lwp_signal *sig);
  82. rt_err_t lwp_signal_detach(struct lwp_signal *signal);
  83. rt_inline void lwp_thread_signal_detach(struct lwp_thread_signal *tsig)
  84. {
  85. lwp_sigqueue_clear(&tsig->sig_queue);
  86. }
  87. /**
  88. * @brief send a signal to the process
  89. *
  90. * @param lwp the process to be killed
  91. * @param signo the signal number
  92. * @param code as in siginfo
  93. * @param value as in siginfo
  94. * @return rt_err_t RT_EINVAL if the parameter is invalid, RT_EOK as
  95. * successful
  96. *
  97. * @note the *signal_kill have the same definition of a successful return as
  98. * kill() in IEEE Std 1003.1-2017
  99. */
  100. rt_err_t lwp_signal_kill(struct rt_lwp *lwp, long signo, long code,
  101. lwp_siginfo_ext_t value);
  102. /**
  103. * @brief set or examine the signal action of signo
  104. *
  105. * @param signo signal number
  106. * @param act the signal action
  107. * @param oact the old signal action
  108. * @return rt_err_t
  109. */
  110. rt_err_t lwp_signal_action(struct rt_lwp *lwp, int signo,
  111. const struct lwp_sigaction *restrict act,
  112. struct lwp_sigaction *restrict oact);
  113. /**
  114. * @brief send a signal to the thread
  115. *
  116. * @param thread target thread
  117. * @param signo the signal number
  118. * @param code as in siginfo
  119. * @param value as in siginfo
  120. * @return rt_err_t RT_EINVAL if the parameter is invalid, RT_EOK as
  121. * successful
  122. */
  123. rt_err_t lwp_thread_signal_kill(rt_thread_t thread, long signo, long code,
  124. lwp_siginfo_ext_t value);
  125. /**
  126. * @brief set signal mask of target thread
  127. *
  128. * @param thread the target thread
  129. * @param how command
  130. * @param sigset operand
  131. * @param oset the address to old set
  132. * @return rt_err_t
  133. */
  134. rt_err_t lwp_thread_signal_mask(rt_thread_t thread, lwp_sig_mask_cmd_t how,
  135. const lwp_sigset_t *sigset, lwp_sigset_t *oset);
  136. /**
  137. * @brief Catch signal if exists and no return, otherwise return with no
  138. * side effect
  139. *
  140. * @param exp_frame the exception frame on kernel stack
  141. */
  142. void lwp_thread_signal_catch(void *exp_frame);
  143. /**
  144. * @brief Check if it's okay to suspend for current lwp thread
  145. *
  146. * @param thread target thread
  147. * @param suspend_flag suspend flag of target thread
  148. * @return int 1 if can be suspended, otherwise not
  149. */
  150. int lwp_thread_signal_suspend_check(rt_thread_t thread, int suspend_flag);
  151. /**
  152. * @brief Asynchronously wait for signal
  153. *
  154. * @param thread target thread
  155. * @param sigset the signals to be waited
  156. * @param info address of user siginfo
  157. * @param timeout timeout of waiting
  158. * @return rt_err_t
  159. */
  160. rt_err_t lwp_thread_signal_timedwait(rt_thread_t thread, lwp_sigset_t *sigset,
  161. siginfo_t *usi, struct timespec *timeout);
  162. /**
  163. * @brief Examine the set of signals that are blocked from delivery to the
  164. * calling thread and that are pending on the process or the calling thread
  165. *
  166. * @param thread target thread
  167. * @param sigset where mask of pending signals is returned
  168. */
  169. void lwp_thread_signal_pending(rt_thread_t thread, lwp_sigset_t *sigset);
  170. /**
  171. * @brief send a signal to the process group
  172. *
  173. * @param pgrp target process group
  174. * @param signo the signal number
  175. * @param code as in siginfo
  176. * @param value as in siginfo
  177. * @return rt_err_t RT_EINVAL if the parameter is invalid, RT_EOK as
  178. * successful
  179. */
  180. rt_err_t lwp_pgrp_signal_kill(struct rt_processgroup *pgrp, long signo,
  181. long code, lwp_siginfo_ext_t value);
  182. rt_inline int lwp_sigismember(lwp_sigset_t *set, int _sig)
  183. {
  184. unsigned long sig = _sig - 1;
  185. if (_LWP_NSIG_WORDS == 1)
  186. {
  187. return 1 & (set->sig[0] >> sig);
  188. }
  189. else
  190. {
  191. return 1 & (set->sig[sig / _LWP_NSIG_BPW] >> (sig % _LWP_NSIG_BPW));
  192. }
  193. }
  194. struct itimerspec;
  195. rt_bool_t lwp_sigisign(struct rt_lwp *lwp, int _sig);
  196. rt_err_t lwp_signal_setitimer(struct rt_lwp *lwp, int which,
  197. const struct itimerspec *restrict new,
  198. struct itimerspec *restrict old);
  199. rt_bool_t lwp_signal_restart_syscall(struct rt_lwp *lwp, int error_code);
  200. #ifdef __cplusplus
  201. }
  202. #endif
  203. #endif /* __LWP_SIGNAL_H__ */