1/*
2 * Copyright (c) 2001-2005 Todd C. Miller <Todd.Miller@courtesan.com>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 *
16 * Sponsored in part by the Defense Advanced Research Projects
17 * Agency (DARPA) and Air Force Research Laboratory, Air Force
18 * Materiel Command, USAF, under agreement number F39502-99-1-0512.
19 */
20
21#include <config.h>
22
23#include <sys/types.h>
24
25#include <signal.h>
26#include <errno.h>
27
28#include "missing.h"
29
30int
31sigaction(signo, sa, osa)
32    int signo;
33    const sigaction_t *sa;
34    sigaction_t *osa;
35{
36    sigaction_t nsa;
37    int error;
38
39    /* We must reverse SV_INTERRUPT since it is the opposite of SA_RESTART */
40    if (sa) {
41	nsa = *sa;
42	nsa.sa_flags ^= SV_INTERRUPT;
43	sa = &nsa;
44    }
45
46    error = sigvec(signo, sa, osa);
47    if (!error && osa)
48	osa->sa_flags ^= SV_INTERRUPT;		/* flip SV_INTERRUPT as above */
49
50    return error;
51}
52
53int
54sigemptyset(set)
55    sigset_t *set;
56{
57
58    *set = 0;
59    return 0;
60}
61
62int
63sigfillset(set)
64    sigset_t *set;
65{
66
67    *set = ~0;;
68    return 0;
69}
70
71int
72sigaddset(set, signo)
73    sigset_t *set;
74    int signo;
75{
76
77    if (signo <= 0 || signo >= NSIG) {
78	errno = EINVAL;
79	return -1;
80    }
81
82    SET(*set, sigmask(signo));
83    return 0;
84}
85
86int
87sigdelset(set, signo)
88    sigset_t *set;
89    int signo;
90{
91
92    if (signo <= 0 || signo >= NSIG) {
93	errno = EINVAL;
94	return -1;
95    }
96
97    CLR(*set, sigmask(signo));
98    return 0;
99}
100
101int
102sigismember(set, signo)
103    sigset_t *set;
104    int signo;
105{
106
107    return ISSET(*set, sigmask(signo));
108}
109
110int
111sigprocmask(how, set, oset)
112    int how;
113    const sigset_t *set;
114    sigset_t *oset;
115{
116    int mask;
117
118    /* If 'set' is NULL the user just wants the current signal mask. */
119    if (set == 0)
120	mask = sigblock(0);
121    else
122	switch (how) {
123	    case SIG_BLOCK:
124		mask = sigblock(*set);
125		break;
126	    case SIG_UNBLOCK:
127		mask = sigsetmask(sigblock(0) & ~(*set));
128		break;
129	    case SIG_SETMASK:
130		mask = sigsetmask(*set);
131		break;
132	    default:
133		return -1;
134	}
135
136    if (mask == -1)
137	return -1;
138    if (oset)
139	*oset = mask;
140    return 0;
141}
142