]> CyberLeo.Net >> Repos - FreeBSD/releng/10.3.git/blob - sys/compat/linux/linux.c
- Copy stable/10@296371 to releng/10.3 in preparation for 10.3-RC1
[FreeBSD/releng/10.3.git] / sys / compat / linux / linux.c
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$");
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 }