1 /*-
2 * Copyright (c) 2015 Dmitry Chagin
3 * 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 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD: releng/11.0/sys/compat/linux/linux.c 283474 2015-05-24 17:47:20Z dchagin $");
29
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/signalvar.h>
33
34 #include <compat/linux/linux.h>
35
36
37 static int bsd_to_linux_sigtbl[LINUX_SIGTBLSZ] = {
38 LINUX_SIGHUP, /* SIGHUP */
39 LINUX_SIGINT, /* SIGINT */
40 LINUX_SIGQUIT, /* SIGQUIT */
41 LINUX_SIGILL, /* SIGILL */
42 LINUX_SIGTRAP, /* SIGTRAP */
43 LINUX_SIGABRT, /* SIGABRT */
44 0, /* SIGEMT */
45 LINUX_SIGFPE, /* SIGFPE */
46 LINUX_SIGKILL, /* SIGKILL */
47 LINUX_SIGBUS, /* SIGBUS */
48 LINUX_SIGSEGV, /* SIGSEGV */
49 LINUX_SIGSYS, /* SIGSYS */
50 LINUX_SIGPIPE, /* SIGPIPE */
51 LINUX_SIGALRM, /* SIGALRM */
52 LINUX_SIGTERM, /* SIGTERM */
53 LINUX_SIGURG, /* SIGURG */
54 LINUX_SIGSTOP, /* SIGSTOP */
55 LINUX_SIGTSTP, /* SIGTSTP */
56 LINUX_SIGCONT, /* SIGCONT */
57 LINUX_SIGCHLD, /* SIGCHLD */
58 LINUX_SIGTTIN, /* SIGTTIN */
59 LINUX_SIGTTOU, /* SIGTTOU */
60 LINUX_SIGIO, /* SIGIO */
61 LINUX_SIGXCPU, /* SIGXCPU */
62 LINUX_SIGXFSZ, /* SIGXFSZ */
63 LINUX_SIGVTALRM,/* SIGVTALRM */
64 LINUX_SIGPROF, /* SIGPROF */
65 LINUX_SIGWINCH, /* SIGWINCH */
66 0, /* SIGINFO */
67 LINUX_SIGUSR1, /* SIGUSR1 */
68 LINUX_SIGUSR2 /* SIGUSR2 */
69 };
70
71 static int linux_to_bsd_sigtbl[LINUX_SIGTBLSZ] = {
72 SIGHUP, /* LINUX_SIGHUP */
73 SIGINT, /* LINUX_SIGINT */
74 SIGQUIT, /* LINUX_SIGQUIT */
75 SIGILL, /* LINUX_SIGILL */
76 SIGTRAP, /* LINUX_SIGTRAP */
77 SIGABRT, /* LINUX_SIGABRT */
78 SIGBUS, /* LINUX_SIGBUS */
79 SIGFPE, /* LINUX_SIGFPE */
80 SIGKILL, /* LINUX_SIGKILL */
81 SIGUSR1, /* LINUX_SIGUSR1 */
82 SIGSEGV, /* LINUX_SIGSEGV */
83 SIGUSR2, /* LINUX_SIGUSR2 */
84 SIGPIPE, /* LINUX_SIGPIPE */
85 SIGALRM, /* LINUX_SIGALRM */
86 SIGTERM, /* LINUX_SIGTERM */
87 SIGBUS, /* LINUX_SIGSTKFLT */
88 SIGCHLD, /* LINUX_SIGCHLD */
89 SIGCONT, /* LINUX_SIGCONT */
90 SIGSTOP, /* LINUX_SIGSTOP */
91 SIGTSTP, /* LINUX_SIGTSTP */
92 SIGTTIN, /* LINUX_SIGTTIN */
93 SIGTTOU, /* LINUX_SIGTTOU */
94 SIGURG, /* LINUX_SIGURG */
95 SIGXCPU, /* LINUX_SIGXCPU */
96 SIGXFSZ, /* LINUX_SIGXFSZ */
97 SIGVTALRM, /* LINUX_SIGVTALARM */
98 SIGPROF, /* LINUX_SIGPROF */
99 SIGWINCH, /* LINUX_SIGWINCH */
100 SIGIO, /* LINUX_SIGIO */
101 /*
102 * FreeBSD does not have SIGPWR signal, map Linux SIGPWR signal
103 * to the first unused FreeBSD signal number. Since Linux supports
104 * signals from 1 to 64 we are ok here as our SIGRTMIN = 65.
105 */
106 SIGRTMIN, /* LINUX_SIGPWR */
107 SIGSYS /* LINUX_SIGSYS */
108 };
109
110 /*
111 * Map Linux RT signals to the FreeBSD RT signals.
112 */
113 static inline int
114 linux_to_bsd_rt_signal(int sig)
115 {
116
117 return (SIGRTMIN + 1 + sig - LINUX_SIGRTMIN);
118 }
119
120 static inline int
121 bsd_to_linux_rt_signal(int sig)
122 {
123
124 return (sig - SIGRTMIN - 1 + LINUX_SIGRTMIN);
125 }
126
127 int
128 linux_to_bsd_signal(int sig)
129 {
130
131 KASSERT(sig > 0 && sig <= LINUX_SIGRTMAX, ("Invalid Linux signal\n"));
132
133 if (sig < LINUX_SIGRTMIN)
134 return (linux_to_bsd_sigtbl[_SIG_IDX(sig)]);
135
136 return (linux_to_bsd_rt_signal(sig));
137 }
138
139 int
140 bsd_to_linux_signal(int sig)
141 {
142
143 if (sig <= LINUX_SIGTBLSZ)
144 return (bsd_to_linux_sigtbl[_SIG_IDX(sig)]);
145 if (sig == SIGRTMIN)
146 return (LINUX_SIGPWR);
147
148 return (bsd_to_linux_rt_signal(sig));
149 }
150
151 int
152 linux_to_bsd_sigaltstack(int lsa)
153 {
154 int bsa = 0;
155
156 if (lsa & LINUX_SS_DISABLE)
157 bsa |= SS_DISABLE;
158 /*
159 * Linux ignores SS_ONSTACK flag for ss
160 * parameter while FreeBSD prohibits it.
161 */
162 return (bsa);
163 }
164
165 int
166 bsd_to_linux_sigaltstack(int bsa)
167 {
168 int lsa = 0;
169
170 if (bsa & SS_DISABLE)
171 lsa |= LINUX_SS_DISABLE;
172 if (bsa & SS_ONSTACK)
173 lsa |= LINUX_SS_ONSTACK;
174 return (lsa);
175 }
176
177 void
178 linux_to_bsd_sigset(l_sigset_t *lss, sigset_t *bss)
179 {
180 int b, l;
181
182 SIGEMPTYSET(*bss);
183 for (l = 1; l <= LINUX_SIGRTMAX; l++) {
184 if (LINUX_SIGISMEMBER(*lss, l)) {
185 b = linux_to_bsd_signal(l);
186 if (b)
187 SIGADDSET(*bss, b);
188 }
189 }
190 }
191
192 void
193 bsd_to_linux_sigset(sigset_t *bss, l_sigset_t *lss)
194 {
195 int b, l;
196
197 LINUX_SIGEMPTYSET(*lss);
198 for (b = 1; b <= SIGRTMAX; b++) {
199 if (SIGISMEMBER(*bss, b)) {
200 l = bsd_to_linux_signal(b);
201 if (l)
202 LINUX_SIGADDSET(*lss, l);
203 }
204 }
205 }
Cache object: 296001c8accef9e0fd88193d96245384
|