xref: /haiku/headers/private/kernel/ksignal.h (revision 1e60bdeab63fa7a57bc9a55b032052e95a18bd2c)
1 /*
2  * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Copyright 2003-2008, Axel Dörfler, axeld@pinc-software.de.
4  * All rights reserved.
5  * Distributed under the terms of the MIT License.
6  */
7 #ifndef _KERNEL_SIGNAL_H
8 #define _KERNEL_SIGNAL_H
9 
10 
11 #include <signal.h>
12 
13 #include <KernelExport.h>
14 
15 #include <signal_defs.h>
16 
17 #include <heap.h>
18 #include <util/DoublyLinkedList.h>
19 #include <util/KernelReferenceable.h>
20 
21 
22 namespace BKernel {
23 	struct ProcessGroup;
24 	struct Team;
25 	struct Thread;
26 }
27 
28 using BKernel::ProcessGroup;
29 using BKernel::Team;
30 using BKernel::Thread;
31 
32 
33 #define KILL_SIGNALS	\
34 	(((sigset_t)1 << (SIGKILL - 1)) | ((sigset_t)1 << (SIGKILLTHR - 1)))
35 
36 #define SYSCALL_RESTART_PARAMETER_SIZE	32
37 
38 // kernel-internal signals
39 #define SIGNAL_DEBUG_THREAD		62
40 	// Debug a thread. Used together with the B_THREAD_DEBUG_STOP thread debug
41 	// flag. Continues the thread, if suspended, but has no effect otherwise.
42 	// Non-blockable.
43 #define SIGNAL_CANCEL_THREAD	63
44 	// Cancel a thread. Non-blockable.
45 #define SIGNAL_CONTINUE_THREAD	64
46 	// Continue a thread. Used by resume_thread(). Non-blockable, prevents
47 	// syscall restart.
48 
49 
50 struct signal_frame_data {
51 	siginfo_t	info;
52 	ucontext_t	context;
53 	void*		user_data;
54 	void*		handler;
55 	bool		siginfo_handler;
56 	int32		thread_flags;
57 	uint64		syscall_restart_return_value;
58 	uint8		syscall_restart_parameters[SYSCALL_RESTART_PARAMETER_SIZE];
59 	void*		commpage_address;
60 };
61 
62 
63 namespace BKernel {
64 
65 
66 struct QueuedSignalsCounter : BReferenceable {
67 								QueuedSignalsCounter(int32 limit);
68 
69 			bool				Increment();
70 			void				Decrement()		{ ReleaseReference(); }
71 
72 private:
73 			int32				fLimit;
74 };
75 
76 
77 struct Signal : KernelReferenceable, DoublyLinkedListLinkImpl<Signal> {
78 public:
79 								Signal();
80 									// cheap no-init constructor
81 								Signal(const Signal& other);
82 								Signal(uint32 number, int32 signalCode,
83 									int32 errorCode, pid_t sendingProcess);
84 	virtual						~Signal();
85 
86 	static	status_t			CreateQueuable(const Signal& signal,
87 									bool queuingRequired,
88 									Signal*& _signalToQueue);
89 
90 			void				SetTo(uint32 number);
91 
92 			uint32				Number() const { return fNumber; }
93 			void				SetNumber(uint32 number)
94 									{ fNumber = number; }
95 
96 			int32				Priority() const;
97 
98 			int32				SignalCode() const
99 									{ return fSignalCode; }
100 			int32				ErrorCode() const
101 									{ return fErrorCode; }
102  			pid_t				SendingProcess() const
103  									{ return fSendingProcess; }
104 
105  			uid_t				SendingUser() const
106  									{ return fSendingUser; }
107  			void				SetSendingUser(uid_t user)
108  									{ fSendingUser = user; }
109 
110 			int32				Status() const
111 									{ return fStatus; }
112 			void				SetStatus(int32 status)
113 									{ fStatus = status; }
114 
115 			int32				PollBand() const
116 									{ return fPollBand; }
117 			void				SetPollBand(int32 pollBand)
118 									{ fPollBand = pollBand; }
119 
120 			void*				Address() const
121 									{ return fAddress; }
122 			void				SetAddress(void* address)
123 									{ fAddress = address; }
124 
125 			union sigval		UserValue() const
126 									{ return fUserValue; }
127 			void				SetUserValue(union sigval userValue)
128 									{ fUserValue = userValue; }
129 
130 			bool				IsPending() const
131 									{ return fPending; }
132 			void				SetPending(bool pending)
133 									{ fPending = pending; }
134 
135 	virtual	void				Handled();
136 
137 protected:
138 	virtual	void				LastReferenceReleased();
139 
140 private:
141 			QueuedSignalsCounter* fCounter;
142 			uint32				fNumber;
143 			int32				fSignalCode;
144 			int32				fErrorCode;	// error code associated with the
145 											// signal
146 			pid_t				fSendingProcess;
147 			uid_t				fSendingUser;
148 			int32				fStatus;	// exit value
149 			int32				fPollBand;	// for SIGPOLL
150 			void*				fAddress;
151 			union sigval		fUserValue;
152 			bool				fPending;
153 };
154 
155 
156 struct PendingSignals {
157 								PendingSignals();
158 								~PendingSignals();
159 
160 			sigset_t			AllSignals() const
161 									{ return fQueuedSignalsMask
162 										| fUnqueuedSignalsMask; }
163 
164 			int32				HighestSignalPriority(sigset_t nonBlocked)
165 									const;
166 
167 			void				Clear();
168 			void				AddSignal(int32 signal)
169 									{ fUnqueuedSignalsMask
170 										|= SIGNAL_TO_MASK(signal); }
171 			void				AddSignal(Signal* signal);
172 			void				RemoveSignal(int32 signal)
173 									{ RemoveSignals(SIGNAL_TO_MASK(signal)); }
174 			void				RemoveSignal(Signal* signal);
175 			void				RemoveSignals(sigset_t mask);
176 
177 			Signal*				DequeueSignal(sigset_t nonBlocked,
178 									Signal& buffer);
179 
180 private:
181 			typedef DoublyLinkedList<Signal> SignalList;
182 
183 private:
184 			int32				_GetHighestPrioritySignal(sigset_t nonBlocked,
185 									Signal*& _queuedSignal,
186 									int32& _unqueuedSignal) const;
187 			void				_UpdateQueuedSignalMask();
188 
189 private:
190 			sigset_t			fQueuedSignalsMask;
191 			sigset_t			fUnqueuedSignalsMask;
192 			SignalList			fQueuedSignals;
193 };
194 
195 
196 }	// namespace BKernel
197 
198 
199 using BKernel::PendingSignals;
200 using BKernel::QueuedSignalsCounter;
201 using BKernel::Signal;
202 
203 
204 #ifdef __cplusplus
205 extern "C" {
206 #endif
207 
208 void handle_signals(Thread* thread);
209 bool is_team_signal_blocked(Team* team, int signal);
210 void signal_get_user_stack(addr_t address, stack_t* stack);
211 
212 status_t send_signal_to_thread_locked(Thread* thread, uint32 signalNumber,
213 	Signal* signal, uint32 flags);
214 status_t send_signal_to_thread(Thread* thread, const Signal& signal,
215 	uint32 flags);
216 status_t send_signal_to_thread_id(thread_id threadID, const Signal& signal,
217 	uint32 flags);
218 
219 status_t send_signal_to_team_locked(Team* team, uint32 signalNumber,
220 	Signal* signal, uint32 flags);
221 status_t send_signal_to_team(Team* team, const Signal& signal, uint32 flags);
222 status_t send_signal_to_team_id(team_id teamID, const Signal& signal,
223 	uint32 flags);
224 
225 status_t send_signal_to_process_group_locked(ProcessGroup* group,
226 	const Signal& signal, uint32 flags);
227 status_t send_signal_to_process_group(pid_t groupID, const Signal& signal,
228 	uint32 flags);
229 
230 status_t _user_send_signal(int32 id, uint32 signal,
231 	const union sigval* userValue, uint32 flags);
232 status_t _user_set_signal_mask(int how, const sigset_t *set, sigset_t *oldSet);
233 status_t _user_sigaction(int sig, const struct sigaction *newAction,
234 	struct sigaction *oldAction);
235 bigtime_t _user_set_alarm(bigtime_t time, uint32 mode);
236 status_t _user_sigwait(const sigset_t *set, siginfo_t *info, uint32 flags,
237 	bigtime_t timeout);
238 status_t _user_sigsuspend(const sigset_t *mask);
239 status_t _user_sigpending(sigset_t *set);
240 status_t _user_set_signal_stack(const stack_t *newUserStack,
241 	stack_t *oldUserStack);
242 int64 _user_restore_signal_frame(struct signal_frame_data* signalFrameData);
243 
244 #ifdef __cplusplus
245 }
246 #endif
247 
248 #endif	/* _KERNEL_SIGNAL_H */
249