1/*
2 * Copyright 2002-2011, Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT license.
4 *
5 * Author:
6 *		Daniel Reinhold, danielre@users.sf.net
7 *		Ingo Weinhod, ingo_weinhold@gmx.de
8 */
9
10
11#include <errno.h>
12#include <signal.h>
13
14#include <syscall_utils.h>
15
16#include <signal_defs.h>
17#include <symbol_versioning.h>
18#include <syscalls.h>
19
20#include <errno_private.h>
21#include <signal_private.h>
22
23
24int
25__sigaction_beos(int signal, const struct sigaction_beos* beosAction,
26	struct sigaction_beos* beosOldAction)
27{
28	// convert the new action
29	struct sigaction action;
30	if (beosAction != NULL) {
31		action.sa_handler = beosAction->sa_handler;
32		action.sa_mask = from_beos_sigset(beosAction->sa_mask);
33		action.sa_flags = beosAction->sa_flags | SA_BEOS_COMPATIBLE_HANDLER;
34		action.sa_userdata = beosAction->sa_userdata;
35	}
36
37	struct sigaction oldAction;
38	if (__sigaction(signal, beosAction != NULL ? &action : NULL,
39			beosOldAction != NULL ? &oldAction : NULL) != 0) {
40		return -1;
41	}
42
43	// If the signal is SIGSEGV, set the same signal action for SIGBUS. Those
44	// constants had the same value under BeOS.
45	if (beosAction != NULL && signal == SIGSEGV)
46		__sigaction(SIGBUS, &action, NULL);
47
48	// convert the old action back
49	if (beosOldAction != NULL) {
50		beosOldAction->sa_handler = oldAction.sa_handler;
51		beosOldAction->sa_mask = to_beos_sigset(oldAction.sa_mask);
52		beosOldAction->sa_flags
53			= oldAction.sa_flags & ~(int)SA_BEOS_COMPATIBLE_HANDLER;
54		beosOldAction->sa_userdata = oldAction.sa_userdata;
55	}
56
57	return 0;
58}
59
60
61int
62__sigaction(int signal, const struct sigaction* action,
63	struct sigaction* oldAction)
64{
65	RETURN_AND_SET_ERRNO(_kern_sigaction(signal, action, oldAction));
66}
67
68
69DEFINE_LIBROOT_KERNEL_SYMBOL_VERSION("__sigaction_beos", "sigaction@", "BASE");
70
71DEFINE_LIBROOT_KERNEL_SYMBOL_VERSION("__sigaction", "sigaction@@", "1_ALPHA4");
72