xref: /haiku/src/system/libroot/posix/signal/sigset.cpp (revision 579f1dbca962a2a03df54f69fdc6e9423f91f20e)
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 
95 DEFINE_LIBROOT_KERNEL_SYMBOL_VERSION("__sigset_beos", "sigset@", "BASE");
96 
97 DEFINE_LIBROOT_KERNEL_SYMBOL_VERSION("__sigset", "sigset@@", "1_ALPHA4");
98