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