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