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)
31 static 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
44 int
sigvec(signo,sv,osv)45 sigvec(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
71 int
sigsetmask(mask)72 sigsetmask(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
86 int
sigblock(mask)87 sigblock(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
101 int
sigpause(int mask)102 sigpause(int mask)
103 {
104 sigset_t set;
105
106 sigemptyset(&set);
107 set.__bits[0] = mask;
108 return (_sigsuspend(&set));
109 }
110
111 int
xsi_sigpause(int sig)112 xsi_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
123 int
sighold(int sig)124 sighold(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
134 int
sigignore(int sig)135 sigignore(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
144 int
sigrelse(int sig)145 sigrelse(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
155 void
sigset(int sig,void (* disp)(int))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