sigcompat.c revision 209932
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: head/lib/libc/compat-43/sigcompat.c 209932 2010-07-12 10:14:24Z kib $");
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	int error;
116
117	if (!_SIG_VALID(sig)) {
118		errno = EINVAL;
119		return (-1);
120	}
121	error = _sigprocmask(SIG_BLOCK, NULL, &set);
122	if (error != 0)
123		return (error);
124	sigdelset(&set, sig);
125	return (_sigsuspend(&set));
126}
127
128int
129sighold(int sig)
130{
131	sigset_t set;
132
133	sigemptyset(&set);
134	sigaddset(&set, sig);
135	return (_sigprocmask(SIG_BLOCK, &set, NULL));
136}
137
138int
139sigignore(int sig)
140{
141	struct sigaction sa;
142
143	bzero(&sa, sizeof(sa));
144	sa.sa_handler = SIG_IGN;
145	return (_sigaction(sig, &sa, NULL));
146}
147
148int
149sigrelse(int sig)
150{
151	sigset_t set;
152
153	sigemptyset(&set);
154	sigaddset(&set, sig);
155	return (_sigprocmask(SIG_UNBLOCK, &set, NULL));
156}
157
158void
159(*sigset(int sig, void (*disp)(int)))(int)
160{
161	sigset_t set, pset;
162	struct sigaction sa, psa;
163	int error;
164
165	sigemptyset(&set);
166	sigaddset(&set, sig);
167	error = _sigprocmask(SIG_BLOCK, NULL, &pset);
168	if (error == -1)
169		return (SIG_ERR);
170	if ((__sighandler_t *)disp == SIG_HOLD) {
171		error = _sigprocmask(SIG_BLOCK, &set, &pset);
172		if (error == -1)
173			return (SIG_ERR);
174		if (sigismember(&pset, sig))
175			return (SIG_HOLD);
176		else {
177			error = _sigaction(sig, NULL, &psa);
178			if (error == -1)
179				return (SIG_ERR);
180			return (psa.sa_handler);
181		}
182	} else {
183		error = _sigprocmask(SIG_UNBLOCK, &set, &pset);
184		if (error == -1)
185			return (SIG_ERR);
186	}
187
188	bzero(&sa, sizeof(sa));
189	sa.sa_handler = disp;
190	error = _sigaction(sig, &sa, &psa);
191	if (error == -1)
192		return (SIG_ERR);
193	if (sigismember(&pset, sig))
194		return (SIG_HOLD);
195	else
196		return (psa.sa_handler);
197}
198