Annotation of src/sys/compat/linux/common/linux_signal.c, Revision 1.55
1.55 ! njoly 1: /* $NetBSD: linux_signal.c,v 1.54 2007/03/04 06:01:24 christos Exp $ */
1.53 ad 2:
1.16 fvdl 3: /*-
4: * Copyright (c) 1995, 1998 The NetBSD Foundation, Inc.
1.1 fvdl 5: * All rights reserved.
6: *
1.16 fvdl 7: * This code is derived from software contributed to The NetBSD Foundation
8: * by Frank van der Linden and Eric Haszlakiewicz.
9: *
1.1 fvdl 10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
18: * 3. All advertising materials mentioning features or use of this software
19: * must display the following acknowledgement:
1.16 fvdl 20: * This product includes software developed by the NetBSD
21: * Foundation, Inc. and its contributors.
22: * 4. Neither the name of The NetBSD Foundation nor the names of its
23: * contributors may be used to endorse or promote products derived
24: * from this software without specific prior written permission.
1.1 fvdl 25: *
1.16 fvdl 26: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36: * POSSIBILITY OF SUCH DAMAGE.
37: */
38: /*
1.1 fvdl 39: * heavily from: svr4_signal.c,v 1.7 1995/01/09 01:04:21 christos Exp
40: */
41:
1.14 erh 42: /*
43: * Functions in multiarch:
44: * linux_sys_signal : linux_sig_notalpha.c
45: * linux_sys_siggetmask : linux_sig_notalpha.c
46: * linux_sys_sigsetmask : linux_sig_notalpha.c
47: * linux_sys_pause : linux_sig_notalpha.c
48: * linux_sys_sigaction : linux_sigaction.c
49: *
50: */
51:
52: /*
53: * Unimplemented:
54: * linux_sys_rt_sigtimedwait : sigsuspend w/timeout.
55: */
1.32 lukem 56:
57: #include <sys/cdefs.h>
1.55 ! njoly 58: __KERNEL_RCSID(0, "$NetBSD: linux_signal.c,v 1.54 2007/03/04 06:01:24 christos Exp $");
1.21 drochner 59:
60: #define COMPAT_LINUX 1
1.14 erh 61:
1.1 fvdl 62: #include <sys/param.h>
63: #include <sys/systm.h>
64: #include <sys/namei.h>
65: #include <sys/proc.h>
66: #include <sys/filedesc.h>
67: #include <sys/ioctl.h>
68: #include <sys/mount.h>
69: #include <sys/kernel.h>
70: #include <sys/signal.h>
71: #include <sys/signalvar.h>
72: #include <sys/malloc.h>
73:
74: #include <sys/syscallargs.h>
75:
1.15 christos 76: #include <compat/linux/common/linux_types.h>
77: #include <compat/linux/common/linux_signal.h>
1.49 manu 78: #include <compat/linux/common/linux_exec.h> /* For emul_linux */
79: #include <compat/linux/common/linux_machdep.h> /* For LINUX_NPTL */
80: #include <compat/linux/common/linux_emuldata.h> /* for linux_emuldata */
1.17 erh 81: #include <compat/linux/common/linux_siginfo.h>
1.45 fvdl 82: #include <compat/linux/common/linux_sigevent.h>
1.15 christos 83: #include <compat/linux/common/linux_util.h>
1.55 ! njoly 84: #include <compat/linux/common/linux_ipc.h>
! 85: #include <compat/linux/common/linux_sem.h>
1.15 christos 86:
1.1 fvdl 87: #include <compat/linux/linux_syscallargs.h>
88:
1.14 erh 89: /* Locally used defines (in bsd<->linux conversion functions): */
1.11 perry 90: #define linux_sigemptyset(s) memset((s), 0, sizeof(*(s)))
1.20 itohy 91: #define linux_sigismember(s, n) ((s)->sig[((n) - 1) / LINUX__NSIG_BPW] \
92: & (1 << ((n) - 1) % LINUX__NSIG_BPW))
93: #define linux_sigaddset(s, n) ((s)->sig[((n) - 1) / LINUX__NSIG_BPW] \
94: |= (1 << ((n) - 1) % LINUX__NSIG_BPW))
1.6 mycroft 95:
1.36 christos 96: #ifdef DEBUG_LINUX
97: #define DPRINTF(a) uprintf a
98: #else
99: #define DPRINTF(a)
100: #endif
101:
1.37 christos 102: extern const int native_to_linux_signo[];
103: extern const int linux_to_native_signo[];
1.6 mycroft 104:
1.14 erh 105: /*
1.20 itohy 106: * Convert between Linux and BSD signal sets.
1.14 erh 107: */
1.20 itohy 108: #if LINUX__NSIG_WORDS > 1
1.6 mycroft 109: void
1.33 christos 110: linux_old_extra_to_native_sigset(bss, lss, extra)
111: sigset_t *bss;
1.14 erh 112: const linux_old_sigset_t *lss;
1.20 itohy 113: const unsigned long *extra;
114: {
115: linux_sigset_t lsnew;
116:
117: /* convert old sigset to new sigset */
118: linux_sigemptyset(&lsnew);
119: lsnew.sig[0] = *lss;
120: if (extra)
1.33 christos 121: memcpy(&lsnew.sig[1], extra,
122: sizeof(linux_sigset_t) - sizeof(linux_old_sigset_t));
1.20 itohy 123:
1.33 christos 124: linux_to_native_sigset(bss, &lsnew);
1.20 itohy 125: }
126:
127: void
1.33 christos 128: native_to_linux_old_extra_sigset(lss, extra, bss)
1.20 itohy 129: linux_old_sigset_t *lss;
130: unsigned long *extra;
1.33 christos 131: const sigset_t *bss;
1.20 itohy 132: {
133: linux_sigset_t lsnew;
134:
1.33 christos 135: native_to_linux_sigset(&lsnew, bss);
1.20 itohy 136:
137: /* convert new sigset to old sigset */
138: *lss = lsnew.sig[0];
139: if (extra)
1.33 christos 140: memcpy(extra, &lsnew.sig[1],
141: sizeof(linux_sigset_t) - sizeof(linux_old_sigset_t));
1.20 itohy 142: }
1.43 manu 143: #endif /* LINUX__NSIG_WORDS > 1 */
1.20 itohy 144:
145: void
1.33 christos 146: linux_to_native_sigset(bss, lss)
147: sigset_t *bss;
1.20 itohy 148: const linux_sigset_t *lss;
1.1 fvdl 149: {
150: int i, newsig;
151:
1.6 mycroft 152: sigemptyset(bss);
1.20 itohy 153: for (i = 1; i < LINUX__NSIG; i++) {
1.6 mycroft 154: if (linux_sigismember(lss, i)) {
1.37 christos 155: newsig = linux_to_native_signo[i];
1.1 fvdl 156: if (newsig)
1.6 mycroft 157: sigaddset(bss, newsig);
1.1 fvdl 158: }
159: }
160: }
161:
162: void
1.33 christos 163: native_to_linux_sigset(lss, bss)
164: linux_sigset_t *lss;
1.1 fvdl 165: const sigset_t *bss;
166: {
167: int i, newsig;
1.20 itohy 168:
1.6 mycroft 169: linux_sigemptyset(lss);
170: for (i = 1; i < NSIG; i++) {
171: if (sigismember(bss, i)) {
1.37 christos 172: newsig = native_to_linux_signo[i];
1.1 fvdl 173: if (newsig)
1.6 mycroft 174: linux_sigaddset(lss, newsig);
1.1 fvdl 175: }
176: }
177: }
178:
1.34 christos 179: unsigned int
180: native_to_linux_sigflags(bsf)
181: const int bsf;
1.33 christos 182: {
1.34 christos 183: unsigned int lsf = 0;
184: if ((bsf & SA_NOCLDSTOP) != 0)
185: lsf |= LINUX_SA_NOCLDSTOP;
186: if ((bsf & SA_NOCLDWAIT) != 0)
187: lsf |= LINUX_SA_NOCLDWAIT;
188: if ((bsf & SA_ONSTACK) != 0)
189: lsf |= LINUX_SA_ONSTACK;
190: if ((bsf & SA_RESTART) != 0)
191: lsf |= LINUX_SA_RESTART;
192: if ((bsf & SA_NODEFER) != 0)
193: lsf |= LINUX_SA_NOMASK;
194: if ((bsf & SA_RESETHAND) != 0)
195: lsf |= LINUX_SA_ONESHOT;
196: if ((bsf & SA_SIGINFO) != 0)
197: lsf |= LINUX_SA_SIGINFO;
198: return lsf;
1.33 christos 199: }
200:
1.34 christos 201: int
202: linux_to_native_sigflags(lsf)
203: const unsigned long lsf;
1.33 christos 204: {
1.34 christos 205: int bsf = 0;
206: if ((lsf & LINUX_SA_NOCLDSTOP) != 0)
207: bsf |= SA_NOCLDSTOP;
208: if ((lsf & LINUX_SA_NOCLDWAIT) != 0)
209: bsf |= SA_NOCLDWAIT;
210: if ((lsf & LINUX_SA_ONSTACK) != 0)
211: bsf |= SA_ONSTACK;
212: if ((lsf & LINUX_SA_RESTART) != 0)
213: bsf |= SA_RESTART;
214: if ((lsf & LINUX_SA_ONESHOT) != 0)
215: bsf |= SA_RESETHAND;
216: if ((lsf & LINUX_SA_NOMASK) != 0)
217: bsf |= SA_NODEFER;
218: if ((lsf & LINUX_SA_SIGINFO) != 0)
219: bsf |= SA_SIGINFO;
1.50 christos 220: if ((lsf & ~LINUX_SA_ALLBITS) != 0) {
1.36 christos 221: DPRINTF(("linux_old_to_native_sigflags: "
222: "%lx extra bits ignored\n", lsf));
1.50 christos 223: }
1.34 christos 224: return bsf;
1.33 christos 225: }
226:
1.1 fvdl 227: /*
1.46 manu 228: * Convert between Linux and BSD sigaction structures.
1.1 fvdl 229: */
230: void
1.33 christos 231: linux_old_to_native_sigaction(bsa, lsa)
1.14 erh 232: struct sigaction *bsa;
1.33 christos 233: const struct linux_old_sigaction *lsa;
1.14 erh 234: {
1.39 christos 235: bsa->sa_handler = lsa->linux_sa_handler;
236: linux_old_to_native_sigset(&bsa->sa_mask, &lsa->linux_sa_mask);
237: bsa->sa_flags = linux_to_native_sigflags(lsa->linux_sa_flags);
1.14 erh 238: }
239:
240: void
1.33 christos 241: native_to_linux_old_sigaction(lsa, bsa)
1.14 erh 242: struct linux_old_sigaction *lsa;
1.33 christos 243: const struct sigaction *bsa;
1.14 erh 244: {
1.39 christos 245: lsa->linux_sa_handler = bsa->sa_handler;
246: native_to_linux_old_sigset(&lsa->linux_sa_mask, &bsa->sa_mask);
247: lsa->linux_sa_flags = native_to_linux_sigflags(bsa->sa_flags);
1.34 christos 248: #ifndef __alpha__
1.39 christos 249: lsa->linux_sa_restorer = NULL;
1.34 christos 250: #endif
1.14 erh 251: }
252:
253: /* ...and the new sigaction conversion funcs. */
254: void
1.33 christos 255: linux_to_native_sigaction(bsa, lsa)
1.1 fvdl 256: struct sigaction *bsa;
1.33 christos 257: const struct linux_sigaction *lsa;
1.1 fvdl 258: {
1.39 christos 259: bsa->sa_handler = lsa->linux_sa_handler;
260: linux_to_native_sigset(&bsa->sa_mask, &lsa->linux_sa_mask);
261: bsa->sa_flags = linux_to_native_sigflags(lsa->linux_sa_flags);
1.1 fvdl 262: }
263:
264: void
1.33 christos 265: native_to_linux_sigaction(lsa, bsa)
1.1 fvdl 266: struct linux_sigaction *lsa;
1.33 christos 267: const struct sigaction *bsa;
1.1 fvdl 268: {
1.39 christos 269: lsa->linux_sa_handler = bsa->sa_handler;
270: native_to_linux_sigset(&lsa->linux_sa_mask, &bsa->sa_mask);
271: lsa->linux_sa_flags = native_to_linux_sigflags(bsa->sa_flags);
1.34 christos 272: #ifndef __alpha__
1.39 christos 273: lsa->linux_sa_restorer = NULL;
1.34 christos 274: #endif
1.1 fvdl 275: }
276:
1.14 erh 277: /* ----------------------------------------------------------------------- */
1.1 fvdl 278:
279: /*
280: * The Linux sigaction() system call. Do the usual conversions,
281: * and just call sigaction(). Some flags and values are silently
282: * ignored (see above).
283: */
284: int
1.52 christos 285: linux_sys_rt_sigaction(struct lwp *l, void *v, register_t *retval)
1.8 thorpej 286: {
1.14 erh 287: struct linux_sys_rt_sigaction_args /* {
1.1 fvdl 288: syscallarg(int) signum;
1.12 mycroft 289: syscallarg(const struct linux_sigaction *) nsa;
1.1 fvdl 290: syscallarg(struct linux_sigaction *) osa;
1.14 erh 291: syscallarg(size_t) sigsetsize;
1.8 thorpej 292: } */ *uap = v;
1.12 mycroft 293: struct linux_sigaction nlsa, olsa;
294: struct sigaction nbsa, obsa;
1.25 tron 295: int error, sig;
1.46 manu 296: void *tramp = NULL;
297: int vers = 0;
1.47 mrg 298: #if defined __amd64__
1.53 ad 299: struct sigacts *ps = l->l_proc->p_sigacts;
1.46 manu 300: #endif
1.1 fvdl 301:
1.14 erh 302: if (SCARG(uap, sigsetsize) != sizeof(linux_sigset_t))
303: return (EINVAL);
304:
1.12 mycroft 305: if (SCARG(uap, nsa)) {
306: error = copyin(SCARG(uap, nsa), &nlsa, sizeof(nlsa));
307: if (error)
308: return (error);
1.33 christos 309: linux_to_native_sigaction(&nbsa, &nlsa);
1.12 mycroft 310: }
1.46 manu 311:
1.25 tron 312: sig = SCARG(uap, signum);
313: if (sig < 0 || sig >= LINUX__NSIG)
314: return (EINVAL);
1.37 christos 315: if (sig > 0 && !linux_to_native_signo[sig]) {
1.29 tv 316: /* Pretend that we did something useful for unknown signals. */
317: obsa.sa_handler = SIG_IGN;
318: sigemptyset(&obsa.sa_mask);
319: obsa.sa_flags = 0;
320: } else {
1.46 manu 321: #if defined __amd64__
322: if (nlsa.linux_sa_flags & LINUX_SA_RESTORER) {
323: if ((tramp = nlsa.linux_sa_restorer) != NULL)
324: vers = 2; /* XXX arch dependant */
325: }
326: #endif
327:
1.53 ad 328: error = sigaction1(l, linux_to_native_signo[sig],
1.38 thorpej 329: SCARG(uap, nsa) ? &nbsa : NULL,
330: SCARG(uap, osa) ? &obsa : NULL,
1.46 manu 331: tramp, vers);
1.29 tv 332: if (error)
333: return (error);
334: }
1.12 mycroft 335: if (SCARG(uap, osa)) {
1.33 christos 336: native_to_linux_sigaction(&olsa, &obsa);
1.46 manu 337:
338: #if defined __amd64__
339: if (ps->sa_sigdesc[sig].sd_vers != 0) {
340: olsa.linux_sa_restorer = ps->sa_sigdesc[sig].sd_tramp;
341: olsa.linux_sa_flags |= LINUX_SA_RESTORER;
342: }
343: #endif
344:
1.12 mycroft 345: error = copyout(&olsa, SCARG(uap, osa), sizeof(olsa));
346: if (error)
347: return (error);
1.1 fvdl 348: }
1.12 mycroft 349: return (0);
1.1 fvdl 350: }
351:
352: int
1.53 ad 353: linux_sigprocmask1(l, how, set, oset)
354: struct lwp *l;
1.17 erh 355: int how;
356: const linux_old_sigset_t *set;
357: linux_old_sigset_t *oset;
1.8 thorpej 358: {
1.53 ad 359: struct proc *p = l->l_proc;
1.14 erh 360: linux_old_sigset_t nlss, olss;
1.12 mycroft 361: sigset_t nbss, obss;
362: int error;
1.1 fvdl 363:
1.17 erh 364: switch (how) {
1.1 fvdl 365: case LINUX_SIG_BLOCK:
1.12 mycroft 366: how = SIG_BLOCK;
1.1 fvdl 367: break;
368: case LINUX_SIG_UNBLOCK:
1.12 mycroft 369: how = SIG_UNBLOCK;
1.1 fvdl 370: break;
371: case LINUX_SIG_SETMASK:
1.12 mycroft 372: how = SIG_SETMASK;
1.1 fvdl 373: break;
374: default:
1.12 mycroft 375: return (EINVAL);
1.1 fvdl 376: }
377:
1.17 erh 378: if (set) {
379: error = copyin(set, &nlss, sizeof(nlss));
1.12 mycroft 380: if (error)
381: return (error);
1.33 christos 382: linux_old_to_native_sigset(&nbss, &nlss);
1.12 mycroft 383: }
1.53 ad 384: mutex_enter(&p->p_smutex);
385: error = sigprocmask1(l, how,
1.27 tron 386: set ? &nbss : NULL, oset ? &obss : NULL);
1.53 ad 387: mutex_exit(&p->p_smutex);
1.12 mycroft 388: if (error)
1.42 perry 389: return (error);
1.17 erh 390: if (oset) {
1.33 christos 391: native_to_linux_old_sigset(&olss, &obss);
1.17 erh 392: error = copyout(&olss, oset, sizeof(olss));
1.12 mycroft 393: if (error)
394: return (error);
1.42 perry 395: }
1.12 mycroft 396: return (error);
1.17 erh 397: }
398:
399: int
1.52 christos 400: linux_sys_rt_sigprocmask(struct lwp *l, void *v, register_t *retval)
1.17 erh 401: {
402: struct linux_sys_rt_sigprocmask_args /* {
403: syscallarg(int) how;
404: syscallarg(const linux_sigset_t *) set;
405: syscallarg(linux_sigset_t *) oset;
406: syscallarg(size_t) sigsetsize;
407: } */ *uap = v;
1.24 fvdl 408: linux_sigset_t nlss, olss, *oset;
409: const linux_sigset_t *set;
1.53 ad 410: struct proc *p = l->l_proc;
1.24 fvdl 411: sigset_t nbss, obss;
412: int error, how;
413:
414: if (SCARG(uap, sigsetsize) != sizeof(linux_sigset_t))
415: return (EINVAL);
416:
417: switch (SCARG(uap, how)) {
418: case LINUX_SIG_BLOCK:
419: how = SIG_BLOCK;
420: break;
421: case LINUX_SIG_UNBLOCK:
422: how = SIG_UNBLOCK;
423: break;
424: case LINUX_SIG_SETMASK:
425: how = SIG_SETMASK;
426: break;
427: default:
428: return (EINVAL);
1.17 erh 429: }
430:
1.24 fvdl 431: set = SCARG(uap, set);
432: oset = SCARG(uap, oset);
433:
434: if (set) {
435: error = copyin(set, &nlss, sizeof(nlss));
436: if (error)
437: return (error);
1.33 christos 438: linux_to_native_sigset(&nbss, &nlss);
1.24 fvdl 439: }
1.53 ad 440: mutex_enter(&p->p_smutex);
441: error = sigprocmask1(l, how,
1.27 tron 442: set ? &nbss : NULL, oset ? &obss : NULL);
1.53 ad 443: mutex_exit(&p->p_smutex);
1.28 tron 444: if (!error && oset) {
1.33 christos 445: native_to_linux_sigset(&olss, &obss);
1.24 fvdl 446: error = copyout(&olss, oset, sizeof(olss));
1.42 perry 447: }
1.24 fvdl 448: return (error);
1.1 fvdl 449: }
450:
451: int
1.52 christos 452: linux_sys_rt_sigpending(struct lwp *l, void *v, register_t *retval)
1.1 fvdl 453: {
1.14 erh 454: struct linux_sys_rt_sigpending_args /* {
455: syscallarg(linux_sigset_t *) set;
456: syscallarg(size_t) sigsetsize;
457: } */ *uap = v;
1.12 mycroft 458: sigset_t bss;
459: linux_sigset_t lss;
1.6 mycroft 460:
1.14 erh 461: if (SCARG(uap, sigsetsize) != sizeof(linux_sigset_t))
462: return (EINVAL);
463:
1.53 ad 464: sigpending1(l, &bss);
1.33 christos 465: native_to_linux_sigset(&lss, &bss);
1.14 erh 466: return copyout(&lss, SCARG(uap, set), sizeof(lss));
1.1 fvdl 467: }
1.24 fvdl 468:
1.43 manu 469: #ifndef __amd64__
1.1 fvdl 470: int
1.52 christos 471: linux_sys_sigpending(struct lwp *l, void *v, register_t *retval)
1.8 thorpej 472: {
1.9 mycroft 473: struct linux_sys_sigpending_args /* {
1.14 erh 474: syscallarg(linux_old_sigset_t *) mask;
1.8 thorpej 475: } */ *uap = v;
1.12 mycroft 476: sigset_t bss;
1.14 erh 477: linux_old_sigset_t lss;
1.1 fvdl 478:
1.53 ad 479: sigpending1(l, &bss);
1.33 christos 480: native_to_linux_old_sigset(&lss, &bss);
1.12 mycroft 481: return copyout(&lss, SCARG(uap, set), sizeof(lss));
1.1 fvdl 482: }
483:
484: int
1.52 christos 485: linux_sys_sigsuspend(struct lwp *l, void *v, register_t *retval)
1.8 thorpej 486: {
1.9 mycroft 487: struct linux_sys_sigsuspend_args /* {
1.54 christos 488: syscallarg(void *) restart;
1.3 fvdl 489: syscallarg(int) oldmask;
1.1 fvdl 490: syscallarg(int) mask;
1.8 thorpej 491: } */ *uap = v;
1.14 erh 492: linux_old_sigset_t lss;
493: sigset_t bss;
494:
495: lss = SCARG(uap, mask);
1.33 christos 496: linux_old_to_native_sigset(&bss, &lss);
1.53 ad 497: return (sigsuspend1(l, &bss));
1.14 erh 498: }
1.43 manu 499: #endif /* __amd64__ */
500:
1.14 erh 501: int
1.52 christos 502: linux_sys_rt_sigsuspend(struct lwp *l, void *v, register_t *retval)
1.14 erh 503: {
504: struct linux_sys_rt_sigsuspend_args /* {
505: syscallarg(linux_sigset_t *) unewset;
506: syscallarg(size_t) sigsetsize;
507: } */ *uap = v;
1.12 mycroft 508: linux_sigset_t lss;
509: sigset_t bss;
1.14 erh 510: int error;
511:
512: if (SCARG(uap, sigsetsize) != sizeof(linux_sigset_t))
513: return (EINVAL);
514:
515: error = copyin(SCARG(uap, unewset), &lss, sizeof(linux_sigset_t));
516: if (error)
517: return (error);
518:
1.33 christos 519: linux_to_native_sigset(&bss, &lss);
1.14 erh 520:
1.53 ad 521: return (sigsuspend1(l, &bss));
1.3 fvdl 522: }
523:
524: /*
1.14 erh 525: * Once more: only a signal conversion is needed.
526: * Note: also used as sys_rt_queueinfo. The info field is ignored.
1.3 fvdl 527: */
528: int
1.40 thorpej 529: linux_sys_rt_queueinfo(l, v, retval)
530: struct lwp *l;
1.14 erh 531: void *v;
1.3 fvdl 532: register_t *retval;
1.14 erh 533: {
534: /* XXX XAX This isn't this really int, int, siginfo_t *, is it? */
535: #if 0
536: struct linux_sys_rt_queueinfo_args /* {
537: syscallarg(int) pid;
538: syscallarg(int) signum;
539: syscallarg(siginfo_t *) uinfo;
540: } */ *uap = v;
541: #endif
1.3 fvdl 542:
1.14 erh 543: /* XXX To really implement this we need to */
544: /* XXX keep a list of queued signals somewhere. */
1.40 thorpej 545: return (linux_sys_kill(l, v, retval));
1.1 fvdl 546: }
547:
548: int
1.40 thorpej 549: linux_sys_kill(l, v, retval)
550: struct lwp *l;
1.8 thorpej 551: void *v;
552: register_t *retval;
553: {
1.9 mycroft 554: struct linux_sys_kill_args /* {
1.1 fvdl 555: syscallarg(int) pid;
556: syscallarg(int) signum;
1.8 thorpej 557: } */ *uap = v;
1.40 thorpej 558:
1.9 mycroft 559: struct sys_kill_args ka;
1.25 tron 560: int sig;
1.6 mycroft 561:
562: SCARG(&ka, pid) = SCARG(uap, pid);
1.25 tron 563: sig = SCARG(uap, signum);
564: if (sig < 0 || sig >= LINUX__NSIG)
565: return (EINVAL);
1.37 christos 566: SCARG(&ka, signum) = linux_to_native_signo[sig];
1.40 thorpej 567: return sys_kill(l, &ka, retval);
1.1 fvdl 568: }
1.30 christos 569:
570: #ifdef LINUX_SS_ONSTACK
571: static void linux_to_native_sigaltstack __P((struct sigaltstack *,
572: const struct linux_sigaltstack *));
573:
574: static void
575: linux_to_native_sigaltstack(bss, lss)
576: struct sigaltstack *bss;
577: const struct linux_sigaltstack *lss;
578: {
579: bss->ss_sp = lss->ss_sp;
580: bss->ss_size = lss->ss_size;
581: if (lss->ss_flags & LINUX_SS_ONSTACK)
582: bss->ss_flags = SS_ONSTACK;
583: else if (lss->ss_flags & LINUX_SS_DISABLE)
584: bss->ss_flags = SS_DISABLE;
585: else
586: bss->ss_flags = 0;
587: }
588:
1.41 christos 589: void
1.30 christos 590: native_to_linux_sigaltstack(lss, bss)
591: struct linux_sigaltstack *lss;
592: const struct sigaltstack *bss;
593: {
594: lss->ss_sp = bss->ss_sp;
595: lss->ss_size = bss->ss_size;
596: if (bss->ss_flags & SS_ONSTACK)
597: lss->ss_flags = LINUX_SS_ONSTACK;
598: else if (bss->ss_flags & SS_DISABLE)
599: lss->ss_flags = LINUX_SS_DISABLE;
600: else
601: lss->ss_flags = 0;
602: }
603:
604: int
1.52 christos 605: linux_sys_sigaltstack(struct lwp *l, void *v, register_t *retval)
1.30 christos 606: {
607: struct linux_sys_sigaltstack_args /* {
608: syscallarg(const struct linux_sigaltstack *) ss;
609: syscallarg(struct linux_sigaltstack *) oss;
610: } */ *uap = v;
611: struct linux_sigaltstack ss;
1.48 christos 612: struct sigaltstack nss;
1.53 ad 613: struct proc *p = l->l_proc;
614: int error = 0;
1.30 christos 615:
1.48 christos 616: if (SCARG(uap, oss)) {
1.53 ad 617: native_to_linux_sigaltstack(&ss, &l->l_sigstk);
1.48 christos 618: if ((error = copyout(&ss, SCARG(uap, oss), sizeof(ss))) != 0)
619: return error;
620: }
621:
1.30 christos 622: if (SCARG(uap, ss) != NULL) {
623: if ((error = copyin(SCARG(uap, ss), &ss, sizeof(ss))) != 0)
624: return error;
625: linux_to_native_sigaltstack(&nss, &ss);
626:
1.53 ad 627: mutex_enter(&p->p_smutex);
628:
1.48 christos 629: if (nss.ss_flags & ~SS_ALLBITS)
1.53 ad 630: error = EINVAL;
631: else if (nss.ss_flags & SS_DISABLE) {
632: if (l->l_sigstk.ss_flags & SS_ONSTACK)
633: error = EINVAL;
634: } else if (nss.ss_size < LINUX_MINSIGSTKSZ)
635: error = ENOMEM;
1.30 christos 636:
1.53 ad 637: if (error == 0)
638: l->l_sigstk = nss;
639:
640: mutex_exit(&p->p_smutex);
1.30 christos 641: }
1.48 christos 642:
1.53 ad 643: return error;
1.30 christos 644: }
1.44 jmc 645: #endif /* LINUX_SS_ONSTACK */
1.49 manu 646:
647: #ifdef LINUX_NPTL
648: int
649: linux_sys_tkill(l, v, retval)
650: struct lwp *l;
651: void *v;
652: register_t *retval;
653: {
654: struct linux_sys_tkill_args /* {
655: syscallarg(int) tid;
656: syscallarg(int) sig;
657: } */ *uap = v;
658: struct linux_sys_kill_args cup;
659:
660: /* We use the PID as the TID ... */
661: SCARG(&cup, pid) = SCARG(uap, tid);
662: SCARG(&cup, signum) = SCARG(uap, sig);
663:
664: return linux_sys_kill(l, &cup, retval);
665: }
666:
667: int
668: linux_sys_tgkill(l, v, retval)
669: struct lwp *l;
670: void *v;
671: register_t *retval;
672: {
673: struct linux_sys_tgkill_args /* {
674: syscallarg(int) tgid;
675: syscallarg(int) tid;
676: syscallarg(int) sig;
677: } */ *uap = v;
678: struct linux_sys_kill_args cup;
679: struct linux_emuldata *led;
680: struct proc *p;
681:
682: SCARG(&cup, pid) = SCARG(uap, tid);
683: SCARG(&cup, signum) = SCARG(uap, sig);
684:
685: if (SCARG(uap, tgid) == -1)
686: return linux_sys_kill(l, &cup, retval);
687:
688: /* We use the PID as the TID, but make sure the group ID is right */
689: if ((p = pfind(SCARG(uap, tid))) == NULL)
690: return ESRCH;
691:
692: if (p->p_emul != &emul_linux)
693: return ESRCH;
694:
695: led = p->p_emuldata;
696:
697: if (led->s->group_pid != SCARG(uap, tgid))
698: return ESRCH;
699:
700: return linux_sys_kill(l, &cup, retval);
701: }
702: #endif /* LINUX_NPTL */
CVSweb <webmaster@jp.NetBSD.org>