1db75a08bSAxel Dörfler/*
224df6592SIngo Weinhold * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
324df6592SIngo Weinhold * Copyright 2003-2008, Axel D��rfler, axeld@pinc-software.de.
424df6592SIngo Weinhold * All rights reserved.
5db75a08bSAxel Dörfler * Distributed under the terms of the MIT License.
6db75a08bSAxel Dörfler */
7a9731b41SAxel Dörfler#ifndef _KERNEL_SIGNAL_H
8a9731b41SAxel Dörfler#define _KERNEL_SIGNAL_H
9a9731b41SAxel Dörfler
1046365cceSAxel Dörfler
11a9731b41SAxel Dörfler#include <signal.h>
12a9731b41SAxel Dörfler
1324df6592SIngo Weinhold#include <KernelExport.h>
1424df6592SIngo Weinhold
1524df6592SIngo Weinhold#include <signal_defs.h>
1624df6592SIngo Weinhold
1724df6592SIngo Weinhold#include <heap.h>
1824df6592SIngo Weinhold#include <util/DoublyLinkedList.h>
1924df6592SIngo Weinhold#include <util/KernelReferenceable.h>
2024df6592SIngo Weinhold
21db75a08bSAxel Dörfler
224535495dSIngo Weinholdnamespace BKernel {
2324df6592SIngo Weinhold	struct ProcessGroup;
2424df6592SIngo Weinhold	struct Team;
254535495dSIngo Weinhold	struct Thread;
264535495dSIngo Weinhold}
274535495dSIngo Weinhold
2824df6592SIngo Weinholdusing BKernel::ProcessGroup;
2924df6592SIngo Weinholdusing BKernel::Team;
304535495dSIngo Weinholdusing BKernel::Thread;
314535495dSIngo Weinhold
324535495dSIngo Weinhold
3324df6592SIngo Weinhold#define KILL_SIGNALS	\
3424df6592SIngo Weinhold	(((sigset_t)1 << (SIGKILL - 1)) | ((sigset_t)1 << (SIGKILLTHR - 1)))
35a9731b41SAxel Dörfler
3624df6592SIngo Weinhold#define SYSCALL_RESTART_PARAMETER_SIZE	32
3733f0dbe4SIngo Weinhold
3824df6592SIngo Weinhold// kernel-internal signals
397a187cd6SIngo Weinhold#define SIGNAL_DEBUG_THREAD		62
407a187cd6SIngo Weinhold	// Debug a thread. Used together with the B_THREAD_DEBUG_STOP thread debug
417a187cd6SIngo Weinhold	// flag. Continues the thread, if suspended, but has no effect otherwise.
427a187cd6SIngo Weinhold	// Non-blockable.
4324df6592SIngo Weinhold#define SIGNAL_CANCEL_THREAD	63
4424df6592SIngo Weinhold	// Cancel a thread. Non-blockable.
4524df6592SIngo Weinhold#define SIGNAL_CONTINUE_THREAD	64
4624df6592SIngo Weinhold	// Continue a thread. Used by resume_thread(). Non-blockable, prevents
4724df6592SIngo Weinhold	// syscall restart.
48df716df5SIngo Weinhold
49a9731b41SAxel Dörfler
5024df6592SIngo Weinholdstruct signal_frame_data {
5124df6592SIngo Weinhold	siginfo_t	info;
5224df6592SIngo Weinhold	ucontext_t	context;
5324df6592SIngo Weinhold	void*		user_data;
5424df6592SIngo Weinhold	void*		handler;
5524df6592SIngo Weinhold	bool		siginfo_handler;
5624df6592SIngo Weinhold	int32		thread_flags;
5724df6592SIngo Weinhold	uint64		syscall_restart_return_value;
5824df6592SIngo Weinhold	uint8		syscall_restart_parameters[SYSCALL_RESTART_PARAMETER_SIZE];
59e85e399fSPawel Dziepak	void*		commpage_address;
6024df6592SIngo Weinhold};
6124df6592SIngo Weinhold
6224df6592SIngo Weinhold
6324df6592SIngo Weinholdnamespace BKernel {
6424df6592SIngo Weinhold
6524df6592SIngo Weinhold
6624df6592SIngo Weinholdstruct QueuedSignalsCounter : BReferenceable {
6724df6592SIngo Weinhold								QueuedSignalsCounter(int32 limit);
6824df6592SIngo Weinhold
6924df6592SIngo Weinhold			bool				Increment();
7024df6592SIngo Weinhold			void				Decrement()		{ ReleaseReference(); }
7124df6592SIngo Weinhold
7224df6592SIngo Weinholdprivate:
7324df6592SIngo Weinhold			int32				fLimit;
7424df6592SIngo Weinhold};
7524df6592SIngo Weinhold
7624df6592SIngo Weinhold
7724df6592SIngo Weinholdstruct Signal : KernelReferenceable, DoublyLinkedListLinkImpl<Signal> {
7824df6592SIngo Weinholdpublic:
7924df6592SIngo Weinhold								Signal();
8024df6592SIngo Weinhold									// cheap no-init constructor
8124df6592SIngo Weinhold								Signal(const Signal& other);
8224df6592SIngo Weinhold								Signal(uint32 number, int32 signalCode,
8324df6592SIngo Weinhold									int32 errorCode, pid_t sendingProcess);
8424df6592SIngo Weinhold	virtual						~Signal();
8524df6592SIngo Weinhold
8624df6592SIngo Weinhold	static	status_t			CreateQueuable(const Signal& signal,
8724df6592SIngo Weinhold									bool queuingRequired,
8824df6592SIngo Weinhold									Signal*& _signalToQueue);
8924df6592SIngo Weinhold
9024df6592SIngo Weinhold			void				SetTo(uint32 number);
9124df6592SIngo Weinhold
9224df6592SIngo Weinhold			uint32				Number() const { return fNumber; }
9324df6592SIngo Weinhold			void				SetNumber(uint32 number)
9424df6592SIngo Weinhold									{ fNumber = number; }
9524df6592SIngo Weinhold
9624df6592SIngo Weinhold			int32				Priority() const;
9724df6592SIngo Weinhold
9824df6592SIngo Weinhold			int32				SignalCode() const
9924df6592SIngo Weinhold									{ return fSignalCode; }
10024df6592SIngo Weinhold			int32				ErrorCode() const
10124df6592SIngo Weinhold									{ return fErrorCode; }
10224df6592SIngo Weinhold 			pid_t				SendingProcess() const
10324df6592SIngo Weinhold 									{ return fSendingProcess; }
10424df6592SIngo Weinhold
10524df6592SIngo Weinhold 			uid_t				SendingUser() const
10624df6592SIngo Weinhold 									{ return fSendingUser; }
10724df6592SIngo Weinhold 			void				SetSendingUser(uid_t user)
10824df6592SIngo Weinhold 									{ fSendingUser = user; }
109782c98afSIngo Weinhold
11024df6592SIngo Weinhold			int32				Status() const
11124df6592SIngo Weinhold									{ return fStatus; }
11224df6592SIngo Weinhold			void				SetStatus(int32 status)
11324df6592SIngo Weinhold									{ fStatus = status; }
114a9731b41SAxel Dörfler
11524df6592SIngo Weinhold			int32				PollBand() const
11624df6592SIngo Weinhold									{ return fPollBand; }
11724df6592SIngo Weinhold			void				SetPollBand(int32 pollBand)
11824df6592SIngo Weinhold									{ fPollBand = pollBand; }
119bc2001bbSIngo Weinhold
12024df6592SIngo Weinhold			void*				Address() const
12124df6592SIngo Weinhold									{ return fAddress; }
12224df6592SIngo Weinhold			void				SetAddress(void* address)
12324df6592SIngo Weinhold									{ fAddress = address; }
12424df6592SIngo Weinhold
12524df6592SIngo Weinhold			union sigval		UserValue() const
12624df6592SIngo Weinhold									{ return fUserValue; }
12724df6592SIngo Weinhold			void				SetUserValue(union sigval userValue)
12824df6592SIngo Weinhold									{ fUserValue = userValue; }
12924df6592SIngo Weinhold
13024df6592SIngo Weinhold			bool				IsPending() const
13124df6592SIngo Weinhold									{ return fPending; }
13224df6592SIngo Weinhold			void				SetPending(bool pending)
13324df6592SIngo Weinhold									{ fPending = pending; }
13424df6592SIngo Weinhold
13524df6592SIngo Weinhold	virtual	void				Handled();
13624df6592SIngo Weinhold
13724df6592SIngo Weinholdprotected:
13824df6592SIngo Weinhold	virtual	void				LastReferenceReleased();
13924df6592SIngo Weinhold
14024df6592SIngo Weinholdprivate:
14124df6592SIngo Weinhold			QueuedSignalsCounter* fCounter;
14224df6592SIngo Weinhold			uint32				fNumber;
14324df6592SIngo Weinhold			int32				fSignalCode;
14424df6592SIngo Weinhold			int32				fErrorCode;	// error code associated with the
14524df6592SIngo Weinhold											// signal
14624df6592SIngo Weinhold			pid_t				fSendingProcess;
14724df6592SIngo Weinhold			uid_t				fSendingUser;
14824df6592SIngo Weinhold			int32				fStatus;	// exit value
14924df6592SIngo Weinhold			int32				fPollBand;	// for SIGPOLL
15024df6592SIngo Weinhold			void*				fAddress;
15124df6592SIngo Weinhold			union sigval		fUserValue;
15224df6592SIngo Weinhold			bool				fPending;
15324df6592SIngo Weinhold};
15424df6592SIngo Weinhold
15524df6592SIngo Weinhold
15624df6592SIngo Weinholdstruct PendingSignals {
15724df6592SIngo Weinhold								PendingSignals();
15824df6592SIngo Weinhold								~PendingSignals();
15924df6592SIngo Weinhold
16024df6592SIngo Weinhold			sigset_t			AllSignals() const
16124df6592SIngo Weinhold									{ return fQueuedSignalsMask
16224df6592SIngo Weinhold										| fUnqueuedSignalsMask; }
16324df6592SIngo Weinhold
16424df6592SIngo Weinhold			int32				HighestSignalPriority(sigset_t nonBlocked)
16524df6592SIngo Weinhold									const;
16624df6592SIngo Weinhold
16724df6592SIngo Weinhold			void				Clear();
16824df6592SIngo Weinhold			void				AddSignal(int32 signal)
16924df6592SIngo Weinhold									{ fUnqueuedSignalsMask
17024df6592SIngo Weinhold										|= SIGNAL_TO_MASK(signal); }
17124df6592SIngo Weinhold			void				AddSignal(Signal* signal);
17224df6592SIngo Weinhold			void				RemoveSignal(int32 signal)
17324df6592SIngo Weinhold									{ RemoveSignals(SIGNAL_TO_MASK(signal)); }
17424df6592SIngo Weinhold			void				RemoveSignal(Signal* signal);
17524df6592SIngo Weinhold			void				RemoveSignals(sigset_t mask);
17624df6592SIngo Weinhold
17724df6592SIngo Weinhold			Signal*				DequeueSignal(sigset_t nonBlocked,
17824df6592SIngo Weinhold									Signal& buffer);
17924df6592SIngo Weinhold
18024df6592SIngo Weinholdprivate:
18124df6592SIngo Weinhold			typedef DoublyLinkedList<Signal> SignalList;
18224df6592SIngo Weinhold
18324df6592SIngo Weinholdprivate:
18424df6592SIngo Weinhold			int32				_GetHighestPrioritySignal(sigset_t nonBlocked,
18524df6592SIngo Weinhold									Signal*& _queuedSignal,
18624df6592SIngo Weinhold									int32& _unqueuedSignal) const;
18724df6592SIngo Weinhold			void				_UpdateQueuedSignalMask();
18824df6592SIngo Weinhold
18924df6592SIngo Weinholdprivate:
19024df6592SIngo Weinhold			sigset_t			fQueuedSignalsMask;
19124df6592SIngo Weinhold			sigset_t			fUnqueuedSignalsMask;
19224df6592SIngo Weinhold			SignalList			fQueuedSignals;
19324df6592SIngo Weinhold};
19424df6592SIngo Weinhold
19524df6592SIngo Weinhold
19624df6592SIngo Weinhold}	// namespace BKernel
19724df6592SIngo Weinhold
19824df6592SIngo Weinhold
19924df6592SIngo Weinholdusing BKernel::PendingSignals;
20024df6592SIngo Weinholdusing BKernel::QueuedSignalsCounter;
20124df6592SIngo Weinholdusing BKernel::Signal;
20224df6592SIngo Weinhold
20324df6592SIngo Weinhold
20424df6592SIngo Weinhold#ifdef __cplusplus
20524df6592SIngo Weinholdextern "C" {
20624df6592SIngo Weinhold#endif
20720b656f0SIngo Weinhold
20824df6592SIngo Weinholdvoid handle_signals(Thread* thread);
20924df6592SIngo Weinholdbool is_team_signal_blocked(Team* team, int signal);
21024df6592SIngo Weinholdvoid signal_get_user_stack(addr_t address, stack_t* stack);
21124df6592SIngo Weinhold
21224df6592SIngo Weinholdstatus_t send_signal_to_thread_locked(Thread* thread, uint32 signalNumber,
21324df6592SIngo Weinhold	Signal* signal, uint32 flags);
21424df6592SIngo Weinholdstatus_t send_signal_to_thread(Thread* thread, const Signal& signal,
21524df6592SIngo Weinhold	uint32 flags);
21624df6592SIngo Weinholdstatus_t send_signal_to_thread_id(thread_id threadID, const Signal& signal,
21724df6592SIngo Weinhold	uint32 flags);
21824df6592SIngo Weinhold
21924df6592SIngo Weinholdstatus_t send_signal_to_team_locked(Team* team, uint32 signalNumber,
22024df6592SIngo Weinhold	Signal* signal, uint32 flags);
22124df6592SIngo Weinholdstatus_t send_signal_to_team(Team* team, const Signal& signal, uint32 flags);
22224df6592SIngo Weinholdstatus_t send_signal_to_team_id(team_id teamID, const Signal& signal,
22324df6592SIngo Weinhold	uint32 flags);
22424df6592SIngo Weinhold
22524df6592SIngo Weinholdstatus_t send_signal_to_process_group_locked(ProcessGroup* group,
22624df6592SIngo Weinhold	const Signal& signal, uint32 flags);
22724df6592SIngo Weinholdstatus_t send_signal_to_process_group(pid_t groupID, const Signal& signal,
22824df6592SIngo Weinhold	uint32 flags);
22924df6592SIngo Weinhold
23024df6592SIngo Weinholdstatus_t _user_send_signal(int32 id, uint32 signal,
23124df6592SIngo Weinhold	const union sigval* userValue, uint32 flags);
23224df6592SIngo Weinholdstatus_t _user_set_signal_mask(int how, const sigset_t *set, sigset_t *oldSet);
23324df6592SIngo Weinholdstatus_t _user_sigaction(int sig, const struct sigaction *newAction,
2340b70ea59SAxel Dörfler	struct sigaction *oldAction);
23524df6592SIngo Weinholdbigtime_t _user_set_alarm(bigtime_t time, uint32 mode);
23624df6592SIngo Weinholdstatus_t _user_sigwait(const sigset_t *set, siginfo_t *info, uint32 flags,
23724df6592SIngo Weinhold	bigtime_t timeout);
23824df6592SIngo Weinholdstatus_t _user_sigsuspend(const sigset_t *mask);
23924df6592SIngo Weinholdstatus_t _user_sigpending(sigset_t *set);
24024df6592SIngo Weinholdstatus_t _user_set_signal_stack(const stack_t *newUserStack,
2410b70ea59SAxel Dörfler	stack_t *oldUserStack);
24224df6592SIngo Weinholdint64 _user_restore_signal_frame(struct signal_frame_data* signalFrameData);
243a9731b41SAxel Dörfler
244782c98afSIngo Weinhold#ifdef __cplusplus
24550374cbdSAxel Dörfler}
246782c98afSIngo Weinhold#endif
247782c98afSIngo Weinhold
248a9731b41SAxel Dörfler#endif	/* _KERNEL_SIGNAL_H */
249