blob: d5f2336c2791e7da8703a848c25fabcb8f779498 [file] [log] [blame]
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001/*
2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * $Id$
30 */
31
32#include "defs.h"
33
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000034#include <signal.h>
35#include <sys/user.h>
36#include <fcntl.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000037
38#ifdef SVR4
39#include <sys/ucontext.h>
40#endif /* SVR4 */
41
Wichert Akkerman36915a11999-07-13 15:45:02 +000042#if defined(linux) && !defined(__GLIBC__)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000043#include <linux/ptrace.h>
Wichert Akkerman36915a11999-07-13 15:45:02 +000044#endif
45
46#ifdef HAVE_SYS_REG_H
47# include <sys/reg.h>
48# define PTRACE_PEEKUSR PTRACE_PEEKUSER
49# define PTRACE_POKEUSR PTRACE_POKEUSER
Wichert Akkerman2e2553a1999-05-09 00:29:58 +000050#endif
Wichert Akkerman36915a11999-07-13 15:45:02 +000051
52#ifdef LINUX
53
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000054#ifdef HAVE_ASM_SIGCONTEXT_H
55#include <asm/sigcontext.h>
56#ifdef SPARC
Wichert Akkerman9ce1a631999-08-29 23:15:07 +000057#include <asm/reg.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000058typedef struct {
Wichert Akkerman9ce1a631999-08-29 23:15:07 +000059 struct regs si_regs;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000060 int si_mask;
61} m_siginfo_t;
62#endif
63#else /* !HAVE_ASM_SIGCONTEXT_H */
64#ifdef I386
65struct sigcontext_struct {
66 unsigned short gs, __gsh;
67 unsigned short fs, __fsh;
68 unsigned short es, __esh;
69 unsigned short ds, __dsh;
70 unsigned long edi;
71 unsigned long esi;
72 unsigned long ebp;
73 unsigned long esp;
74 unsigned long ebx;
75 unsigned long edx;
76 unsigned long ecx;
77 unsigned long eax;
78 unsigned long trapno;
79 unsigned long err;
80 unsigned long eip;
81 unsigned short cs, __csh;
82 unsigned long eflags;
83 unsigned long esp_at_signal;
84 unsigned short ss, __ssh;
85 unsigned long i387;
86 unsigned long oldmask;
87 unsigned long cr2;
88};
89#else /* !I386 */
90#ifdef M68K
Wichert Akkerman2e2553a1999-05-09 00:29:58 +000091struct sigcontext
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000092{
93 unsigned long sc_mask;
94 unsigned long sc_usp;
95 unsigned long sc_d0;
96 unsigned long sc_d1;
97 unsigned long sc_a0;
98 unsigned long sc_a1;
99 unsigned short sc_sr;
100 unsigned long sc_pc;
101 unsigned short sc_formatvec;
102};
103#endif /* M68K */
104#endif /* !I386 */
105#endif /* !HAVE_ASM_SIGCONTEXT_H */
106#ifndef NSIG
107#define NSIG 32
108#endif
109#ifdef ARM
110#undef NSIG
111#define NSIG 32
112#endif
113#endif /* LINUX */
114
115char *signalent0[] = {
116#include "signalent.h"
117};
118int nsignals0 = sizeof signalent0 / sizeof signalent0[0];
119
120#if SUPPORTED_PERSONALITIES >= 2
121char *signalent1[] = {
122#include "signalent1.h"
123};
124int nsignals1 = sizeof signalent1 / sizeof signalent1[0];
125#endif /* SUPPORTED_PERSONALITIES >= 2 */
126
127#if SUPPORTED_PERSONALITIES >= 3
128char *signalent2[] = {
129#include "signalent2.h"
130};
131int nsignals2 = sizeof signalent2 / sizeof signalent2[0];
132#endif /* SUPPORTED_PERSONALITIES >= 3 */
133
134char **signalent;
135int nsignals;
136
137#ifdef SUNOS4
138
139static struct xlat sigvec_flags[] = {
140 { SV_ONSTACK, "SV_ONSTACK" },
141 { SV_INTERRUPT, "SV_INTERRUPT" },
142 { SV_RESETHAND, "SV_RESETHAND" },
143 { SA_NOCLDSTOP, "SA_NOCLDSTOP" },
144 { 0, NULL },
145};
146
147#endif /* SUNOS4 */
148
149#ifdef HAVE_SIGACTION
150
151static struct xlat sigact_flags[] = {
152#ifdef SA_STACK
153 { SA_STACK, "SA_STACK" },
154#endif
155#ifdef SA_RESTART
156 { SA_RESTART, "SA_RESTART" },
157#endif
158#ifdef SA_INTERRUPT
159 { SA_INTERRUPT, "SA_INTERRUPT" },
160#endif
161#ifdef SA_NOMASK
162 { SA_NOMASK, "SA_NOMASK" },
163#endif
164#ifdef SA_ONESHOT
165 { SA_ONESHOT, "SA_ONESHOT" },
166#endif
167#ifdef SA_SIGINFO
168 { SA_SIGINFO, "SA_SIGINFO" },
169#endif
170#ifdef SA_RESETHAND
171 { SA_RESETHAND, "SA_RESETHAND" },
172#endif
173#ifdef SA_ONSTACK
174 { SA_ONSTACK, "SA_ONSTACK" },
175#endif
176#ifdef SA_NODEFER
177 { SA_NODEFER, "SA_NODEFER" },
178#endif
179#ifdef SA_NOCLDSTOP
180 { SA_NOCLDSTOP, "SA_NOCLDSTOP" },
181#endif
182#ifdef SA_NOCLDWAIT
183 { SA_NOCLDWAIT, "SA_NOCLDWAIT" },
184#endif
185#ifdef _SA_BSDCALL
186 { _SA_BSDCALL, "_SA_BSDCALL" },
187#endif
188 { 0, NULL },
189};
190
191static struct xlat sigprocmaskcmds[] = {
192 { SIG_BLOCK, "SIG_BLOCK" },
193 { SIG_UNBLOCK, "SIG_UNBLOCK" },
194 { SIG_SETMASK, "SIG_SETMASK" },
195#ifdef SIG_SETMASK32
196 { SIG_SETMASK32,"SIG_SETMASK32" },
197#endif
198 { 0, NULL },
199};
200
201#endif /* HAVE_SIGACTION */
202
Nate Sammonsce780fc1999-03-29 23:23:13 +0000203/* Anonymous realtime signals. */
204/* Under glibc 2.1, SIGRTMIN et al are functions, but __SIGRTMIN is a
205 constant. This is what we want. Otherwise, just use SIGRTMIN. */
206#ifdef SIGRTMIN
207#ifndef __SIGRTMIN
208#define __SIGRTMIN SIGRTMIN
209#define __SIGRTMAX SIGRTMAX /* likewise */
210#endif
211#endif
212
213char *
214signame(sig)
215int sig;
216{
217 static char buf[30];
218 if (sig < nsignals) {
219 return signalent[sig];
220#ifdef SIGRTMIN
Nate Sammons3080aa41999-03-30 00:16:41 +0000221 } else if (sig >= __SIGRTMIN && sig <= __SIGRTMAX) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000222 sprintf(buf, "SIGRT_%ld", (long)(sig - __SIGRTMIN));
Nate Sammonsce780fc1999-03-29 23:23:13 +0000223 return buf;
224#endif /* SIGRTMIN */
225 } else {
226 sprintf(buf, "%d", sig);
227 return buf;
228 }
229}
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000230
Wichert Akkerman9ce1a631999-08-29 23:15:07 +0000231#ifndef UNIXWARE
Nate Sammons4a121431999-04-06 01:19:39 +0000232static void
233long_to_sigset(l, s)
234long l;
235sigset_t *s;
236{
237 sigemptyset(s);
238 *(long *)s = l;
239}
Wichert Akkerman9ce1a631999-08-29 23:15:07 +0000240#endif
Nate Sammons4a121431999-04-06 01:19:39 +0000241
242static int
243copy_sigset_len(tcp, addr, s, len)
244struct tcb *tcp;
245int addr;
246sigset_t *s;
247int len;
248{
249 if (len > sizeof(*s))
250 len = sizeof(*s);
251 sigemptyset(s);
252 if (umoven(tcp, addr, len, (char *)s) < 0)
253 return -1;
254 return 0;
255}
256
257#ifdef LINUX
258/* Original sigset is unsigned long */
259#define copy_sigset(tcp, addr, s) copy_sigset_len(tcp, addr, s, sizeof(long))
260#else
261#define copy_sigset(tcp, addr, s) copy_sigset_len(tcp, addr, s, sizeof(sigset_t))
262#endif
263
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000264static char *
Nate Sammons4a121431999-04-06 01:19:39 +0000265sprintsigmask(s, mask, rt)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000266char *s;
267sigset_t *mask;
Nate Sammons4a121431999-04-06 01:19:39 +0000268int rt; /* set might include realtime sigs */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000269{
270 int i, nsigs;
Nate Sammons4a121431999-04-06 01:19:39 +0000271 int maxsigs;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000272 char *format;
273 static char outstr[256];
274
275 strcpy(outstr, s);
276 s = outstr + strlen(outstr);
277 nsigs = 0;
Nate Sammons4a121431999-04-06 01:19:39 +0000278 maxsigs = nsignals;
279#ifdef __SIGRTMAX
280 if (rt)
281 maxsigs = __SIGRTMAX; /* instead */
282#endif
283 for (i = 1; i < maxsigs; i++) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000284 if (sigismember(mask, i) == 1)
285 nsigs++;
286 }
287 if (nsigs >= nsignals * 2 / 3) {
288 *s++ = '~';
Nate Sammons4a121431999-04-06 01:19:39 +0000289 for (i = 1; i < maxsigs; i++) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000290 switch (sigismember(mask, i)) {
291 case 1:
292 sigdelset(mask, i);
293 break;
294 case 0:
295 sigaddset(mask, i);
296 break;
297 }
298 }
299 }
300 format = "%s";
301 *s++ = '[';
Nate Sammons4a121431999-04-06 01:19:39 +0000302 for (i = 1; i < maxsigs; i++) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000303 if (sigismember(mask, i) == 1) {
Nate Sammonsce780fc1999-03-29 23:23:13 +0000304 sprintf(s, format, signame(i) + 3); s += strlen(s);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000305 format = " %s";
306 }
307 }
308 *s++ = ']';
309 *s = '\0';
310 return outstr;
311}
312
313static void
Nate Sammons4a121431999-04-06 01:19:39 +0000314printsigmask(mask, rt)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000315sigset_t *mask;
Nate Sammons4a121431999-04-06 01:19:39 +0000316int rt;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000317{
Nate Sammons4a121431999-04-06 01:19:39 +0000318 tprintf("%s", sprintsigmask("", mask, rt));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000319}
320
321void
322printsignal(nr)
323int nr;
324{
Nate Sammonsce780fc1999-03-29 23:23:13 +0000325 tprintf(signame(nr));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000326}
327
328/*
329 * Check process TCP for the disposition of signal SIG.
330 * Return 1 if the process would somehow manage to survive signal SIG,
331 * else return 0. This routine will never be called with SIGKILL.
332 */
333int
334sigishandled(tcp, sig)
335struct tcb *tcp;
336int sig;
337{
338#ifdef LINUX
339 int sfd;
340 char sname[32];
341 char buf[1024];
342 char *s;
343 int i;
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000344 unsigned int signalled, blocked, ignored, caught;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000345
346 /* This is incredibly costly but it's worth it. */
347 sprintf(sname, "/proc/%d/stat", tcp->pid);
348 if ((sfd = open(sname, O_RDONLY)) == -1) {
349 perror(sname);
350 return 1;
351 }
352 i = read(sfd, buf, 1024);
353 buf[i] = '\0';
354 close(sfd);
355 /*
356 * Skip the extraneous fields. This loses if the
357 * command name has any spaces in it. So be it.
358 */
359 for (i = 0, s = buf; i < 30; i++) {
360 while (*++s != ' ') {
361 if (!*s)
362 break;
363 }
364 }
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000365 if (sscanf(s, "%u%u%u%u",
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000366 &signalled, &blocked, &ignored, &caught) != 4) {
367 fprintf(stderr, "/proc/pid/stat format error\n");
368 return 1;
369 }
370#ifdef DEBUG
371 fprintf(stderr, "sigs: %08x %08x %08x %08x\n",
372 signalled, blocked, ignored, caught);
373#endif
374 if ((ignored & sigmask(sig)) || (caught & sigmask(sig)))
375 return 1;
376#endif /* LINUX */
377
378#ifdef SUNOS4
379 void (*u_signal)();
380
381 if (upeek(tcp->pid, uoff(u_signal[0]) + sig*sizeof(u_signal),
382 (long *) &u_signal) < 0) {
383 return 0;
384 }
385 if (u_signal != SIG_DFL)
386 return 1;
387#endif /* SUNOS4 */
388
389#ifdef SVR4
390 /*
391 * Since procfs doesn't interfere with wait I think it is safe
392 * to punt on this question. If not, the information is there.
393 */
394 return 1;
395#else /* !SVR4 */
396 switch (sig) {
397 case SIGCONT:
398 case SIGSTOP:
399 case SIGTSTP:
400 case SIGTTIN:
401 case SIGTTOU:
402 case SIGCHLD:
403 case SIGIO:
404#if defined(SIGURG) && SIGURG != SIGIO
405 case SIGURG:
406#endif
407 case SIGWINCH:
408 /* Gloria Gaynor says ... */
409 return 1;
410 default:
411 break;
412 }
413 return 0;
414#endif /* !SVR4 */
415}
416
417#if defined(SUNOS4)
418
419int
420sys_sigvec(tcp)
421struct tcb *tcp;
422{
423 struct sigvec sv;
424 long addr;
425
426 if (entering(tcp)) {
427 printsignal(tcp->u_arg[0]);
428 tprintf(", ");
429 addr = tcp->u_arg[1];
430 } else {
431 addr = tcp->u_arg[2];
432 }
433 if (addr == 0)
434 tprintf("NULL");
435 else if (!verbose(tcp))
436 tprintf("%#lx", addr);
437 else if (umove(tcp, addr, &sv) < 0)
438 tprintf("{...}");
439 else {
440 switch ((int) sv.sv_handler) {
441 case (int) SIG_ERR:
442 tprintf("{SIG_ERR}");
443 break;
444 case (int) SIG_DFL:
445 tprintf("{SIG_DFL}");
446 break;
447 case (int) SIG_IGN:
448 if (tcp->u_arg[0] == SIGTRAP) {
449 tcp->flags |= TCB_SIGTRAPPED;
450 kill(tcp->pid, SIGSTOP);
451 }
452 tprintf("{SIG_IGN}");
453 break;
454 case (int) SIG_HOLD:
455 if (tcp->u_arg[0] == SIGTRAP) {
456 tcp->flags |= TCB_SIGTRAPPED;
457 kill(tcp->pid, SIGSTOP);
458 }
459 tprintf("SIG_HOLD");
460 break;
461 default:
462 if (tcp->u_arg[0] == SIGTRAP) {
463 tcp->flags |= TCB_SIGTRAPPED;
464 kill(tcp->pid, SIGSTOP);
465 }
466 tprintf("{%#lx, ", (unsigned long) sv.sv_handler);
Nate Sammons4a121431999-04-06 01:19:39 +0000467 printsigmask(&sv.sv_mask, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000468 tprintf(", ");
469 if (!printflags(sigvec_flags, sv.sv_flags))
470 tprintf("0");
471 tprintf("}");
472 }
473 }
474 if (entering(tcp))
475 tprintf(", ");
476 return 0;
477}
478
479int
480sys_sigpause(tcp)
481struct tcb *tcp;
482{
483 if (entering(tcp)) { /* WTA: UD had a bug here: he forgot the braces */
Nate Sammons4a121431999-04-06 01:19:39 +0000484 sigset_t sigm;
485 long_to_sigset(tcp->u_arg[0], &sigm);
486 printsigmask(&sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000487 }
488 return 0;
489}
490
491int
492sys_sigstack(tcp)
493struct tcb *tcp;
494{
495 struct sigstack ss;
496 long addr;
497
498 if (entering(tcp))
499 addr = tcp->u_arg[0];
500 else
501 addr = tcp->u_arg[1];
502 if (addr == 0)
503 tprintf("NULL");
504 else if (umove(tcp, addr, &ss) < 0)
505 tprintf("%#lx", addr);
506 else {
507 tprintf("{ss_sp %#lx ", (unsigned long) ss.ss_sp);
508 tprintf("ss_onstack %s}", ss.ss_onstack ? "YES" : "NO");
509 }
510 if (entering(tcp))
511 tprintf(", ");
512 return 0;
513}
514
515int
516sys_sigcleanup(tcp)
517struct tcb *tcp;
518{
519 return 0;
520}
521
522#endif /* SUNOS4 */
523
524#ifndef SVR4
525
526int
527sys_sigsetmask(tcp)
528struct tcb *tcp;
529{
530 if (entering(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000531 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000532 long_to_sigset(tcp->u_arg[0], &sigm);
533 printsigmask(&sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000534 if ((tcp->u_arg[0] & sigmask(SIGTRAP))) {
535 /* Mark attempt to block SIGTRAP */
536 tcp->flags |= TCB_SIGTRAPPED;
537 /* Send unblockable signal */
538 kill(tcp->pid, SIGSTOP);
539 }
540 }
541 else if (!syserror(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000542 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000543 long_to_sigset(tcp->u_rval, &sigm);
544 tcp->auxstr = sprintsigmask("old mask ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000545
546 return RVAL_HEX | RVAL_STR;
547 }
548 return 0;
549}
550
551int
552sys_sigblock(tcp)
553struct tcb *tcp;
554{
555 return sys_sigsetmask(tcp);
556}
557
558#endif /* !SVR4 */
559
560#ifdef HAVE_SIGACTION
561
562#ifdef LINUX
563struct old_sigaction {
564 __sighandler_t __sa_handler;
565 unsigned long sa_mask;
566 unsigned long sa_flags;
567 void (*sa_restorer)(void);
568};
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000569#define SA_HANDLER __sa_handler
570#endif /* LINUX */
571
572#ifndef SA_HANDLER
573#define SA_HANDLER sa_handler
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000574#endif
575
576int
577sys_sigaction(tcp)
578struct tcb *tcp;
579{
580 long addr;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000581 sigset_t sigset;
Nate Sammons4a121431999-04-06 01:19:39 +0000582#ifdef LINUX
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000583 struct old_sigaction sa;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000584#else
585 struct sigaction sa;
586#endif
587
588
589 if (entering(tcp)) {
590 printsignal(tcp->u_arg[0]);
591 tprintf(", ");
592 addr = tcp->u_arg[1];
593 } else
594 addr = tcp->u_arg[2];
595 if (addr == 0)
596 tprintf("NULL");
597 else if (!verbose(tcp))
598 tprintf("%#lx", addr);
599 else if (umove(tcp, addr, &sa) < 0)
600 tprintf("{...}");
601 else {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000602 switch ((long) sa.SA_HANDLER) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000603 case (long) SIG_ERR:
604 tprintf("{SIG_ERR}");
605 break;
606 case (long) SIG_DFL:
607 tprintf("{SIG_DFL}");
608 break;
609 case (long) SIG_IGN:
610#ifndef SVR4
611 if (tcp->u_arg[0] == SIGTRAP) {
612 tcp->flags |= TCB_SIGTRAPPED;
613 kill(tcp->pid, SIGSTOP);
614 }
615#endif /* !SVR4 */
616 tprintf("{SIG_IGN}");
617 break;
618 default:
619#ifndef SVR4
620 if (tcp->u_arg[0] == SIGTRAP) {
621 tcp->flags |= TCB_SIGTRAPPED;
622 kill(tcp->pid, SIGSTOP);
623 }
624#endif /* !SVR4 */
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000625 tprintf("{%#lx, ", (long) sa.SA_HANDLER);
Nate Sammons4a121431999-04-06 01:19:39 +0000626 long_to_sigset(sa.sa_mask, &sigset);
627 printsigmask(&sigset, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000628 tprintf(", ");
629 if (!printflags(sigact_flags, sa.sa_flags))
630 tprintf("0");
631 tprintf("}");
632 }
633 }
634 if (entering(tcp))
635 tprintf(", ");
636#ifdef LINUX
637 else
638 tprintf(", %#lx", (unsigned long) sa.sa_restorer);
639#endif
640 return 0;
641}
642
643int
644sys_signal(tcp)
645struct tcb *tcp;
646{
647 if (entering(tcp)) {
648 printsignal(tcp->u_arg[0]);
649 switch (tcp->u_arg[1]) {
650 case (int) SIG_ERR:
651 tprintf("SIG_ERR");
652 break;
653 case (int) SIG_DFL:
654 tprintf("SIG_DFL");
655 break;
656 case (int) SIG_IGN:
657#ifndef SVR4
658 if (tcp->u_arg[0] == SIGTRAP) {
659 tcp->flags |= TCB_SIGTRAPPED;
660 kill(tcp->pid, SIGSTOP);
661 }
662#endif /* !SVR4 */
663 tprintf("SIG_IGN");
664 break;
665 default:
666#ifndef SVR4
667 if (tcp->u_arg[0] == SIGTRAP) {
668 tcp->flags |= TCB_SIGTRAPPED;
669 kill(tcp->pid, SIGSTOP);
670 }
671#endif /* !SVR4 */
672 tprintf("%#lx", tcp->u_arg[1]);
673 }
674 }
675 return 0;
676}
677
678#endif /* HAVE_SIGACTION */
679
680#ifdef LINUX
681
682int
683sys_sigreturn(tcp)
684struct tcb *tcp;
685{
686#ifdef I386
687 long esp;
688 struct sigcontext_struct sc;
689
690 if (entering(tcp)) {
691 tcp->u_arg[0] = 0;
692 if (upeek(tcp->pid, 4*UESP, &esp) < 0)
693 return 0;
694 if (umove(tcp, esp, &sc) < 0)
695 return 0;
696 tcp->u_arg[0] = 1;
697 tcp->u_arg[1] = sc.oldmask;
698 }
699 else {
700 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000701 long_to_sigset(tcp->u_arg[1], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000702 tcp->u_rval = tcp->u_error = 0;
703 if (tcp->u_arg[0] == 0)
704 return 0;
Nate Sammons4a121431999-04-06 01:19:39 +0000705 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000706 return RVAL_NONE | RVAL_STR;
707 }
708 return 0;
709#else /* !I386 */
710#ifdef POWERPC
711 long esp;
712 struct sigcontext_struct sc;
713
714 if (entering(tcp)) {
715 tcp->u_arg[0] = 0;
716 if (upeek(tcp->pid, 4*PT_R1, &esp) < 0)
717 return 0;
718 if (umove(tcp, esp, &sc) < 0)
719 return 0;
720 tcp->u_arg[0] = 1;
721 tcp->u_arg[1] = sc.oldmask;
722 }
723 else {
724 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000725 long_to_sigset(tcp->u_arg[1], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000726 tcp->u_rval = tcp->u_error = 0;
727 if (tcp->u_arg[0] == 0)
728 return 0;
Nate Sammons4a121431999-04-06 01:19:39 +0000729 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000730 return RVAL_NONE | RVAL_STR;
731 }
732 return 0;
733#else /* !POWERPC */
734#ifdef M68K
735 long usp;
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000736 struct sigcontext sc;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000737
738 if (entering(tcp)) {
739 tcp->u_arg[0] = 0;
740 if (upeek(tcp->pid, 4*PT_USP, &usp) < 0)
741 return 0;
742 if (umove(tcp, usp, &sc) < 0)
743 return 0;
744 tcp->u_arg[0] = 1;
745 tcp->u_arg[1] = sc.sc_mask;
746 }
747 else {
748 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000749 long_to_sigset(tcp->u_arg[1], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000750 tcp->u_rval = tcp->u_error = 0;
751 if (tcp->u_arg[0] == 0)
752 return 0;
Nate Sammons4a121431999-04-06 01:19:39 +0000753 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000754 return RVAL_NONE | RVAL_STR;
755 }
756 return 0;
757#else /* !M68K */
758#ifdef ALPHA
759 long fp;
760 struct sigcontext_struct sc;
761
762 if (entering(tcp)) {
763 tcp->u_arg[0] = 0;
764 if (upeek(tcp->pid, REG_FP, &fp) < 0)
765 return 0;
766 if (umove(tcp, fp, &sc) < 0)
767 return 0;
768 tcp->u_arg[0] = 1;
769 tcp->u_arg[1] = sc.sc_mask;
770 }
771 else {
772 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000773 long_to_sigset(tcp->u_arg[1], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000774 tcp->u_rval = tcp->u_error = 0;
775 if (tcp->u_arg[0] == 0)
776 return 0;
Nate Sammons4a121431999-04-06 01:19:39 +0000777 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000778 return RVAL_NONE | RVAL_STR;
779 }
780 return 0;
781#else
782#ifdef SPARC
783 long i1;
Wichert Akkerman9ce1a631999-08-29 23:15:07 +0000784 struct regs regs;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000785 m_siginfo_t si;
786
787 if(ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
788 perror("sigreturn: PTRACE_GETREGS ");
789 return 0;
790 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000791 if(entering(tcp)) {
792 tcp->u_arg[0] = 0;
Wichert Akkerman9ce1a631999-08-29 23:15:07 +0000793 i1 = regs.r_o1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000794 if(umove(tcp, i1, &si) < 0) {
795 perror("sigreturn: umove ");
796 return 0;
797 }
798 tcp->u_arg[0] = 1;
799 tcp->u_arg[1] = si.si_mask;
800 } else {
801 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000802 long_to_sigset(tcp->u_arg[1], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000803 tcp->u_rval = tcp->u_error = 0;
804 if(tcp->u_arg[0] == 0)
805 return 0;
Nate Sammons4a121431999-04-06 01:19:39 +0000806 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000807 return RVAL_NONE | RVAL_STR;
808 }
809 return 0;
810#endif /* SPARC */
811#endif /* ALPHA */
812#endif /* !M68K */
813#endif /* !POWERPC */
814#endif /* !I386 */
815}
816
817int
818sys_siggetmask(tcp)
819struct tcb *tcp;
820{
821 if (exiting(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000822 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000823 long_to_sigset(tcp->u_rval, &sigm);
824 tcp->auxstr = sprintsigmask("mask ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000825 }
826 return RVAL_HEX | RVAL_STR;
827}
828
829int
830sys_sigsuspend(tcp)
831struct tcb *tcp;
832{
833 if (entering(tcp)) {
834 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000835 long_to_sigset(tcp->u_arg[2], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000836#if 0
837 /* first two are not really arguments, but print them anyway */
838 /* nevermind, they are an anachronism now, too bad... */
839 tprintf("%d, %#x, ", tcp->u_arg[0], tcp->u_arg[1]);
840#endif
Nate Sammons4a121431999-04-06 01:19:39 +0000841 printsigmask(&sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000842 }
843 return 0;
844}
845
846#endif /* LINUX */
847
848#ifdef SVR4
849
850int
851sys_sigsuspend(tcp)
852struct tcb *tcp;
853{
854 sigset_t sigset;
855
856 if (entering(tcp)) {
857 if (umove(tcp, tcp->u_arg[0], &sigset) < 0)
858 tprintf("[?]");
859 else
Nate Sammons4a121431999-04-06 01:19:39 +0000860 printsigmask(sigset, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000861 }
862 return 0;
863}
864static struct xlat ucontext_flags[] = {
865 { UC_SIGMASK, "UC_SIGMASK" },
866 { UC_STACK, "UC_STACK" },
867 { UC_CPU, "UC_CPU" },
868#ifdef UC_FPU
869 { UC_FPU, "UC_FPU" },
870#endif
871#ifdef UC_INTR
872 { UC_INTR, "UC_INTR" },
873#endif
874 { 0, NULL },
875};
876
877#endif
878
879#if defined SVR4 || defined LINUX
880#if defined LINUX && !defined SS_ONSTACK
881#define SS_ONSTACK 1
882#define SS_DISABLE 2
883#if __GLIBC_MINOR__ == 0
884typedef struct
885{
886 __ptr_t ss_sp;
887 int ss_flags;
888 size_t ss_size;
889} stack_t;
890#endif
891#endif
892
893static struct xlat sigaltstack_flags[] = {
894 { SS_ONSTACK, "SS_ONSTACK" },
895 { SS_DISABLE, "SS_DISABLE" },
896 { 0, NULL },
897};
898#endif
899
900#ifdef SVR4
901static void
902printcontext(tcp, ucp)
903struct tcb *tcp;
904ucontext_t *ucp;
905{
906 tprintf("{");
907 if (!abbrev(tcp)) {
908 tprintf("uc_flags=");
909 if (!printflags(ucontext_flags, ucp->uc_flags))
910 tprintf("0");
911 tprintf(", uc_link=%#lx, ", (unsigned long) ucp->uc_link);
912 }
913 tprintf("uc_sigmask=");
Nate Sammons4a121431999-04-06 01:19:39 +0000914 printsigmask(ucp->uc_sigmask, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000915 if (!abbrev(tcp)) {
916 tprintf(", uc_stack={ss_sp=%#lx, ss_size=%d, ss_flags=",
917 (unsigned long) ucp->uc_stack.ss_sp,
918 ucp->uc_stack.ss_size);
919 if (!printflags(sigaltstack_flags, ucp->uc_stack.ss_flags))
920 tprintf("0");
921 tprintf("}");
922 }
923 tprintf(", ...}");
924}
925
926int
927sys_getcontext(tcp)
928struct tcb *tcp;
929{
930 ucontext_t uc;
931
932 if (entering(tcp)) {
933 if (!tcp->u_arg[0])
934 tprintf("NULL");
935 else if (umove(tcp, tcp->u_arg[0], &uc) < 0)
936 tprintf("{...}");
937 else
938 printcontext(tcp, &uc);
939 }
940 return 0;
941}
942
943int
944sys_setcontext(tcp)
945struct tcb *tcp;
946{
947 ucontext_t uc;
948
949 if (entering(tcp)) {
950 if (!tcp->u_arg[0])
951 tprintf("NULL");
952 else if (umove(tcp, tcp->u_arg[0], &uc) < 0)
953 tprintf("{...}");
954 else
955 printcontext(tcp, &uc);
956 }
957 else {
958 tcp->u_rval = tcp->u_error = 0;
959 if (tcp->u_arg[0] == 0)
960 return 0;
961 return RVAL_NONE;
962 }
963 return 0;
964}
965
966#endif /* SVR4 */
967
968#ifdef LINUX
969
970static int
971print_stack_t(tcp, addr)
972struct tcb *tcp;
973unsigned long addr;
974{
975 stack_t ss;
976 if (umove(tcp, addr, &ss) < 0)
977 return -1;
978 tprintf("{ss_sp=%#lx, ss_flags=", (unsigned long) ss.ss_sp);
979 if (!printflags(sigaltstack_flags, ss.ss_flags))
980 tprintf("0");
981 tprintf(", ss_size=%lu}", (unsigned long) ss.ss_size);
982 return 0;
983}
984
985int
986sys_sigaltstack(tcp)
987 struct tcb *tcp;
988{
989 if (entering(tcp)) {
990 if (tcp->u_arg[0] == 0)
991 tprintf("NULL");
992 else if (print_stack_t(tcp, tcp->u_arg[0]) < 0)
993 return -1;
994 }
995 else {
996 tprintf(", ");
997 if (tcp->u_arg[1] == 0)
998 tprintf("NULL");
999 else if (print_stack_t(tcp, tcp->u_arg[1]) < 0)
1000 return -1;
1001 }
1002 return 0;
1003}
1004#endif
1005
1006#ifdef HAVE_SIGACTION
1007
1008int
1009sys_sigprocmask(tcp)
1010struct tcb *tcp;
1011{
1012#ifdef ALPHA
1013 if (entering(tcp)) {
1014 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1015 tprintf(", ");
Nate Sammons4a121431999-04-06 01:19:39 +00001016 printsigmask(tcp->u_arg[1], 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001017 }
1018 else if (!syserror(tcp)) {
Nate Sammons4a121431999-04-06 01:19:39 +00001019 tcp->auxstr = sprintsigmask("old mask ", tcp->u_rval, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001020 return RVAL_HEX | RVAL_STR;
1021 }
1022#else /* !ALPHA */
1023 sigset_t sigset;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001024
1025 if (entering(tcp)) {
1026#ifdef SVR4
1027 if (tcp->u_arg[0] == 0)
1028 tprintf("0");
1029 else
1030#endif /* SVR4 */
1031 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1032 tprintf(", ");
1033 if (!tcp->u_arg[1])
1034 tprintf("NULL, ");
Nate Sammons4a121431999-04-06 01:19:39 +00001035 else if (copy_sigset(tcp, tcp->u_arg[1], &sigset) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001036 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001037 else {
Nate Sammons4a121431999-04-06 01:19:39 +00001038 printsigmask(&sigset, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001039 tprintf(", ");
1040 }
1041 }
1042 else {
1043 if (!tcp->u_arg[2])
1044 tprintf("NULL");
1045 else if (syserror(tcp))
1046 tprintf("%#lx", tcp->u_arg[2]);
Nate Sammons4a121431999-04-06 01:19:39 +00001047 else if (copy_sigset(tcp, tcp->u_arg[2], &sigset) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001048 tprintf("[?]");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001049 else
Nate Sammons4a121431999-04-06 01:19:39 +00001050 printsigmask(&sigset, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001051 }
1052#endif /* !ALPHA */
1053 return 0;
1054}
1055
1056#endif /* HAVE_SIGACTION */
1057
1058int
1059sys_kill(tcp)
1060struct tcb *tcp;
1061{
1062 if (entering(tcp)) {
Nate Sammonsce780fc1999-03-29 23:23:13 +00001063 tprintf("%ld, %s", tcp->u_arg[0], signame(tcp->u_arg[1]));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001064 }
1065 return 0;
1066}
1067
1068int
1069sys_killpg(tcp)
1070struct tcb *tcp;
1071{
1072 return sys_kill(tcp);
1073}
1074
1075int
1076sys_sigpending(tcp)
1077struct tcb *tcp;
1078{
1079 sigset_t sigset;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001080
1081 if (exiting(tcp)) {
1082 if (syserror(tcp))
1083 tprintf("%#lx", tcp->u_arg[0]);
Nate Sammons4a121431999-04-06 01:19:39 +00001084 else if (copy_sigset(tcp, tcp->u_arg[0], &sigset) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001085 tprintf("[?]");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001086 else
Nate Sammons4a121431999-04-06 01:19:39 +00001087 printsigmask(sigset, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001088 }
1089 return 0;
1090}
1091
1092#ifdef LINUX
1093
1094 int
1095sys_rt_sigprocmask(tcp)
1096 struct tcb *tcp;
1097{
1098 sigset_t sigset;
1099
Nate Sammons4a121431999-04-06 01:19:39 +00001100 /* Note: arg[3] is the length of the sigset. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001101 if (entering(tcp)) {
1102 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1103 tprintf(", ");
1104 if (!tcp->u_arg[1])
1105 tprintf("NULL, ");
Nate Sammons4a121431999-04-06 01:19:39 +00001106 else if (copy_sigset_len(tcp, tcp->u_arg[1], &sigset, tcp->u_arg[3]) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001107 tprintf("%#lx, ", tcp->u_arg[1]);
1108 else {
Nate Sammons4a121431999-04-06 01:19:39 +00001109 printsigmask(&sigset, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001110 tprintf(", ");
1111 }
1112 }
1113 else {
1114 if (!tcp->u_arg[2])
1115
1116 tprintf("NULL");
1117 else if (syserror(tcp))
1118 tprintf("%#lx", tcp->u_arg[2]);
Nate Sammons4a121431999-04-06 01:19:39 +00001119 else if (copy_sigset_len(tcp, tcp->u_arg[2], &sigset, tcp->u_arg[3]) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001120 tprintf("[?]");
1121 else
Nate Sammons4a121431999-04-06 01:19:39 +00001122 printsigmask(&sigset, 1);
Nate Sammonsdab325a1999-03-29 23:33:35 +00001123 tprintf(", %lu", tcp->u_arg[3]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001124 }
1125 return 0;
1126}
1127
1128#if __GLIBC_MINOR__ < 1
1129/* Type for data associated with a signal. */
1130typedef union sigval
1131{
1132 int sival_int;
1133 void *sival_ptr;
1134} sigval_t;
1135
1136# define __SI_MAX_SIZE 128
1137# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 3)
1138
1139typedef struct siginfo
1140{
1141 int si_signo; /* Signal number. */
1142 int si_errno; /* If non-zero, an errno value associated with
1143 this signal, as defined in <errno.h>. */
1144 int si_code; /* Signal code. */
1145
1146 union
1147 {
1148 int _pad[__SI_PAD_SIZE];
1149
1150 /* kill(). */
1151 struct
1152 {
1153 __pid_t si_pid; /* Sending process ID. */
1154 __uid_t si_uid; /* Real user ID of sending process. */
1155 } _kill;
1156
1157 /* POSIX.1b timers. */
1158 struct
1159 {
1160 unsigned int _timer1;
1161 unsigned int _timer2;
1162 } _timer;
1163
1164 /* POSIX.1b signals. */
1165 struct
1166 {
1167 __pid_t si_pid; /* Sending process ID. */
1168 __uid_t si_uid; /* Real user ID of sending process. */
1169 sigval_t si_sigval; /* Signal value. */
1170 } _rt;
1171
1172 /* SIGCHLD. */
1173 struct
1174 {
1175 __pid_t si_pid; /* Which child. */
1176 int si_status; /* Exit value or signal. */
1177 __clock_t si_utime;
1178 __clock_t si_stime;
1179 } _sigchld;
1180
1181 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS. */
1182 struct
1183 {
1184 void *si_addr; /* Faulting insn/memory ref. */
1185 } _sigfault;
1186
1187 /* SIGPOLL. */
1188 struct
1189 {
1190 int si_band; /* Band event for SIGPOLL. */
1191 int si_fd;
1192 } _sigpoll;
1193 } _sifields;
1194} siginfo_t;
1195#endif
1196
1197/* Structure describing the action to be taken when a signal arrives. */
1198struct new_sigaction
1199{
1200 union
1201 {
1202 __sighandler_t __sa_handler;
1203 void (*__sa_sigaction) (int, siginfo_t *, void *);
1204 }
1205 __sigaction_handler;
1206 unsigned long sa_flags;
1207 void (*sa_restorer) (void);
1208 unsigned long int sa_mask[2];
1209};
1210
1211
1212 int
1213sys_rt_sigaction(tcp)
1214 struct tcb *tcp;
1215{
1216 struct new_sigaction sa;
1217 sigset_t sigset;
1218 long addr;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001219
1220 if (entering(tcp)) {
1221 printsignal(tcp->u_arg[0]);
1222 tprintf(", ");
1223 addr = tcp->u_arg[1];
1224 } else
1225 addr = tcp->u_arg[2];
1226 if (addr == 0)
1227 tprintf("NULL");
1228 else if (!verbose(tcp))
1229 tprintf("%#lx", addr);
1230 else if (umove(tcp, addr, &sa) < 0)
1231 tprintf("{...}");
1232 else {
1233 switch ((long) sa.__sigaction_handler.__sa_handler) {
1234 case (long) SIG_ERR:
1235 tprintf("{SIG_ERR}");
1236 break;
1237 case (long) SIG_DFL:
1238 tprintf("{SIG_DFL}");
1239 break;
1240 case (long) SIG_IGN:
1241 tprintf("{SIG_IGN}");
1242 break;
1243 default:
1244 tprintf("{%#lx, ",
1245 (long) sa.__sigaction_handler.__sa_handler);
Nate Sammons4a121431999-04-06 01:19:39 +00001246 sigemptyset(&sigset);
Wichert Akkermandacfb6e1999-06-03 14:21:07 +00001247#ifdef LINUXSPARC
1248 if (tcp->u_arg[4] <= sizeof(sigset))
1249 memcpy(&sigset, &sa.sa_mask, tcp->u_arg[4]);
1250#else
Nate Sammons4a121431999-04-06 01:19:39 +00001251 if (tcp->u_arg[3] <= sizeof(sigset))
1252 memcpy(&sigset, &sa.sa_mask, tcp->u_arg[3]);
Wichert Akkermandacfb6e1999-06-03 14:21:07 +00001253#endif
Nate Sammons4a121431999-04-06 01:19:39 +00001254 else
1255 memcpy(&sigset, &sa.sa_mask, sizeof(sigset));
1256 printsigmask(&sigset, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001257 tprintf(", ");
1258 if (!printflags(sigact_flags, sa.sa_flags))
1259 tprintf("0");
1260 tprintf("}");
1261 }
1262 }
1263 if (entering(tcp))
1264 tprintf(", ");
1265 else
Wichert Akkermandacfb6e1999-06-03 14:21:07 +00001266#ifdef LINUXSPARC
1267 tprintf(", %#lx, %lu", tcp->u_arg[3], tcp->u_arg[4]);
1268#elif defined(ALPHA)
1269 tprintf(", %lu, %#lx", tcp->u_arg[3], tcp->u_arg[4]);
1270#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001271 tprintf(", %lu", addr = tcp->u_arg[3]);
Wichert Akkermandacfb6e1999-06-03 14:21:07 +00001272#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001273 return 0;
1274}
1275
1276 int
1277sys_rt_sigpending(tcp)
1278 struct tcb *tcp;
1279{
1280 sigset_t sigset;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001281
1282 if (exiting(tcp)) {
1283 if (syserror(tcp))
1284 tprintf("%#lx", tcp->u_arg[0]);
Nate Sammons4a121431999-04-06 01:19:39 +00001285 else if (copy_sigset_len(tcp, tcp->u_arg[0],
1286 &sigset, tcp->u_arg[1]) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001287 tprintf("[?]");
1288 else
Nate Sammons4a121431999-04-06 01:19:39 +00001289 printsigmask(sigset, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001290 }
1291 return 0;
1292}
1293 int
1294sys_rt_sigsuspend(tcp)
1295 struct tcb *tcp;
1296{
1297 if (entering(tcp)) {
1298 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +00001299 if (copy_sigset_len(tcp, tcp->u_arg[0], &sigm, tcp->u_arg[1]) < 0)
1300 tprintf("[?]");
1301 else
1302 printsigmask(&sigm, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001303 }
1304 return 0;
1305}
1306#ifndef ILL_ILLOPC
1307#define ILL_ILLOPC 1 /* illegal opcode */
1308#define ILL_ILLOPN 2 /* illegal operand */
1309#define ILL_ILLADR 3 /* illegal addressing mode */
1310#define ILL_ILLTRP 4 /* illegal trap */
1311#define ILL_PRVOPC 5 /* privileged opcode */
1312#define ILL_PRVREG 6 /* privileged register */
1313#define ILL_COPROC 7 /* coprocessor error */
1314#define ILL_BADSTK 8 /* internal stack error */
1315#define FPE_INTDIV 1 /* integer divide by zero */
1316#define FPE_INTOVF 2 /* integer overflow */
1317#define FPE_FLTDIV 3 /* floating point divide by zero */
1318#define FPE_FLTOVF 4 /* floating point overflow */
1319#define FPE_FLTUND 5 /* floating point underflow */
1320#define FPE_FLTRES 6 /* floating point inexact result */
1321#define FPE_FLTINV 7 /* floating point invalid operation */
1322#define FPE_FLTSUB 8 /* subscript out of range */
1323#define SEGV_MAPERR 1 /* address not mapped to object */
1324#define SEGV_ACCERR 2 /* invalid permissions for mapped object */
1325#define BUS_ADRALN 1 /* invalid address alignment */
1326#define BUS_ADRERR 2 /* non-existant physical address */
1327#define BUS_OBJERR 3 /* object specific hardware error */
1328#define TRAP_BRKPT 1 /* process breakpoint */
1329#define TRAP_TRACE 2 /* process trace trap */
1330#define CLD_EXITED 1 /* child has exited */
1331#define CLD_KILLED 2 /* child was killed */
1332#define CLD_DUMPED 3 /* child terminated abnormally */
1333#define CLD_TRAPPED 4 /* traced child has trapped */
1334#define CLD_STOPPED 5 /* child has stopped */
1335#define CLD_CONTINUED 6 /* stopped child has continued */
1336#define POLL_IN 1 /* data input available */
1337#define POLL_OUT 2 /* output buffers available */
1338#define POLL_MSG 3 /* input message available */
1339#define POLL_ERR 4 /* i/o error */
1340#define POLL_PRI 5 /* high priority input available */
1341#define POLL_HUP 6 /* device disconnected */
1342#define SI_USER 0 /* sent by kill, sigsend, raise */
1343#define SI_QUEUE -1 /* sent by sigqueue */
1344#define SI_TIMER -2 /* sent by timer expiration */
1345#define SI_MESGQ -3 /* sent by real time mesq state change */
1346#define SI_ASYNCIO -4 /* sent by AIO completion */
1347#else
1348#undef si_pid
1349#undef si_uid
1350#undef si_status
1351#undef si_utime
1352#undef si_stime
1353#undef si_value
1354#undef si_int
1355#undef si_ptr
1356#undef si_addr
1357#undef si_band
1358#undef si_fd
1359#endif
1360
1361static struct xlat sigill_flags[] = {
1362 {ILL_ILLOPC, "ILL_ILLOPC"},
1363 {ILL_ILLOPN, "ILL_ILLOPN"},
1364 {ILL_ILLADR, "ILL_ILLADR"},
1365 {ILL_ILLTRP, "ILL_ILLTRP"},
1366 {ILL_PRVOPC, "ILL_PRVOPC"},
1367 {ILL_PRVREG, "ILL_PRVREG"},
1368 {ILL_COPROC, "ILL_COPROC"},
1369 {ILL_BADSTK, "ILL_BADSTK"},
1370 {0, NULL}
1371};
1372
1373static struct xlat sigfpe_flags[] = {
1374 {FPE_INTDIV, "FPE_INTDIV"},
1375 {FPE_INTOVF, "FPE_INTOVF"},
1376 {FPE_FLTDIV, "FPE_FLTDIV"},
1377 {FPE_FLTOVF, "FPE_FLTOVF"},
1378 {FPE_FLTUND, "FPE_FLTUND"},
1379 {FPE_FLTRES, "FPE_FLTRES"},
1380 {FPE_FLTINV, "FPE_FLTINV"},
1381 {FPE_FLTSUB, "FPE_FLTSUB"},
1382 {0, NULL}
1383};
1384
1385static struct xlat sigsegv_flags[] = {
1386 {SEGV_MAPERR, "SEGV_MAPERR"},
1387 {SEGV_ACCERR, "SEGV_ACCERR"},
1388 {0, NULL}
1389};
1390
1391static struct xlat sigbus_flags[] = {
1392 {BUS_ADRALN, "BUS_ADRALN"},
1393 {BUS_ADRERR, "BUS_ADRERR"},
1394 {BUS_OBJERR, "BUS_OBJERR"},
1395 {0, NULL}
1396};
1397
1398static struct xlat sigtrap_flags[] = {
1399 {TRAP_BRKPT, "TRAP_BRKPT"},
1400 {TRAP_TRACE, "TRAP_TRACE"},
1401 {0, NULL}
1402};
1403
1404static struct xlat sigchld_flags[] = {
1405 {CLD_EXITED, "CLD_EXITED"},
1406 {CLD_KILLED, "CLD_KILLED"},
1407 {CLD_DUMPED, "CLD_DUMPED"},
1408 {CLD_TRAPPED, "CLD_TRAPPED"},
1409 {CLD_STOPPED, "CLD_STOPPED"},
1410 {CLD_CONTINUED, "CLD_CONTINUED"},
1411 {0, NULL}
1412};
1413
1414static struct xlat sigpoll_flags[] = {
1415 {POLL_IN, "POLL_IN"},
1416 {POLL_OUT, "POLL_OUT"},
1417 {POLL_MSG, "POLL_MSG"},
1418 {POLL_ERR, "POLL_ERR"},
1419 {POLL_PRI, "POLL_PRI"},
1420 {POLL_HUP, "POLL_HUP"},
1421 {0, NULL}
1422};
1423
1424static struct xlat siginfo_flags[] = {
1425 {SI_USER, "SI_USER"},
1426 {SI_QUEUE, "SI_QUEUE"},
1427 {SI_TIMER, "SI_TIMER"},
1428 {SI_MESGQ, "SI_MESGQ"},
1429 {SI_ASYNCIO, "SI_ASYNCIO"},
1430 {0, NULL}
1431};
1432
1433 static void
1434printsiginfo(tcp, si)
1435 struct tcb *tcp;
1436 siginfo_t *si;
1437{
1438 tprintf("{si_signo=");
1439 printsignal(si->si_signo);
1440 tprintf(", si_errno=%d, si_code=", si->si_errno);
1441 switch(si->si_signo)
1442 {
1443 case SIGILL:
1444 if (!printflags(sigill_flags, si->si_code))
1445 tprintf("%d /* ILL_??? */", si->si_code);
1446 tprintf(", si_addr=%lx",
1447 (unsigned long) si->_sifields._sigfault.si_addr);
1448 break;
1449 case SIGFPE:
1450 if (!printflags(sigfpe_flags, si->si_code))
1451 tprintf("%d /* FPE_??? */", si->si_code);
1452 tprintf(", si_addr=%lx",
1453 (unsigned long) si->_sifields._sigfault.si_addr);
1454 break;
1455 case SIGSEGV:
1456 if (!printflags(sigsegv_flags, si->si_code))
1457 tprintf("%d /* SEGV_??? */", si->si_code);
1458 tprintf(", si_addr=%lx",
1459 (unsigned long) si->_sifields._sigfault.si_addr);
1460 break;
1461 case SIGBUS:
1462 if (!printflags(sigbus_flags, si->si_code))
1463 tprintf("%d /* BUS_??? */", si->si_code);
1464 tprintf(", si_addr=%lx",
1465 (unsigned long) si->_sifields._sigfault.si_addr);
1466 break;
1467 case SIGTRAP:
1468 if (!printflags(sigtrap_flags, si->si_code))
1469 tprintf("%d /* TRAP_??? */", si->si_code);
1470 break;
1471 case SIGCHLD:
1472 if (!printflags(sigchld_flags, si->si_code))
1473 tprintf("%d /* CLD_??? */", si->si_code);
1474 if (!verbose(tcp))
1475 tprintf(", ...");
1476 else
1477 tprintf(", si_pid=%d, si_uid=%d, si_status=%d, si_utime=%lu, si_stime=%lu",
1478 si->_sifields._kill.si_pid,
1479 si->_sifields._kill.si_uid,
1480 si->_sifields._sigchld.si_status,
1481 si->_sifields._sigchld.si_utime,
1482 si->_sifields._sigchld.si_stime);
1483 break;
1484 case SIGPOLL:
1485 if (!printflags(sigpoll_flags, si->si_code))
1486 tprintf("%d /* POLL_??? */", si->si_code);
1487 if (si->si_code == POLL_IN
1488 || si->si_code == POLL_OUT
1489 || si->si_code == POLL_MSG)
1490 tprintf(", si_bind=%lu, si_fd=%d",
1491 (unsigned long) si->_sifields._sigpoll.si_band,
1492 si->_sifields._sigpoll.si_fd);
1493 break;
1494 default:
1495 if (!printflags(siginfo_flags, si->si_code))
1496 tprintf("%d /* SI_??? */", si->si_code);
1497 tprintf(", si_pid=%lu, si_uid=%lu, si_value={",
1498 (unsigned long) si->_sifields._rt.si_pid,
1499 (unsigned long) si->_sifields._rt.si_uid);
1500 if (!verbose(tcp))
1501 tprintf("...");
1502 else {
1503 tprintf("sival_int=%u, sival_ptr=%#lx",
1504 si->_sifields._rt.si_sigval.sival_int,
1505 (unsigned long) si->_sifields._rt.si_sigval.sival_ptr);
1506 }
1507 tprintf("}");
1508 break;
1509 }
1510 tprintf("}");
1511}
1512
1513 int
1514sys_rt_sigqueueinfo(tcp)
1515 struct tcb *tcp;
1516{
1517 if (entering(tcp)) {
1518 siginfo_t si;
1519 tprintf("%lu, ", tcp->u_arg[0]);
1520 printsignal(tcp->u_arg[1]);
1521 tprintf(", ");
1522 if (umove(tcp, tcp->u_arg[2], &si) < 0)
1523 tprintf("%#lx", tcp->u_arg[2]);
1524 else
1525 printsiginfo(&si);
1526 }
1527 return 0;
1528}
1529
1530int sys_rt_sigtimedwait(tcp)
1531 struct tcb *tcp;
1532{
1533 if (entering(tcp)) {
1534 sigset_t sigset;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001535
Nate Sammons4a121431999-04-06 01:19:39 +00001536 if (copy_sigset_len(tcp, tcp->u_arg[0],
1537 &sigset, tcp->u_arg[3]) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001538 tprintf("[?]");
1539 else
Nate Sammons4a121431999-04-06 01:19:39 +00001540 printsigmask(sigset, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001541 tprintf(", ");
1542 }
1543 else {
1544 if (syserror(tcp))
1545 tprintf("%#lx", tcp->u_arg[0]);
1546 else {
1547 siginfo_t si;
1548 if (umove(tcp, tcp->u_arg[1], &si) < 0)
1549 tprintf("%#lx", tcp->u_arg[1]);
1550 else
1551 printsiginfo(&si);
1552 /* XXX For now */
1553 tprintf(", %#lx", tcp->u_arg[2]);
1554 tprintf(", %d", (int) tcp->u_arg[3]);
1555 }
1556 }
1557 return 0;
1558};
1559
1560#endif /* LINUX */
1561