1 1.24 christos /* $NetBSD: linux32_signal.c,v 1.24 2021/11/26 13:32:38 christos Exp $ */ 2 1.1 manu 3 1.1 manu /*- 4 1.1 manu * Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved. 5 1.1 manu * 6 1.1 manu * Redistribution and use in source and binary forms, with or without 7 1.1 manu * modification, are permitted provided that the following conditions 8 1.1 manu * are met: 9 1.1 manu * 1. Redistributions of source code must retain the above copyright 10 1.1 manu * notice, this list of conditions and the following disclaimer. 11 1.1 manu * 2. Redistributions in binary form must reproduce the above copyright 12 1.1 manu * notice, this list of conditions and the following disclaimer in the 13 1.1 manu * documentation and/or other materials provided with the distribution. 14 1.1 manu * 3. All advertising materials mentioning features or use of this software 15 1.1 manu * must display the following acknowledgement: 16 1.1 manu * This product includes software developed by Emmanuel Dreyfus 17 1.1 manu * 4. The name of the author may not be used to endorse or promote 18 1.1 manu * products derived from this software without specific prior written 19 1.1 manu * permission. 20 1.1 manu * 21 1.1 manu * THIS SOFTWARE IS PROVIDED BY THE THE AUTHOR AND CONTRIBUTORS ``AS IS'' 22 1.1 manu * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 23 1.1 manu * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 1.1 manu * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 25 1.1 manu * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 1.1 manu * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 1.1 manu * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 1.1 manu * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 1.1 manu * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 1.1 manu * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 1.1 manu * POSSIBILITY OF SUCH DAMAGE. 32 1.1 manu */ 33 1.6 lukem 34 1.6 lukem #include <sys/cdefs.h> 35 1.24 christos __KERNEL_RCSID(0, "$NetBSD: linux32_signal.c,v 1.24 2021/11/26 13:32:38 christos Exp $"); 36 1.6 lukem 37 1.1 manu #include <sys/param.h> 38 1.1 manu #include <sys/ucred.h> 39 1.1 manu #include <sys/signalvar.h> 40 1.1 manu #include <sys/lwp.h> 41 1.1 manu #include <sys/time.h> 42 1.2 ad #include <sys/proc.h> 43 1.14 christos #include <sys/wait.h> 44 1.1 manu 45 1.1 manu #include <compat/netbsd32/netbsd32.h> 46 1.1 manu 47 1.17 chs #include <compat/linux/common/linux_types.h> 48 1.14 christos #include <compat/linux/common/linux_signal.h> 49 1.22 thorpej #include <compat/linux/common/linux_sigevent.h> 50 1.17 chs 51 1.1 manu #include <compat/linux32/common/linux32_types.h> 52 1.1 manu #include <compat/linux32/common/linux32_signal.h> 53 1.22 thorpej #include <compat/linux32/common/linux32_sigevent.h> 54 1.14 christos #include <compat/linux32/common/linux32_siginfo.h> 55 1.1 manu #include <compat/linux32/linux32_syscallargs.h> 56 1.14 christos #include <compat/linux32/common/linux32_errno.h> 57 1.14 christos #include <compat/linux32/common/linux32_sched.h> 58 1.1 manu 59 1.1 manu #define linux32_sigemptyset(s) memset((s), 0, sizeof(*(s))) 60 1.1 manu #define linux32_sigismember(s, n) ((s)->sig[((n) - 1) / LINUX32__NSIG_BPW] \ 61 1.1 manu & (1 << ((n) - 1) % LINUX32__NSIG_BPW)) 62 1.1 manu #define linux32_sigaddset(s, n) ((s)->sig[((n) - 1) / LINUX32__NSIG_BPW] \ 63 1.1 manu |= (1 << ((n) - 1) % LINUX32__NSIG_BPW)) 64 1.1 manu 65 1.1 manu extern const int native_to_linux32_signo[]; 66 1.1 manu extern const int linux32_to_native_signo[]; 67 1.1 manu 68 1.10 christos #ifdef DEBUG_LINUX 69 1.10 christos #define DPRINTF(a) uprintf a 70 1.10 christos #else 71 1.10 christos #define DPRINTF(a) 72 1.10 christos #endif 73 1.10 christos 74 1.1 manu void 75 1.5 dsl linux32_to_native_sigset(sigset_t *bss, const linux32_sigset_t *lss) 76 1.1 manu { 77 1.1 manu int i, newsig; 78 1.1 manu 79 1.1 manu sigemptyset(bss); 80 1.1 manu for (i = 1; i < LINUX32__NSIG; i++) { 81 1.1 manu if (linux32_sigismember(lss, i)) { 82 1.1 manu newsig = linux32_to_native_signo[i]; 83 1.1 manu if (newsig) 84 1.1 manu sigaddset(bss, newsig); 85 1.1 manu } 86 1.1 manu } 87 1.1 manu } 88 1.1 manu 89 1.1 manu void 90 1.5 dsl native_to_linux32_sigset(linux32_sigset_t *lss, const sigset_t *bss) 91 1.1 manu { 92 1.1 manu int i, newsig; 93 1.1 manu 94 1.1 manu linux32_sigemptyset(lss); 95 1.1 manu for (i = 1; i < NSIG; i++) { 96 1.1 manu if (sigismember(bss, i)) { 97 1.1 manu newsig = native_to_linux32_signo[i]; 98 1.1 manu if (newsig) 99 1.1 manu linux32_sigaddset(lss, newsig); 100 1.1 manu } 101 1.1 manu } 102 1.1 manu } 103 1.1 manu 104 1.14 christos void 105 1.14 christos native_to_linux32_siginfo(linux32_siginfo_t *lsi, const struct _ksiginfo *ksi) 106 1.14 christos { 107 1.14 christos memset(lsi, 0, sizeof(*lsi)); 108 1.14 christos 109 1.14 christos lsi->lsi_signo = native_to_linux32_signo[ksi->_signo]; 110 1.14 christos lsi->lsi_errno = native_to_linux32_errno[ksi->_errno]; 111 1.14 christos lsi->lsi_code = native_to_linux32_si_code(ksi->_code); 112 1.14 christos 113 1.14 christos switch (ksi->_code) { 114 1.14 christos case SI_NOINFO: 115 1.14 christos break; 116 1.14 christos 117 1.14 christos case SI_USER: 118 1.14 christos lsi->lsi_pid = ksi->_reason._rt._pid; 119 1.14 christos lsi->lsi_uid = ksi->_reason._rt._uid; 120 1.14 christos if (lsi->lsi_signo == LINUX_SIGALRM || 121 1.14 christos lsi->lsi_signo >= LINUX_SIGRTMIN) 122 1.14 christos NETBSD32PTR32(lsi->lsi_value.sival_ptr, 123 1.14 christos ksi->_reason._rt._value.sival_ptr); 124 1.14 christos break; 125 1.14 christos 126 1.14 christos case SI_TIMER: 127 1.14 christos case SI_QUEUE: 128 1.14 christos lsi->lsi_uid = ksi->_reason._rt._uid; 129 1.14 christos lsi->lsi_uid = ksi->_reason._rt._uid; 130 1.14 christos NETBSD32PTR32(lsi->lsi_value.sival_ptr, 131 1.14 christos ksi->_reason._rt._value.sival_ptr); 132 1.14 christos break; 133 1.14 christos 134 1.14 christos case SI_ASYNCIO: 135 1.14 christos case SI_MESGQ: 136 1.14 christos NETBSD32PTR32(lsi->lsi_value.sival_ptr, 137 1.14 christos ksi->_reason._rt._value.sival_ptr); 138 1.14 christos break; 139 1.14 christos 140 1.14 christos default: 141 1.14 christos switch (ksi->_signo) { 142 1.14 christos case SIGCHLD: 143 1.14 christos lsi->lsi_uid = ksi->_reason._child._uid; 144 1.14 christos lsi->lsi_pid = ksi->_reason._child._pid; 145 1.14 christos lsi->lsi_status = native_to_linux32_si_status( 146 1.14 christos ksi->_code, ksi->_reason._child._status); 147 1.14 christos lsi->lsi_utime = ksi->_reason._child._utime; 148 1.14 christos lsi->lsi_stime = ksi->_reason._child._stime; 149 1.14 christos break; 150 1.14 christos 151 1.14 christos case SIGILL: 152 1.14 christos case SIGFPE: 153 1.14 christos case SIGSEGV: 154 1.14 christos case SIGBUS: 155 1.14 christos case SIGTRAP: 156 1.14 christos NETBSD32PTR32(lsi->lsi_addr, ksi->_reason._fault._addr); 157 1.14 christos break; 158 1.14 christos 159 1.14 christos case SIGIO: 160 1.14 christos lsi->lsi_fd = ksi->_reason._poll._fd; 161 1.14 christos lsi->lsi_band = ksi->_reason._poll._band; 162 1.14 christos break; 163 1.14 christos default: 164 1.14 christos break; 165 1.14 christos } 166 1.14 christos } 167 1.14 christos } 168 1.14 christos 169 1.1 manu unsigned int 170 1.5 dsl native_to_linux32_sigflags(const int bsf) 171 1.1 manu { 172 1.1 manu unsigned int lsf = 0; 173 1.1 manu if ((bsf & SA_NOCLDSTOP) != 0) 174 1.1 manu lsf |= LINUX32_SA_NOCLDSTOP; 175 1.1 manu if ((bsf & SA_NOCLDWAIT) != 0) 176 1.1 manu lsf |= LINUX32_SA_NOCLDWAIT; 177 1.1 manu if ((bsf & SA_ONSTACK) != 0) 178 1.1 manu lsf |= LINUX32_SA_ONSTACK; 179 1.1 manu if ((bsf & SA_RESTART) != 0) 180 1.1 manu lsf |= LINUX32_SA_RESTART; 181 1.1 manu if ((bsf & SA_NODEFER) != 0) 182 1.1 manu lsf |= LINUX32_SA_NOMASK; 183 1.1 manu if ((bsf & SA_RESETHAND) != 0) 184 1.1 manu lsf |= LINUX32_SA_ONESHOT; 185 1.1 manu if ((bsf & SA_SIGINFO) != 0) 186 1.1 manu lsf |= LINUX32_SA_SIGINFO; 187 1.1 manu return lsf; 188 1.1 manu } 189 1.1 manu 190 1.1 manu int 191 1.5 dsl linux32_to_native_sigflags(const unsigned long lsf) 192 1.1 manu { 193 1.1 manu int bsf = 0; 194 1.1 manu if ((lsf & LINUX32_SA_NOCLDSTOP) != 0) 195 1.1 manu bsf |= SA_NOCLDSTOP; 196 1.1 manu if ((lsf & LINUX32_SA_NOCLDWAIT) != 0) 197 1.1 manu bsf |= SA_NOCLDWAIT; 198 1.1 manu if ((lsf & LINUX32_SA_ONSTACK) != 0) 199 1.1 manu bsf |= SA_ONSTACK; 200 1.1 manu if ((lsf & LINUX32_SA_RESTART) != 0) 201 1.1 manu bsf |= SA_RESTART; 202 1.1 manu if ((lsf & LINUX32_SA_ONESHOT) != 0) 203 1.1 manu bsf |= SA_RESETHAND; 204 1.1 manu if ((lsf & LINUX32_SA_NOMASK) != 0) 205 1.1 manu bsf |= SA_NODEFER; 206 1.1 manu if ((lsf & LINUX32_SA_SIGINFO) != 0) 207 1.1 manu bsf |= SA_SIGINFO; 208 1.1 manu if ((lsf & ~LINUX32_SA_ALLBITS) != 0) { 209 1.1 manu #ifdef DEBUG_LINUX 210 1.1 manu printf("linux32_old_to_native_sigflags: " 211 1.1 manu "%lx extra bits ignored\n", lsf); 212 1.1 manu #endif 213 1.1 manu } 214 1.1 manu return bsf; 215 1.1 manu } 216 1.1 manu 217 1.1 manu void 218 1.5 dsl linux32_to_native_sigaction(struct sigaction *bsa, const struct linux32_sigaction *lsa) 219 1.1 manu { 220 1.21 riastrad memset(bsa, 0, sizeof(*bsa)); 221 1.1 manu bsa->sa_handler = NETBSD32PTR64(lsa->linux_sa_handler); 222 1.1 manu linux32_to_native_sigset(&bsa->sa_mask, &lsa->linux_sa_mask); 223 1.1 manu bsa->sa_flags = linux32_to_native_sigflags(lsa->linux_sa_flags); 224 1.1 manu } 225 1.1 manu 226 1.1 manu void 227 1.5 dsl native_to_linux32_sigaction(struct linux32_sigaction *lsa, const struct sigaction *bsa) 228 1.1 manu { 229 1.21 riastrad memset(lsa, 0, sizeof(*lsa)); 230 1.3 dsl NETBSD32PTR32(lsa->linux_sa_handler, bsa->sa_handler); 231 1.1 manu native_to_linux32_sigset(&lsa->linux_sa_mask, &bsa->sa_mask); 232 1.1 manu lsa->linux_sa_flags = native_to_linux32_sigflags(bsa->sa_flags); 233 1.3 dsl NETBSD32PTR32(lsa->linux_sa_restorer, NULL); 234 1.1 manu } 235 1.1 manu 236 1.1 manu void 237 1.23 thorpej native_to_linux32_sigaltstack(struct linux32_sigaltstack *lss, 238 1.23 thorpej const stack_t *bss) 239 1.1 manu { 240 1.20 maxv memset(lss, 0, sizeof(*lss)); 241 1.3 dsl NETBSD32PTR32(lss->ss_sp, bss->ss_sp); 242 1.1 manu lss->ss_size = bss->ss_size; 243 1.1 manu if (bss->ss_flags & SS_ONSTACK) 244 1.1 manu lss->ss_flags = LINUX32_SS_ONSTACK; 245 1.1 manu else if (bss->ss_flags & SS_DISABLE) 246 1.1 manu lss->ss_flags = LINUX32_SS_DISABLE; 247 1.1 manu else 248 1.1 manu lss->ss_flags = 0; 249 1.1 manu } 250 1.1 manu 251 1.1 manu 252 1.1 manu void 253 1.5 dsl native_to_linux32_old_sigset(linux32_old_sigset_t *lss, const sigset_t *bss) 254 1.1 manu { 255 1.1 manu linux32_sigset_t lsnew; 256 1.1 manu 257 1.1 manu native_to_linux32_sigset(&lsnew, bss); 258 1.1 manu 259 1.1 manu /* convert new sigset to old sigset */ 260 1.1 manu *lss = lsnew.sig[0]; 261 1.1 manu } 262 1.1 manu 263 1.1 manu void 264 1.5 dsl linux32_old_to_native_sigset(sigset_t *bss, const linux32_old_sigset_t *lss) 265 1.1 manu { 266 1.1 manu linux32_sigset_t ls; 267 1.1 manu 268 1.11 cegger memset(&ls, 0, sizeof(ls)); 269 1.1 manu ls.sig[0] = *lss; 270 1.1 manu 271 1.1 manu linux32_to_native_sigset(bss, &ls); 272 1.1 manu } 273 1.1 manu 274 1.1 manu int 275 1.7 dsl linux32_sys_rt_sigaction(struct lwp *l, const struct linux32_sys_rt_sigaction_args *uap, register_t *retval) 276 1.1 manu { 277 1.7 dsl /* { 278 1.1 manu syscallarg(int) signum; 279 1.1 manu syscallarg(const linux32_sigactionp_t) nsa; 280 1.1 manu syscallarg(linux32_sigactionp_t) osa; 281 1.1 manu syscallarg(netbsd32_size_t) sigsetsize; 282 1.7 dsl } */ 283 1.1 manu struct linux32_sigaction nls32; 284 1.1 manu struct linux32_sigaction ols32; 285 1.1 manu struct sigaction ns; 286 1.1 manu struct sigaction os; 287 1.1 manu int error; 288 1.1 manu int sig; 289 1.1 manu int vers = 0; 290 1.1 manu void *tramp = NULL; 291 1.1 manu 292 1.10 christos if (SCARG(uap, sigsetsize) != sizeof(linux32_sigset_t)) { 293 1.10 christos DPRINTF(("rt_sigaction: Inconsistent sigsetsize %u %zu\n", 294 1.10 christos SCARG(uap, sigsetsize), sizeof(linux32_sigset_t))); 295 1.1 manu return EINVAL; 296 1.10 christos } 297 1.1 manu 298 1.4 dsl if (SCARG_P32(uap, nsa) != NULL) { 299 1.4 dsl if ((error = copyin(SCARG_P32(uap, nsa), 300 1.10 christos &nls32, sizeof(nls32))) != 0) { 301 1.10 christos DPRINTF(("rt_sigaction: Copyin %d\n", error)); 302 1.1 manu return error; 303 1.10 christos } 304 1.1 manu linux32_to_native_sigaction(&ns, &nls32); 305 1.1 manu } 306 1.1 manu 307 1.1 manu sig = SCARG(uap, signum); 308 1.19 christos /* 309 1.19 christos * XXX: Linux has 33 realtime signals, the go binary wants to 310 1.19 christos * reset all of them; nothing else uses the last RT signal, so for 311 1.19 christos * now ignore it. 312 1.19 christos */ 313 1.19 christos if (sig == LINUX__NSIG) { 314 1.19 christos uprintf("%s: setting signal %d ignored\n", __func__, sig); 315 1.19 christos sig--; /* back to 63 which is ignored */ 316 1.19 christos } 317 1.10 christos if (sig < 0 || sig >= LINUX32__NSIG) { 318 1.10 christos DPRINTF(("rt_sigaction: Bad signal number %d %d\n", 319 1.10 christos sig, LINUX32__NSIG)); 320 1.1 manu return EINVAL; 321 1.10 christos } 322 1.1 manu if (sig > 0 && !linux32_to_native_signo[sig]) { 323 1.1 manu /* unknown signal... */ 324 1.1 manu os.sa_handler = SIG_IGN; 325 1.1 manu sigemptyset(&os.sa_mask); 326 1.1 manu os.sa_flags = 0; 327 1.1 manu } else { 328 1.2 ad if ((error = sigaction1(l, 329 1.1 manu linux32_to_native_signo[sig], 330 1.4 dsl SCARG_P32(uap, nsa) ? &ns : NULL, 331 1.4 dsl SCARG_P32(uap, osa) ? &os : NULL, 332 1.10 christos tramp, vers)) != 0) { 333 1.10 christos DPRINTF(("rt_sigaction: sigaction %d\n", error)); 334 1.1 manu return error; 335 1.10 christos } 336 1.1 manu } 337 1.1 manu 338 1.4 dsl if (SCARG_P32(uap, osa) != NULL) { 339 1.1 manu native_to_linux32_sigaction(&ols32, &os); 340 1.1 manu 341 1.4 dsl if ((error = copyout(&ols32, SCARG_P32(uap, osa), 342 1.10 christos sizeof(ols32))) != 0) { 343 1.10 christos DPRINTF(("rt_sigaction: Copyout %d\n", error)); 344 1.1 manu return error; 345 1.10 christos } 346 1.1 manu } 347 1.1 manu 348 1.1 manu return 0; 349 1.1 manu } 350 1.1 manu 351 1.1 manu int 352 1.7 dsl linux32_sys_rt_sigprocmask(struct lwp *l, const struct linux32_sys_rt_sigprocmask_args *uap, register_t *retval) 353 1.1 manu { 354 1.7 dsl /* { 355 1.1 manu syscallarg(int) how; 356 1.1 manu syscallarg(const linux32_sigsetp_t) set; 357 1.1 manu syscallarg(linux32_sigsetp_t) oset; 358 1.1 manu syscallarg(netbsd32_size_t) sigsetsize; 359 1.7 dsl } */ 360 1.1 manu struct proc *p = l->l_proc; 361 1.1 manu linux32_sigset_t nls32, ols32; 362 1.1 manu sigset_t ns, os; 363 1.1 manu int error; 364 1.1 manu int how; 365 1.1 manu 366 1.1 manu if (SCARG(uap, sigsetsize) != sizeof(linux32_sigset_t)) 367 1.1 manu return EINVAL; 368 1.1 manu 369 1.1 manu switch (SCARG(uap, how)) { 370 1.1 manu case LINUX32_SIG_BLOCK: 371 1.1 manu how = SIG_BLOCK; 372 1.1 manu break; 373 1.1 manu case LINUX32_SIG_UNBLOCK: 374 1.1 manu how = SIG_UNBLOCK; 375 1.1 manu break; 376 1.1 manu case LINUX32_SIG_SETMASK: 377 1.1 manu how = SIG_SETMASK; 378 1.1 manu break; 379 1.1 manu default: 380 1.1 manu return EINVAL; 381 1.1 manu break; 382 1.1 manu } 383 1.1 manu 384 1.4 dsl if (SCARG_P32(uap, set) != NULL) { 385 1.4 dsl if ((error = copyin(SCARG_P32(uap, set), 386 1.1 manu &nls32, sizeof(nls32))) != 0) 387 1.1 manu return error; 388 1.1 manu linux32_to_native_sigset(&ns, &nls32); 389 1.1 manu } 390 1.1 manu 391 1.8 ad mutex_enter(p->p_lock); 392 1.2 ad error = sigprocmask1(l, how, 393 1.4 dsl SCARG_P32(uap, set) ? &ns : NULL, 394 1.4 dsl SCARG_P32(uap, oset) ? &os : NULL); 395 1.8 ad mutex_exit(p->p_lock); 396 1.2 ad 397 1.2 ad if (error != 0) 398 1.1 manu return error; 399 1.1 manu 400 1.4 dsl if (SCARG_P32(uap, oset) != NULL) { 401 1.1 manu native_to_linux32_sigset(&ols32, &os); 402 1.1 manu if ((error = copyout(&ols32, 403 1.4 dsl SCARG_P32(uap, oset), sizeof(ols32))) != 0) 404 1.1 manu return error; 405 1.1 manu } 406 1.1 manu 407 1.1 manu return 0; 408 1.1 manu } 409 1.1 manu 410 1.1 manu int 411 1.7 dsl linux32_sys_kill(struct lwp *l, const struct linux32_sys_kill_args *uap, register_t *retval) 412 1.7 dsl { 413 1.7 dsl /* { 414 1.1 manu syscallarg(int) pid; 415 1.1 manu syscallarg(int) signum; 416 1.7 dsl } */ 417 1.1 manu 418 1.1 manu struct sys_kill_args ka; 419 1.1 manu int sig; 420 1.1 manu 421 1.1 manu SCARG(&ka, pid) = SCARG(uap, pid); 422 1.1 manu sig = SCARG(uap, signum); 423 1.1 manu if (sig < 0 || sig >= LINUX32__NSIG) 424 1.1 manu return (EINVAL); 425 1.1 manu SCARG(&ka, signum) = linux32_to_native_signo[sig]; 426 1.1 manu return sys_kill(l, &ka, retval); 427 1.1 manu } 428 1.1 manu 429 1.1 manu int 430 1.7 dsl linux32_sys_rt_sigsuspend(struct lwp *l, const struct linux32_sys_rt_sigsuspend_args *uap, register_t *retval) 431 1.7 dsl { 432 1.7 dsl /* { 433 1.1 manu syscallarg(linux32_sigsetp_t) unewset; 434 1.1 manu syscallarg(netbsd32_size_t) sigsetsize; 435 1.7 dsl } */ 436 1.1 manu linux32_sigset_t lss; 437 1.1 manu sigset_t bss; 438 1.1 manu int error; 439 1.1 manu 440 1.1 manu if (SCARG(uap, sigsetsize) != sizeof(linux32_sigset_t)) 441 1.1 manu return EINVAL; 442 1.1 manu 443 1.4 dsl if ((error = copyin(SCARG_P32(uap, unewset), 444 1.1 manu &lss, sizeof(linux32_sigset_t))) != 0) 445 1.1 manu return error; 446 1.1 manu 447 1.1 manu linux32_to_native_sigset(&bss, &lss); 448 1.1 manu 449 1.2 ad return sigsuspend1(l, &bss); 450 1.1 manu } 451 1.1 manu 452 1.14 christos static int 453 1.14 christos fetchss(const void *u, void *s, size_t len) 454 1.14 christos { 455 1.14 christos int error; 456 1.14 christos linux32_sigset_t lss; 457 1.14 christos 458 1.14 christos if ((error = copyin(u, &lss, sizeof(lss))) != 0) 459 1.14 christos return error; 460 1.14 christos 461 1.14 christos linux32_to_native_sigset(s, &lss); 462 1.14 christos return 0; 463 1.14 christos } 464 1.14 christos 465 1.14 christos static int 466 1.14 christos fetchts(const void *u, void *s, size_t len) 467 1.14 christos { 468 1.14 christos int error; 469 1.14 christos struct linux32_timespec lts; 470 1.14 christos 471 1.14 christos if ((error = copyin(u, <s, sizeof(lts))) != 0) 472 1.14 christos return error; 473 1.14 christos 474 1.14 christos linux32_to_native_timespec(s, <s); 475 1.14 christos return 0; 476 1.14 christos } 477 1.14 christos 478 1.14 christos static int 479 1.14 christos fakestorets(const void *u, void *s, size_t len) 480 1.14 christos { 481 1.14 christos /* Do nothing, sigtimedwait does not alter timeout like ours */ 482 1.14 christos return 0; 483 1.14 christos } 484 1.14 christos 485 1.14 christos static int 486 1.14 christos storeinfo(const void *s, void *u, size_t len) 487 1.14 christos { 488 1.14 christos linux32_siginfo_t lsi; 489 1.14 christos 490 1.14 christos 491 1.14 christos native_to_linux32_siginfo(&lsi, &((const siginfo_t *)s)->_info); 492 1.14 christos return copyout(&lsi, u, sizeof(lsi)); 493 1.14 christos } 494 1.14 christos 495 1.14 christos int 496 1.14 christos linux32_sys_rt_sigtimedwait(struct lwp *l, 497 1.14 christos const struct linux32_sys_rt_sigtimedwait_args *uap, register_t *retval) 498 1.14 christos { 499 1.14 christos /* { 500 1.14 christos syscallarg(const linux32_sigset_t *) set; 501 1.14 christos syscallarg(linux32_siginfo_t *) info); 502 1.14 christos syscallarg(const struct linux32_timespec *) timeout; 503 1.14 christos } */ 504 1.16 christos struct sys_____sigtimedwait50_args ap; 505 1.14 christos 506 1.16 christos SCARG(&ap, set) = SCARG_P32(uap, set); 507 1.16 christos SCARG(&ap, info) = SCARG_P32(uap, info); 508 1.16 christos SCARG(&ap, timeout) = SCARG_P32(uap, timeout); 509 1.16 christos 510 1.16 christos return sigtimedwait1(l, &ap, 511 1.14 christos retval, fetchss, storeinfo, fetchts, fakestorets); 512 1.14 christos } 513 1.14 christos 514 1.1 manu int 515 1.7 dsl linux32_sys_signal(struct lwp *l, const struct linux32_sys_signal_args *uap, register_t *retval) 516 1.1 manu { 517 1.7 dsl /* { 518 1.1 manu syscallarg(int) signum; 519 1.18 christos syscallarg(linux32_handlerp_t) handler; 520 1.7 dsl } */ 521 1.1 manu struct sigaction nbsa, obsa; 522 1.1 manu int error, sig; 523 1.1 manu 524 1.1 manu *retval = -1; 525 1.1 manu 526 1.1 manu sig = SCARG(uap, signum); 527 1.1 manu if (sig < 0 || sig >= LINUX32__NSIG) 528 1.1 manu return EINVAL; 529 1.1 manu 530 1.4 dsl nbsa.sa_handler = SCARG_P32(uap, handler); 531 1.1 manu sigemptyset(&nbsa.sa_mask); 532 1.1 manu nbsa.sa_flags = SA_RESETHAND | SA_NODEFER; 533 1.1 manu 534 1.2 ad if ((error = sigaction1(l, linux32_to_native_signo[sig], 535 1.1 manu &nbsa, &obsa, NULL, 0)) != 0) 536 1.1 manu return error; 537 1.1 manu 538 1.1 manu *retval = (int)(long)obsa.sa_handler; 539 1.1 manu return 0; 540 1.1 manu } 541 1.9 njoly 542 1.9 njoly int 543 1.9 njoly linux32_sys_rt_sigpending(struct lwp *l, const struct linux32_sys_rt_sigpending_args *uap, register_t *retval) 544 1.9 njoly { 545 1.9 njoly /* { 546 1.9 njoly syscallarg(linux32_sigsetp_t) set; 547 1.9 njoly syscallarg(netbsd32_size_t) sigsetsize; 548 1.9 njoly } */ 549 1.9 njoly sigset_t bss; 550 1.9 njoly linux32_sigset_t lss; 551 1.9 njoly 552 1.9 njoly if (SCARG(uap, sigsetsize) != sizeof(linux32_sigset_t)) 553 1.9 njoly return EINVAL; 554 1.9 njoly 555 1.9 njoly sigpending1(l, &bss); 556 1.9 njoly native_to_linux32_sigset(&lss, &bss); 557 1.9 njoly return copyout(&lss, SCARG_P32(uap, set), sizeof(lss)); 558 1.9 njoly } 559 1.12 njoly 560 1.12 njoly int 561 1.12 njoly linux32_sys_siggetmask(struct lwp *l, const void *v, register_t *retval) 562 1.12 njoly { 563 1.12 njoly struct proc *p = l->l_proc; 564 1.12 njoly sigset_t bss; 565 1.12 njoly linux32_old_sigset_t lss; 566 1.12 njoly int error; 567 1.12 njoly 568 1.12 njoly mutex_enter(p->p_lock); 569 1.12 njoly error = sigprocmask1(l, SIG_SETMASK, 0, &bss); 570 1.12 njoly mutex_exit(p->p_lock); 571 1.12 njoly if (error) 572 1.12 njoly return error; 573 1.12 njoly native_to_linux32_old_sigset(&lss, &bss); 574 1.12 njoly *retval = lss; 575 1.12 njoly return 0; 576 1.12 njoly } 577 1.12 njoly 578 1.12 njoly int 579 1.12 njoly linux32_sys_sigsetmask(struct lwp *l, const struct linux32_sys_sigsetmask_args *uap, register_t *retval) 580 1.12 njoly { 581 1.12 njoly /* { 582 1.12 njoly syscallarg(linux32_old_sigset_t) mask; 583 1.12 njoly } */ 584 1.12 njoly sigset_t nbss, obss; 585 1.12 njoly linux32_old_sigset_t nlss, olss; 586 1.12 njoly struct proc *p = l->l_proc; 587 1.12 njoly int error; 588 1.12 njoly 589 1.12 njoly nlss = SCARG(uap, mask); 590 1.12 njoly linux32_old_to_native_sigset(&nbss, &nlss); 591 1.12 njoly mutex_enter(p->p_lock); 592 1.12 njoly error = sigprocmask1(l, SIG_SETMASK, &nbss, &obss); 593 1.12 njoly mutex_exit(p->p_lock); 594 1.12 njoly if (error) 595 1.12 njoly return error; 596 1.12 njoly native_to_linux32_old_sigset(&olss, &obss); 597 1.12 njoly *retval = olss; 598 1.12 njoly return 0; 599 1.12 njoly } 600 1.13 njoly 601 1.13 njoly int 602 1.13 njoly linux32_sys_rt_queueinfo(struct lwp *l, const struct linux32_sys_rt_queueinfo_args *uap, register_t *retval) 603 1.13 njoly { 604 1.13 njoly /* 605 1.13 njoly syscallarg(int) pid; 606 1.13 njoly syscallarg(int) sig; 607 1.13 njoly syscallarg(linux32_siginfop_t) uinfo; 608 1.13 njoly */ 609 1.13 njoly int error; 610 1.13 njoly linux32_siginfo_t info; 611 1.13 njoly 612 1.13 njoly error = copyin(SCARG_P32(uap, uinfo), &info, sizeof(info)); 613 1.13 njoly if (error) 614 1.13 njoly return error; 615 1.13 njoly if (info.lsi_code >= 0) 616 1.13 njoly return EPERM; 617 1.13 njoly 618 1.13 njoly /* XXX To really implement this we need to */ 619 1.13 njoly /* XXX keep a list of queued signals somewhere. */ 620 1.13 njoly return linux32_sys_kill(l, (const void *)uap, retval); 621 1.13 njoly } 622 1.14 christos 623 1.14 christos int 624 1.14 christos native_to_linux32_si_code(int code) 625 1.14 christos { 626 1.14 christos int si_codes[] = { 627 1.14 christos LINUX32_SI_USER, LINUX32_SI_QUEUE, LINUX32_SI_TIMER, 628 1.14 christos LINUX32_SI_ASYNCIO, LINUX32_SI_MESGQ, LINUX32_SI_TKILL /* SI_LWP */ 629 1.14 christos }; 630 1.14 christos 631 1.14 christos if (code <= 0 && -code < __arraycount(si_codes)) 632 1.14 christos return si_codes[-code]; 633 1.14 christos 634 1.14 christos return code; 635 1.14 christos } 636 1.14 christos 637 1.14 christos int 638 1.14 christos native_to_linux32_si_status(int code, int status) 639 1.14 christos { 640 1.14 christos int sts; 641 1.14 christos 642 1.14 christos switch (code) { 643 1.14 christos case CLD_CONTINUED: 644 1.14 christos sts = LINUX_SIGCONT; 645 1.14 christos break; 646 1.14 christos case CLD_EXITED: 647 1.14 christos sts = WEXITSTATUS(status); 648 1.14 christos break; 649 1.14 christos case CLD_STOPPED: 650 1.14 christos case CLD_TRAPPED: 651 1.14 christos case CLD_DUMPED: 652 1.14 christos case CLD_KILLED: 653 1.14 christos default: 654 1.14 christos sts = native_to_linux32_signo[WTERMSIG(status)]; 655 1.14 christos break; 656 1.14 christos } 657 1.14 christos 658 1.14 christos return sts; 659 1.14 christos } 660 1.22 thorpej 661 1.22 thorpej int 662 1.22 thorpej linux32_to_native_sigevent(struct sigevent *nsep, 663 1.22 thorpej const struct linux32_sigevent *lsep) 664 1.22 thorpej { 665 1.22 thorpej memset(nsep, 0, sizeof(*nsep)); 666 1.22 thorpej 667 1.22 thorpej switch (lsep->sigev_notify) { 668 1.22 thorpej case LINUX_SIGEV_SIGNAL: 669 1.22 thorpej nsep->sigev_notify = SIGEV_SIGNAL; 670 1.22 thorpej break; 671 1.22 thorpej 672 1.22 thorpej case LINUX_SIGEV_NONE: 673 1.22 thorpej nsep->sigev_notify = SIGEV_NONE; 674 1.22 thorpej break; 675 1.22 thorpej 676 1.22 thorpej case LINUX_SIGEV_THREAD: 677 1.22 thorpej case LINUX_SIGEV_THREAD_ID: 678 1.22 thorpej default: 679 1.22 thorpej return ENOTSUP; 680 1.22 thorpej } 681 1.22 thorpej 682 1.22 thorpej nsep->sigev_value.sival_ptr = 683 1.22 thorpej NETBSD32PTR64(lsep->sigev_value.sival_ptr); 684 1.22 thorpej 685 1.22 thorpej if (lsep->sigev_signo < 0 || lsep->sigev_signo >= LINUX32__NSIG) { 686 1.22 thorpej return EINVAL; 687 1.22 thorpej } 688 1.22 thorpej nsep->sigev_signo = linux32_to_native_signo[lsep->sigev_signo]; 689 1.22 thorpej 690 1.22 thorpej return 0; 691 1.22 thorpej } 692 1.22 thorpej 693 1.22 thorpej int 694 1.22 thorpej linux32_sigevent_copyin(const void *src, void *dst, size_t size) 695 1.22 thorpej { 696 1.22 thorpej struct linux32_sigevent lse; 697 1.22 thorpej struct sigevent *sep = dst; 698 1.22 thorpej int error; 699 1.22 thorpej 700 1.22 thorpej KASSERT(size == sizeof(*sep)); 701 1.22 thorpej 702 1.22 thorpej error = copyin(src, &lse, sizeof(lse)); 703 1.22 thorpej if (error) { 704 1.22 thorpej return error; 705 1.22 thorpej } 706 1.22 thorpej 707 1.22 thorpej return linux32_to_native_sigevent(sep, &lse); 708 1.22 thorpej } 709