xref: /haiku/src/system/libroot/posix/signal/signal.cpp (revision ae9019359606f1db67632ef51a77ce70001d3770)
124df6592SIngo Weinhold /*
224df6592SIngo Weinhold  * Copyright 2002-2011, Haiku, Inc. All rights reserved.
324df6592SIngo Weinhold  * Distributed under the terms of the MIT license.
424df6592SIngo Weinhold  *
524df6592SIngo Weinhold  * Author:
624df6592SIngo Weinhold  *		Daniel Reinhold, danielre@users.sf.net
724df6592SIngo Weinhold  *		Ingo Weinhold, ingo_weinhold@gmx.de
824df6592SIngo Weinhold  */
924df6592SIngo Weinhold 
1024df6592SIngo Weinhold 
1124df6592SIngo Weinhold #include <signal.h>
1224df6592SIngo Weinhold 
1324df6592SIngo Weinhold #include <errno.h>
1424df6592SIngo Weinhold #include <stdio.h>
1524df6592SIngo Weinhold 
1624df6592SIngo Weinhold #include <symbol_versioning.h>
1724df6592SIngo Weinhold 
18*ae901935SOliver Tappe #include <errno_private.h>
1924df6592SIngo Weinhold #include <signal_private.h>
2024df6592SIngo Weinhold 
2124df6592SIngo Weinhold 
2224df6592SIngo Weinhold static __sighandler_t
2324df6592SIngo Weinhold signal_common(int signal, __sighandler_t signalHandler, int flags)
2424df6592SIngo Weinhold {
2524df6592SIngo Weinhold 	struct sigaction newAction, oldAction;
2624df6592SIngo Weinhold 
2724df6592SIngo Weinhold 	// setup the replacement sigaction
2824df6592SIngo Weinhold 	newAction.sa_handler = signalHandler;
2924df6592SIngo Weinhold 	newAction.sa_mask = 0;
3024df6592SIngo Weinhold 	newAction.sa_flags = flags;
3124df6592SIngo Weinhold 
3224df6592SIngo Weinhold 	if (__sigaction(signal, &newAction, &oldAction) != 0)
3324df6592SIngo Weinhold 		return SIG_ERR;
3424df6592SIngo Weinhold 
3524df6592SIngo Weinhold 	// success, return the original handler
3624df6592SIngo Weinhold 	return oldAction.sa_handler;
3724df6592SIngo Weinhold }
3824df6592SIngo Weinhold 
3924df6592SIngo Weinhold 
4024df6592SIngo Weinhold __sighandler_t
4124df6592SIngo Weinhold __signal_beos(int signal, __sighandler_t signalHandler)
4224df6592SIngo Weinhold {
4324df6592SIngo Weinhold 	// check signal range
4424df6592SIngo Weinhold 	if (signal < 0 || signal > MAX_SIGNAL_NUMBER_BEOS) {
45*ae901935SOliver Tappe 		__set_errno(EINVAL);
4624df6592SIngo Weinhold 		return SIG_ERR;
4724df6592SIngo Weinhold 	}
4824df6592SIngo Weinhold 
4924df6592SIngo Weinhold 	// set the signal handler
5024df6592SIngo Weinhold 	__sighandler_t result = signal_common(signal, signalHandler,
5124df6592SIngo Weinhold 		SA_BEOS_COMPATIBLE_HANDLER);
5224df6592SIngo Weinhold 	if (result == SIG_ERR)
5324df6592SIngo Weinhold 		return SIG_ERR;
5424df6592SIngo Weinhold 
5524df6592SIngo Weinhold 	// If the signal is SIGSEGV, set the same signal handler for SIGBUS. Those
5624df6592SIngo Weinhold 	// constants had the same value under BeOS.
5724df6592SIngo Weinhold 	if (signal == SIGSEGV)
5824df6592SIngo Weinhold 		signal_common(SIGBUS, signalHandler, SA_BEOS_COMPATIBLE_HANDLER);
5924df6592SIngo Weinhold 
6024df6592SIngo Weinhold 	return result;
6124df6592SIngo Weinhold }
6224df6592SIngo Weinhold 
6324df6592SIngo Weinhold 
6424df6592SIngo Weinhold __sighandler_t
6524df6592SIngo Weinhold __signal(int signal, __sighandler_t signalHandler)
6624df6592SIngo Weinhold {
6724df6592SIngo Weinhold 	return signal_common(signal, signalHandler, 0);
6824df6592SIngo Weinhold }
6924df6592SIngo Weinhold 
7024df6592SIngo Weinhold 
7124df6592SIngo Weinhold DEFINE_LIBROOT_KERNEL_SYMBOL_VERSION("__signal_beos", "signal@", "BASE");
7224df6592SIngo Weinhold 
7324df6592SIngo Weinhold DEFINE_LIBROOT_KERNEL_SYMBOL_VERSION("__signal", "signal@@", "1_ALPHA4");
74