1/*
2 * Copyright (c) 1989, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 4. Neither the name of the University nor the names of its contributors
14 *    may be used to endorse or promote products derived from this software
15 *    without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#if defined(LIBC_SCCS) && !defined(lint)
31static char sccsid[] = "@(#)sigcompat.c	8.1 (Berkeley) 6/2/93";
32#endif /* LIBC_SCCS and not lint */
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD$");
35
36#include "namespace.h"
37#include <sys/param.h>
38#include <errno.h>
39#include <signal.h>
40#include <string.h>
41#include "un-namespace.h"
42#include "libc_private.h"
43
44int
45sigvec(signo, sv, osv)
46	int signo;
47	struct sigvec *sv, *osv;
48{
49	struct sigaction sa, osa;
50	struct sigaction *sap, *osap;
51	int ret;
52
53	if (sv != NULL) {
54		sa.sa_handler = sv->sv_handler;
55		sa.sa_flags = sv->sv_flags ^ SV_INTERRUPT;
56		sigemptyset(&sa.sa_mask);
57		sa.sa_mask.__bits[0] = sv->sv_mask;
58		sap = &sa;
59	} else
60		sap = NULL;
61	osap = osv != NULL ? &osa : NULL;
62	ret = _sigaction(signo, sap, osap);
63	if (ret == 0 && osv != NULL) {
64		osv->sv_handler = osa.sa_handler;
65		osv->sv_flags = osa.sa_flags ^ SV_INTERRUPT;
66		osv->sv_mask = osa.sa_mask.__bits[0];
67	}
68	return (ret);
69}
70
71int
72sigsetmask(mask)
73	int mask;
74{
75	sigset_t set, oset;
76	int n;
77
78	sigemptyset(&set);
79	set.__bits[0] = mask;
80	n = _sigprocmask(SIG_SETMASK, &set, &oset);
81	if (n)
82		return (n);
83	return (oset.__bits[0]);
84}
85
86int
87sigblock(mask)
88	int mask;
89{
90	sigset_t set, oset;
91	int n;
92
93	sigemptyset(&set);
94	set.__bits[0] = mask;
95	n = _sigprocmask(SIG_BLOCK, &set, &oset);
96	if (n)
97		return (n);
98	return (oset.__bits[0]);
99}
100
101int
102sigpause(int mask)
103{
104	sigset_t set;
105
106	sigemptyset(&set);
107	set.__bits[0] = mask;
108	return (_sigsuspend(&set));
109}
110
111int
112xsi_sigpause(int sig)
113{
114	sigset_t set;
115
116	if (_sigprocmask(SIG_BLOCK, NULL, &set) == -1)
117		return (-1);
118	if (sigdelset(&set, sig) == -1)
119		return (-1);
120	return (_sigsuspend(&set));
121}
122
123int
124sighold(int sig)
125{
126	sigset_t set;
127
128	sigemptyset(&set);
129	if (sigaddset(&set, sig) == -1)
130		return (-1);
131	return (_sigprocmask(SIG_BLOCK, &set, NULL));
132}
133
134int
135sigignore(int sig)
136{
137	struct sigaction sa;
138
139	bzero(&sa, sizeof(sa));
140	sa.sa_handler = SIG_IGN;
141	return (_sigaction(sig, &sa, NULL));
142}
143
144int
145sigrelse(int sig)
146{
147	sigset_t set;
148
149	sigemptyset(&set);
150	if (sigaddset(&set, sig) == -1)
151		return (-1);
152	return (_sigprocmask(SIG_UNBLOCK, &set, NULL));
153}
154
155void
156(*sigset(int sig, void (*disp)(int)))(int)
157{
158	sigset_t set, pset;
159	struct sigaction sa, psa;
160
161	sigemptyset(&set);
162	if (sigaddset(&set, sig) == -1)
163		return (SIG_ERR);
164	if (_sigprocmask(SIG_BLOCK, NULL, &pset) == -1)
165		return (SIG_ERR);
166	if ((__sighandler_t *)disp == SIG_HOLD) {
167		if (_sigprocmask(SIG_BLOCK, &set, &pset) == -1)
168			return (SIG_ERR);
169		if (sigismember(&pset, sig))
170			return (SIG_HOLD);
171		else {
172			if (_sigaction(sig, NULL, &psa) == -1)
173				return (SIG_ERR);
174			return (psa.sa_handler);
175		}
176	} else {
177		if (_sigprocmask(SIG_UNBLOCK, &set, &pset) == -1)
178			return (SIG_ERR);
179	}
180
181	bzero(&sa, sizeof(sa));
182	sa.sa_handler = disp;
183	if (_sigaction(sig, &sa, &psa) == -1)
184		return (SIG_ERR);
185	if (sigismember(&pset, sig))
186		return (SIG_HOLD);
187	else
188		return (psa.sa_handler);
189}
190