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(int signo, struct sigvec *sv, struct sigvec *osv)
46{
47	struct sigaction sa, osa;
48	struct sigaction *sap, *osap;
49	int ret;
50
51	if (sv != NULL) {
52		sa.sa_handler = sv->sv_handler;
53		sa.sa_flags = sv->sv_flags ^ SV_INTERRUPT;
54		sigemptyset(&sa.sa_mask);
55		sa.sa_mask.__bits[0] = sv->sv_mask;
56		sap = &sa;
57	} else
58		sap = NULL;
59	osap = osv != NULL ? &osa : NULL;
60	ret = __libc_sigaction(signo, sap, osap);
61	if (ret == 0 && osv != NULL) {
62		osv->sv_handler = osa.sa_handler;
63		osv->sv_flags = osa.sa_flags ^ SV_INTERRUPT;
64		osv->sv_mask = osa.sa_mask.__bits[0];
65	}
66	return (ret);
67}
68
69int
70sigsetmask(int mask)
71{
72	sigset_t set, oset;
73	int n;
74
75	sigemptyset(&set);
76	set.__bits[0] = mask;
77	n = __libc_sigprocmask(SIG_SETMASK, &set, &oset);
78	if (n)
79		return (n);
80	return (oset.__bits[0]);
81}
82
83int
84sigblock(int mask)
85{
86	sigset_t set, oset;
87	int n;
88
89	sigemptyset(&set);
90	set.__bits[0] = mask;
91	n = __libc_sigprocmask(SIG_BLOCK, &set, &oset);
92	if (n)
93		return (n);
94	return (oset.__bits[0]);
95}
96
97int
98sigpause(int mask)
99{
100	sigset_t set;
101
102	sigemptyset(&set);
103	set.__bits[0] = mask;
104	return (__libc_sigsuspend(&set));
105}
106
107int
108xsi_sigpause(int sig)
109{
110	sigset_t set;
111
112	if (__libc_sigprocmask(SIG_BLOCK, NULL, &set) == -1)
113		return (-1);
114	if (sigdelset(&set, sig) == -1)
115		return (-1);
116	return (__libc_sigsuspend(&set));
117}
118
119int
120sighold(int sig)
121{
122	sigset_t set;
123
124	sigemptyset(&set);
125	if (sigaddset(&set, sig) == -1)
126		return (-1);
127	return (__libc_sigprocmask(SIG_BLOCK, &set, NULL));
128}
129
130int
131sigignore(int sig)
132{
133	struct sigaction sa;
134
135	bzero(&sa, sizeof(sa));
136	sa.sa_handler = SIG_IGN;
137	return (__libc_sigaction(sig, &sa, NULL));
138}
139
140int
141sigrelse(int sig)
142{
143	sigset_t set;
144
145	sigemptyset(&set);
146	if (sigaddset(&set, sig) == -1)
147		return (-1);
148	return (__libc_sigprocmask(SIG_UNBLOCK, &set, NULL));
149}
150
151void
152(*sigset(int sig, void (*disp)(int)))(int)
153{
154	sigset_t set, pset;
155	struct sigaction sa, psa;
156
157	sigemptyset(&set);
158	if (sigaddset(&set, sig) == -1)
159		return (SIG_ERR);
160	if (__libc_sigprocmask(SIG_BLOCK, NULL, &pset) == -1)
161		return (SIG_ERR);
162	if ((__sighandler_t *)disp == SIG_HOLD) {
163		if (__libc_sigprocmask(SIG_BLOCK, &set, &pset) == -1)
164			return (SIG_ERR);
165		if (sigismember(&pset, sig))
166			return (SIG_HOLD);
167		else {
168			if (__libc_sigaction(sig, NULL, &psa) == -1)
169				return (SIG_ERR);
170			return (psa.sa_handler);
171		}
172	} else {
173		if (__libc_sigprocmask(SIG_UNBLOCK, &set, &pset) == -1)
174			return (SIG_ERR);
175	}
176
177	bzero(&sa, sizeof(sa));
178	sa.sa_handler = disp;
179	if (__libc_sigaction(sig, &sa, &psa) == -1)
180		return (SIG_ERR);
181	if (sigismember(&pset, sig))
182		return (SIG_HOLD);
183	else
184		return (psa.sa_handler);
185}
186