1/*
2 * Copyright 2007, Vasilis Kaoutsis, kaoutsis@sch.gr
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include <signal.h>
8
9#include <symbol_versioning.h>
10
11#include <signal_private.h>
12
13
14__sighandler_t
15__sigset_beos(int signal, __sighandler_t signalHandler)
16{
17	// prepare new action
18	struct sigaction_beos newAction;
19	newAction.sa_handler = signalHandler;
20	newAction.sa_flags = 0;
21	if (signal == SIGCHLD && signalHandler == SIG_IGN) {
22		// In case of SIGCHLD the specification requires SA_NOCLDWAIT behavior.
23		newAction.sa_flags |= SA_NOCLDWAIT;
24	}
25	newAction.sa_mask = 0;
26
27	// set action
28	struct sigaction_beos oldAction;
29	if (__sigaction_beos(signal,
30			signalHandler == SIG_HOLD ? NULL : &newAction, &oldAction) == -1) {
31		return SIG_ERR;
32	}
33
34	// prepare new signal mask
35	sigset_t_beos newSet = 0;
36	__sigaddset_beos(&newSet, signal);
37
38	// set signal mask
39	sigset_t_beos oldSet;
40	if (signalHandler == SIG_HOLD) {
41		if (__pthread_sigmask_beos(SIG_BLOCK, &newSet, &oldSet) == -1)
42			return SIG_ERR;
43	} else {
44		// Disposition is not equal to SIG_HOLD, so sig will be removed from the
45		// calling process' signal mask.
46		if (__pthread_sigmask_beos(SIG_UNBLOCK, &newSet, &oldSet) == -1)
47			return SIG_ERR;
48	}
49
50	return __sigismember_beos(&oldSet, signal)
51		? SIG_HOLD : oldAction.sa_handler;
52}
53
54
55__sighandler_t
56__sigset(int signal, __sighandler_t signalHandler)
57{
58	// prepare new action
59	struct sigaction newAction;
60	newAction.sa_handler = signalHandler;
61	newAction.sa_flags = 0;
62	if (signal == SIGCHLD && signalHandler == SIG_IGN) {
63		// In case of SIGCHLD the specification requires SA_NOCLDWAIT behavior.
64		newAction.sa_flags |= SA_NOCLDWAIT;
65	}
66	newAction.sa_mask = 0;
67
68	// set action
69	struct sigaction oldAction;
70	if (__sigaction(signal,
71			signalHandler == SIG_HOLD ? NULL : &newAction, &oldAction) == -1) {
72		return SIG_ERR;
73	}
74
75	// prepare new signal mask
76	sigset_t newSet = 0;
77	sigaddset(&newSet, signal);
78
79	// set signal mask
80	sigset_t oldSet;
81	if (signalHandler == SIG_HOLD) {
82		if (sigprocmask(SIG_BLOCK, &newSet, &oldSet) == -1)
83			return SIG_ERR;
84	} else {
85		// Disposition is not equal to SIG_HOLD, so sig will be
86		// removed from the calling process' signal mask.
87		if (sigprocmask(SIG_UNBLOCK, &newSet, &oldSet) == -1)
88			return SIG_ERR;
89	}
90
91	return sigismember(&oldSet, signal) ? SIG_HOLD : oldAction.sa_handler;
92}
93
94
95DEFINE_LIBROOT_KERNEL_SYMBOL_VERSION("__sigset_beos", "sigset@", "BASE");
96
97DEFINE_LIBROOT_KERNEL_SYMBOL_VERSION("__sigset", "sigset@@", "1_ALPHA4");
98