]> granicus.if.org Git - strace/blob - signal.c
3ca9c8f43275850941946d42b1c3c9026a1743d9
[strace] / signal.c
1 /*
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
34 /* ugly hack to make header file do what I want - davidw  */
35 #ifdef __arm__
36 #undef __USE_POSIX199309
37 #endif
38
39 #include <signal.h>
40 #include <sys/user.h>
41 #include <fcntl.h>
42 #if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 && (defined(I386) || defined(M68K))
43 # include <sys/reg.h>
44 #endif
45
46 #ifdef SVR4
47 #include <sys/ucontext.h>
48 #endif /* SVR4 */
49
50 #ifdef LINUX
51 #include <linux/ptrace.h>
52 #ifdef HAVE_ASM_SIGCONTEXT_H
53 #include <asm/sigcontext.h>
54 #ifdef SPARC
55 typedef struct {
56         struct pt_regs          si_regs;
57         int                     si_mask;
58 } m_siginfo_t;
59 #endif
60 #else /* !HAVE_ASM_SIGCONTEXT_H */
61 #ifdef I386
62 struct sigcontext_struct {
63         unsigned short gs, __gsh;
64         unsigned short fs, __fsh;
65         unsigned short es, __esh;
66         unsigned short ds, __dsh;
67         unsigned long edi;
68         unsigned long esi;
69         unsigned long ebp;
70         unsigned long esp;
71         unsigned long ebx;
72         unsigned long edx;
73         unsigned long ecx;
74         unsigned long eax;
75         unsigned long trapno;
76         unsigned long err;
77         unsigned long eip;
78         unsigned short cs, __csh;
79         unsigned long eflags;
80         unsigned long esp_at_signal;
81         unsigned short ss, __ssh;
82         unsigned long i387;
83         unsigned long oldmask;
84         unsigned long cr2;
85 };
86 #else /* !I386 */
87 #ifdef M68K
88 struct sigcontext_struct
89 {
90         unsigned long sc_mask;
91         unsigned long sc_usp;
92         unsigned long sc_d0;
93         unsigned long sc_d1;
94         unsigned long sc_a0;
95         unsigned long sc_a1;
96         unsigned short sc_sr;
97         unsigned long sc_pc;
98         unsigned short sc_formatvec;
99 };
100 #endif /* M68K */
101 #endif /* !I386 */
102 #endif /* !HAVE_ASM_SIGCONTEXT_H */
103 #ifndef NSIG
104 #define NSIG 32
105 #endif
106 #ifdef ARM
107 #undef NSIG
108 #define NSIG 32
109 #endif
110 #endif /* LINUX */
111
112 char *signalent0[] = {
113 #include "signalent.h"
114 };
115 int nsignals0 = sizeof signalent0 / sizeof signalent0[0];
116
117 #if SUPPORTED_PERSONALITIES >= 2
118 char *signalent1[] = {
119 #include "signalent1.h"
120 };
121 int nsignals1 = sizeof signalent1 / sizeof signalent1[0];
122 #endif /* SUPPORTED_PERSONALITIES >= 2 */
123
124 #if SUPPORTED_PERSONALITIES >= 3
125 char *signalent2[] = {
126 #include "signalent2.h"
127 };
128 int nsignals2 = sizeof signalent2 / sizeof signalent2[0];
129 #endif /* SUPPORTED_PERSONALITIES >= 3 */
130
131 char **signalent;
132 int nsignals;
133
134 #ifdef SUNOS4
135
136 static struct xlat sigvec_flags[] = {
137         { SV_ONSTACK,   "SV_ONSTACK"    },
138         { SV_INTERRUPT, "SV_INTERRUPT"  },
139         { SV_RESETHAND, "SV_RESETHAND"  },
140         { SA_NOCLDSTOP, "SA_NOCLDSTOP"  },
141         { 0,            NULL            },
142 };
143
144 #endif /* SUNOS4 */
145
146 #ifdef HAVE_SIGACTION
147
148 static struct xlat sigact_flags[] = {
149 #ifdef SA_STACK
150         { SA_STACK,     "SA_STACK"      },
151 #endif
152 #ifdef SA_RESTART
153         { SA_RESTART,   "SA_RESTART"    },
154 #endif
155 #ifdef SA_INTERRUPT
156         { SA_INTERRUPT, "SA_INTERRUPT"  },
157 #endif
158 #ifdef SA_NOMASK
159         { SA_NOMASK,    "SA_NOMASK"     },
160 #endif
161 #ifdef SA_ONESHOT
162         { SA_ONESHOT,   "SA_ONESHOT"    },
163 #endif
164 #ifdef SA_SIGINFO
165         { SA_SIGINFO,   "SA_SIGINFO"    },
166 #endif
167 #ifdef SA_RESETHAND
168         { SA_RESETHAND, "SA_RESETHAND"  },
169 #endif
170 #ifdef SA_ONSTACK
171         { SA_ONSTACK,   "SA_ONSTACK"    },
172 #endif
173 #ifdef SA_NODEFER
174         { SA_NODEFER,   "SA_NODEFER"    },
175 #endif
176 #ifdef SA_NOCLDSTOP
177         { SA_NOCLDSTOP, "SA_NOCLDSTOP"  },
178 #endif
179 #ifdef SA_NOCLDWAIT
180         { SA_NOCLDWAIT, "SA_NOCLDWAIT"  },
181 #endif
182 #ifdef _SA_BSDCALL
183         { _SA_BSDCALL,  "_SA_BSDCALL"   },
184 #endif
185         { 0,            NULL            },
186 };
187
188 static struct xlat sigprocmaskcmds[] = {
189         { SIG_BLOCK,    "SIG_BLOCK"     },
190         { SIG_UNBLOCK,  "SIG_UNBLOCK"   },
191         { SIG_SETMASK,  "SIG_SETMASK"   },
192 #ifdef SIG_SETMASK32
193         { SIG_SETMASK32,"SIG_SETMASK32" },
194 #endif
195         { 0,            NULL            },
196 };
197
198 #endif /* HAVE_SIGACTION */
199
200 /* Anonymous realtime signals. */
201 /* Under glibc 2.1, SIGRTMIN et al are functions, but __SIGRTMIN is a
202    constant.  This is what we want.  Otherwise, just use SIGRTMIN. */
203 #ifdef SIGRTMIN
204 #ifndef __SIGRTMIN
205 #define __SIGRTMIN SIGRTMIN
206 #define __SIGRTMAX SIGRTMAX /* likewise */
207 #endif
208 #endif
209
210 char *
211 signame(sig)
212 int sig;
213 {
214         static char buf[30];
215         if (sig < nsignals) {
216                 return signalent[sig];
217 #ifdef SIGRTMIN
218         } else if (sig >= __SIGRTMIN && sig <= __SIGRTMAX) {
219                 sprintf(buf, "SIGRT_%d", sig);
220                 return buf;
221 #endif /* SIGRTMIN */
222         } else {
223                 sprintf(buf, "%d", sig);
224                 return buf;
225         }
226 }
227
228 static char *
229 sprintsigmask(s, mask)
230 char *s;
231 sigset_t *mask;
232 {
233         int i, nsigs;
234         char *format;
235         static char outstr[256];
236
237         strcpy(outstr, s);
238         s = outstr + strlen(outstr);
239         nsigs = 0;
240         for (i = 1; i < nsignals; i++) {
241                 if (sigismember(mask, i) == 1)
242                         nsigs++;
243         }
244         if (nsigs >= nsignals * 2 / 3) {
245                 *s++ = '~';
246                 for (i = 1; i < nsignals; i++) {
247                         switch (sigismember(mask, i)) {
248                         case 1:
249                                 sigdelset(mask, i);
250                                 break;
251                         case 0:
252                                 sigaddset(mask, i);
253                                 break;
254                         }
255                 }
256         }
257         format = "%s";
258         *s++ = '[';
259         for (i = 1; i < nsignals; i++) {
260                 if (sigismember(mask, i) == 1) {
261                         sprintf(s, format, signame(i) + 3); s += strlen(s);
262                         format = " %s";
263                 }
264         }
265         *s++ = ']';
266         *s = '\0';
267         return outstr;
268 }
269
270 static void
271 printsigmask(mask)
272 sigset_t *mask;
273 {
274         tprintf("%s", sprintsigmask("", mask));
275 }
276
277 void
278 printsignal(nr)
279 int nr;
280 {
281         tprintf(signame(nr));
282 }
283
284 /*
285  * Check process TCP for the disposition of signal SIG.
286  * Return 1 if the process would somehow manage to  survive signal SIG,
287  * else return 0.  This routine will never be called with SIGKILL.
288  */
289 int
290 sigishandled(tcp, sig)
291 struct tcb *tcp;
292 int sig;
293 {
294 #ifdef LINUX
295         int sfd;
296         char sname[32];
297         char buf[1024];
298         char *s;
299         int i;
300         int signalled, blocked, ignored, caught;
301
302         /* This is incredibly costly but it's worth it. */
303         sprintf(sname, "/proc/%d/stat", tcp->pid);
304         if ((sfd = open(sname, O_RDONLY)) == -1) {
305                 perror(sname);
306                 return 1;
307         }
308         i = read(sfd, buf, 1024);
309         buf[i] = '\0';
310         close(sfd);
311         /*
312          * Skip the extraneous fields. This loses if the
313          * command name has any spaces in it.  So be it.
314          */
315         for (i = 0, s = buf; i < 30; i++) {
316                 while (*++s != ' ') {
317                         if (!*s)
318                                 break;
319                 }
320         }
321         if (sscanf(s, "%d%d%d%d",
322                    &signalled, &blocked, &ignored, &caught) != 4) {
323                 fprintf(stderr, "/proc/pid/stat format error\n");
324                 return 1;
325         }
326 #ifdef DEBUG
327         fprintf(stderr, "sigs: %08x %08x %08x %08x\n",
328                 signalled, blocked, ignored, caught);
329 #endif
330         if ((ignored & sigmask(sig)) || (caught & sigmask(sig)))
331                 return 1;
332 #endif /* LINUX */
333
334 #ifdef SUNOS4
335         void (*u_signal)();
336
337         if (upeek(tcp->pid, uoff(u_signal[0]) + sig*sizeof(u_signal),
338             (long *) &u_signal) < 0) {
339                 return 0;
340         }
341         if (u_signal != SIG_DFL)
342                 return 1;
343 #endif /* SUNOS4 */
344
345 #ifdef SVR4
346         /*
347          * Since procfs doesn't interfere with wait I think it is safe
348          * to punt on this question.  If not, the information is there.
349          */
350         return 1;
351 #else /* !SVR4 */
352         switch (sig) {
353         case SIGCONT:
354         case SIGSTOP:
355         case SIGTSTP:
356         case SIGTTIN:
357         case SIGTTOU:
358         case SIGCHLD:
359         case SIGIO:
360 #if defined(SIGURG) && SIGURG != SIGIO
361         case SIGURG:
362 #endif
363         case SIGWINCH:
364                 /* Gloria Gaynor says ... */
365                 return 1;
366         default:
367                 break;
368         }
369         return 0;
370 #endif /* !SVR4 */
371 }
372
373 #if defined(SUNOS4)
374
375 int
376 sys_sigvec(tcp)
377 struct tcb *tcp;
378 {
379         struct sigvec sv;
380         long addr;
381
382         if (entering(tcp)) {
383                 printsignal(tcp->u_arg[0]);
384                 tprintf(", ");
385                 addr = tcp->u_arg[1];
386         } else {
387                 addr = tcp->u_arg[2];
388         }
389         if (addr == 0)
390                 tprintf("NULL");
391         else if (!verbose(tcp))
392                 tprintf("%#lx", addr);
393         else if (umove(tcp, addr, &sv) < 0)
394                 tprintf("{...}");
395         else {
396                 switch ((int) sv.sv_handler) {
397                 case (int) SIG_ERR:
398                         tprintf("{SIG_ERR}");
399                         break;
400                 case (int) SIG_DFL:
401                         tprintf("{SIG_DFL}");
402                         break;
403                 case (int) SIG_IGN:
404                         if (tcp->u_arg[0] == SIGTRAP) {
405                                 tcp->flags |= TCB_SIGTRAPPED;
406                                 kill(tcp->pid, SIGSTOP);
407                         }
408                         tprintf("{SIG_IGN}");
409                         break;
410                 case (int) SIG_HOLD:
411                         if (tcp->u_arg[0] == SIGTRAP) {
412                                 tcp->flags |= TCB_SIGTRAPPED;
413                                 kill(tcp->pid, SIGSTOP);
414                         }
415                         tprintf("SIG_HOLD");
416                         break;
417                 default:
418                         if (tcp->u_arg[0] == SIGTRAP) {
419                                 tcp->flags |= TCB_SIGTRAPPED;
420                                 kill(tcp->pid, SIGSTOP);
421                         }
422                         tprintf("{%#lx, ", (unsigned long) sv.sv_handler);
423                         printsigmask(&sv.sv_mask);
424                         tprintf(", ");
425                         if (!printflags(sigvec_flags, sv.sv_flags))
426                                 tprintf("0");
427                         tprintf("}");
428                 }
429         }
430         if (entering(tcp))
431                 tprintf(", ");
432         return 0;
433 }
434
435 int
436 sys_sigpause(tcp)
437 struct tcb *tcp;
438 {
439         if (entering(tcp)) {    /* WTA: UD had a bug here: he forgot the braces */
440                 sigset_t sigm = tcp->u_arg[0];
441                 printsigmask(&sigm);
442         }
443         return 0;
444 }
445
446 int
447 sys_sigstack(tcp)
448 struct tcb *tcp;
449 {
450         struct sigstack ss;
451         long addr;
452
453         if (entering(tcp))
454                 addr = tcp->u_arg[0];
455         else
456                 addr = tcp->u_arg[1];
457         if (addr == 0)
458                 tprintf("NULL");
459         else if (umove(tcp, addr, &ss) < 0)
460                 tprintf("%#lx", addr);
461         else {
462                 tprintf("{ss_sp %#lx ", (unsigned long) ss.ss_sp);
463                 tprintf("ss_onstack %s}", ss.ss_onstack ? "YES" : "NO");
464         }
465         if (entering(tcp))
466                 tprintf(", ");
467         return 0;
468 }
469
470 int
471 sys_sigcleanup(tcp)
472 struct tcb *tcp;
473 {
474         return 0;
475 }
476
477 #endif /* SUNOS4 */
478
479 #ifndef SVR4
480
481 int
482 sys_sigsetmask(tcp)
483 struct tcb *tcp;
484 {
485         if (entering(tcp)) {
486 #ifdef LINUX
487                 sigset_t sigm;
488                 sigemptyset(&sigm);
489                 sigm.__val[0] = tcp->u_arg[0];
490 #else
491                 sigset_t sigm = tcp->u_arg[0];
492 #endif
493                 printsigmask(&sigm);
494                 if ((tcp->u_arg[0] & sigmask(SIGTRAP))) {
495                         /* Mark attempt to block SIGTRAP */
496                         tcp->flags |= TCB_SIGTRAPPED;
497                         /* Send unblockable signal */
498                         kill(tcp->pid, SIGSTOP);
499                 }
500         }
501         else if (!syserror(tcp)) {
502 #ifdef LINUX
503                 sigset_t sigm;
504                 sigemptyset(&sigm);
505                 sigm.__val[0] = tcp->u_rval;
506 #else
507                 sigset_t sigm = tcp->u_rval;
508 #endif
509                 tcp->auxstr = sprintsigmask("old mask ", &sigm);
510
511                 return RVAL_HEX | RVAL_STR;
512         }
513         return 0;
514 }
515
516 int
517 sys_sigblock(tcp)
518 struct tcb *tcp;
519 {
520         return sys_sigsetmask(tcp);
521 }
522
523 #endif /* !SVR4 */
524
525 #ifdef HAVE_SIGACTION
526
527 #ifdef LINUX
528 struct old_sigaction {
529         __sighandler_t __sa_handler;
530         unsigned long sa_mask;
531         unsigned long sa_flags;
532         void (*sa_restorer)(void);
533 };
534 #endif
535
536 int
537 sys_sigaction(tcp)
538 struct tcb *tcp;
539 {
540         long addr;
541 #ifdef LINUX
542         sigset_t sigset;
543         struct old_sigaction sa;
544         sigemptyset(&sigset);
545 #else
546         struct sigaction sa;
547 #endif
548
549
550         if (entering(tcp)) {
551                 printsignal(tcp->u_arg[0]);
552                 tprintf(", ");
553                 addr = tcp->u_arg[1];
554         } else
555                 addr = tcp->u_arg[2];
556         if (addr == 0)
557                 tprintf("NULL");
558         else if (!verbose(tcp))
559                 tprintf("%#lx", addr);
560         else if (umove(tcp, addr, &sa) < 0)
561                 tprintf("{...}");
562         else {
563                 switch ((long) sa.__sa_handler) {
564                 case (long) SIG_ERR:
565                         tprintf("{SIG_ERR}");
566                         break;
567                 case (long) SIG_DFL:
568                         tprintf("{SIG_DFL}");
569                         break;
570                 case (long) SIG_IGN:
571 #ifndef SVR4
572                         if (tcp->u_arg[0] == SIGTRAP) {
573                                 tcp->flags |= TCB_SIGTRAPPED;
574                                 kill(tcp->pid, SIGSTOP);
575                         }
576 #endif /* !SVR4 */
577                         tprintf("{SIG_IGN}");
578                         break;
579                 default:
580 #ifndef SVR4
581                         if (tcp->u_arg[0] == SIGTRAP) {
582                                 tcp->flags |= TCB_SIGTRAPPED;
583                                 kill(tcp->pid, SIGSTOP);
584                         }
585 #endif /* !SVR4 */
586                         tprintf("{%#lx, ", (long) sa.__sa_handler);
587 #ifdef LINUX
588                         sigset.__val[0] = sa.sa_mask;
589                         printsigmask(&sigset);
590 #else
591                         printsigmask(&sa.sa_mask);
592 #endif
593                         tprintf(", ");
594                         if (!printflags(sigact_flags, sa.sa_flags))
595                                 tprintf("0");
596                         tprintf("}");
597                 }
598         }
599         if (entering(tcp))
600                 tprintf(", ");
601 #ifdef LINUX
602         else
603                 tprintf(", %#lx", (unsigned long) sa.sa_restorer);
604 #endif
605         return 0;
606 }
607
608 int
609 sys_signal(tcp)
610 struct tcb *tcp;
611 {
612         if (entering(tcp)) {
613                 printsignal(tcp->u_arg[0]);
614                 switch (tcp->u_arg[1]) {
615                 case (int) SIG_ERR:
616                         tprintf("SIG_ERR");
617                         break;
618                 case (int) SIG_DFL:
619                         tprintf("SIG_DFL");
620                         break;
621                 case (int) SIG_IGN:
622 #ifndef SVR4
623                         if (tcp->u_arg[0] == SIGTRAP) {
624                                 tcp->flags |= TCB_SIGTRAPPED;
625                                 kill(tcp->pid, SIGSTOP);
626                         }
627 #endif /* !SVR4 */
628                         tprintf("SIG_IGN");
629                         break;
630                 default:
631 #ifndef SVR4
632                         if (tcp->u_arg[0] == SIGTRAP) {
633                                 tcp->flags |= TCB_SIGTRAPPED;
634                                 kill(tcp->pid, SIGSTOP);
635                         }
636 #endif /* !SVR4 */
637                         tprintf("%#lx", tcp->u_arg[1]);
638                 }
639         }
640         return 0;
641 }
642
643 #endif /* HAVE_SIGACTION */
644
645 #ifdef LINUX
646
647 int
648 sys_sigreturn(tcp)
649 struct tcb *tcp;
650 {
651 #ifdef I386
652         long esp;
653         struct sigcontext_struct sc;
654
655         if (entering(tcp)) {
656                 tcp->u_arg[0] = 0;
657                 if (upeek(tcp->pid, 4*UESP, &esp) < 0)
658                         return 0;
659                 if (umove(tcp, esp, &sc) < 0)
660                         return 0;
661                 tcp->u_arg[0] = 1;
662                 tcp->u_arg[1] = sc.oldmask;
663         }
664         else {
665                 sigset_t sigm;
666                 sigemptyset(&sigm);
667                 sigm.__val[0] = tcp->u_arg[1];
668                 tcp->u_rval = tcp->u_error = 0;
669                 if (tcp->u_arg[0] == 0)
670                         return 0;
671                 tcp->auxstr = sprintsigmask("mask now ", &sigm);
672                 return RVAL_NONE | RVAL_STR;
673         }
674         return 0;
675 #else /* !I386 */
676 #ifdef POWERPC
677        long esp;
678        struct sigcontext_struct sc;
679
680        if (entering(tcp)) {
681                    tcp->u_arg[0] = 0;
682                    if (upeek(tcp->pid, 4*PT_R1, &esp) < 0)
683                            return 0;
684                    if (umove(tcp, esp, &sc) < 0)
685                            return 0;
686                    tcp->u_arg[0] = 1;
687                    tcp->u_arg[1] = sc.oldmask;
688        }
689        else {
690                    sigset_t sigm;
691                    sigemptyset(&sigm);
692                    sigm.__val[0] = tcp->u_arg[1];
693                    tcp->u_rval = tcp->u_error = 0;
694                    if (tcp->u_arg[0] == 0)
695                            return 0;
696                    tcp->auxstr = sprintsigmask("mask now ", &sigm);
697                    return RVAL_NONE | RVAL_STR;
698        }
699        return 0;
700 #else /* !POWERPC */
701 #ifdef M68K
702         long usp;
703         struct sigcontext_struct sc;
704
705         if (entering(tcp)) {
706             tcp->u_arg[0] = 0;
707             if (upeek(tcp->pid, 4*PT_USP, &usp) < 0)
708                         return 0;
709             if (umove(tcp, usp, &sc) < 0)
710                         return 0;
711             tcp->u_arg[0] = 1;
712             tcp->u_arg[1] = sc.sc_mask;
713         }
714         else {
715             sigset_t sigm;
716             sigemptyset(&sigm);
717             sigm.__val[0] = tcp->u_arg[1];
718             tcp->u_rval = tcp->u_error = 0;
719             if (tcp->u_arg[0] == 0)
720                         return 0;
721             tcp->auxstr = sprintsigmask("mask now ", &sigm);
722             return RVAL_NONE | RVAL_STR;
723         }
724         return 0;
725 #else /* !M68K */
726 #ifdef ALPHA
727         long fp;
728         struct sigcontext_struct sc;
729
730         if (entering(tcp)) {
731             tcp->u_arg[0] = 0;
732             if (upeek(tcp->pid, REG_FP, &fp) < 0)
733                         return 0;
734             if (umove(tcp, fp, &sc) < 0)
735                         return 0;
736             tcp->u_arg[0] = 1;
737             tcp->u_arg[1] = sc.sc_mask;
738         }
739         else {
740             sigset_t sigm;
741             sigemptyset(&sigm);
742             sigm.__val[0] = tcp->u_arg[1];
743             tcp->u_rval = tcp->u_error = 0;
744             if (tcp->u_arg[0] == 0)
745                         return 0;
746             tcp->auxstr = sprintsigmask("mask now ", &sigm);
747             return RVAL_NONE | RVAL_STR;
748         }
749         return 0;
750 #else
751 #ifdef SPARC
752         long i1;
753         struct pt_regs regs;
754         m_siginfo_t si;
755
756         if(ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
757             perror("sigreturn: PTRACE_GETREGS ");
758             return 0;
759         }
760         memmove (&regs.u_regs [1], &regs.u_regs [0],
761                         sizeof (regs.u_regs) - sizeof (regs.u_regs [0]));
762         if(entering(tcp)) {
763                 tcp->u_arg[0] = 0;
764                 i1 = regs.u_regs[UREG_I1];
765                 if(umove(tcp, i1, &si) < 0) {
766                         perror("sigreturn: umove ");
767                         return 0;
768                 }
769                 tcp->u_arg[0] = 1;
770                 tcp->u_arg[1] = si.si_mask;
771         } else {
772                 sigset_t sigm;
773                 sigemptyset(&sigm);
774                 sigm.__val[0] = tcp->u_arg[1];
775                 tcp->u_rval = tcp->u_error = 0;
776                 if(tcp->u_arg[0] == 0)
777                         return 0;
778                 tcp->auxstr = sprintsigmask("mask now ", &sigm);
779                 return RVAL_NONE | RVAL_STR;
780         }
781         return 0;
782 #endif /* SPARC */
783 #endif /* ALPHA */
784 #endif /* !M68K */
785 #endif /* !POWERPC */
786 #endif /* !I386 */
787 }
788
789 int
790 sys_siggetmask(tcp)
791 struct tcb *tcp;
792 {
793         if (exiting(tcp)) {
794 #ifdef LINUX
795                 sigset_t sigm;
796                 sigemptyset(&sigm);
797                 sigm.__val[0] = tcp->u_rval;
798 #else
799                 sigset_t sigm = tcp->u_rval;
800 #endif
801                 tcp->auxstr = sprintsigmask("mask ", &sigm);
802         }
803         return RVAL_HEX | RVAL_STR;
804 }
805
806 int
807 sys_sigsuspend(tcp)
808 struct tcb *tcp;
809 {
810         if (entering(tcp)) {
811                 sigset_t sigm;
812                 sigemptyset(&sigm);
813                 sigm.__val[0] = tcp->u_arg[2];
814 #if 0
815                 /* first two are not really arguments, but print them anyway */
816                 /* nevermind, they are an anachronism now, too bad... */
817                 tprintf("%d, %#x, ", tcp->u_arg[0], tcp->u_arg[1]);
818 #endif
819                 printsigmask(&sigm);
820         }
821         return 0;
822 }
823
824 #endif /* LINUX */
825
826 #ifdef SVR4
827
828 int
829 sys_sigsuspend(tcp)
830 struct tcb *tcp;
831 {
832         sigset_t sigset;
833
834         if (entering(tcp)) {
835                 if (umove(tcp, tcp->u_arg[0], &sigset) < 0)
836                         tprintf("[?]");
837                 else
838                         printsigmask(sigset);
839         }
840         return 0;
841 }
842 static struct xlat ucontext_flags[] = {
843         { UC_SIGMASK,   "UC_SIGMASK"    },
844         { UC_STACK,     "UC_STACK"      },
845         { UC_CPU,       "UC_CPU"        },
846 #ifdef UC_FPU
847         { UC_FPU,       "UC_FPU"        },
848 #endif
849 #ifdef UC_INTR
850         { UC_INTR,      "UC_INTR"       },
851 #endif
852         { 0,            NULL            },
853 };
854
855 #endif
856
857 #if defined SVR4 || defined LINUX
858 #if defined LINUX && !defined SS_ONSTACK
859 #define SS_ONSTACK      1
860 #define SS_DISABLE      2
861 #if __GLIBC_MINOR__ == 0
862 typedef struct
863 {
864         __ptr_t ss_sp;
865         int ss_flags;
866         size_t ss_size;
867 } stack_t;
868 #endif
869 #endif
870
871 static struct xlat sigaltstack_flags[] = {
872         { SS_ONSTACK,   "SS_ONSTACK"    },
873         { SS_DISABLE,   "SS_DISABLE"    },
874         { 0,            NULL            },
875 };
876 #endif
877
878 #ifdef SVR4
879 static void
880 printcontext(tcp, ucp)
881 struct tcb *tcp;
882 ucontext_t *ucp;
883 {
884         tprintf("{");
885         if (!abbrev(tcp)) {
886                 tprintf("uc_flags=");
887                 if (!printflags(ucontext_flags, ucp->uc_flags))
888                         tprintf("0");
889                 tprintf(", uc_link=%#lx, ", (unsigned long) ucp->uc_link);
890         }
891         tprintf("uc_sigmask=");
892         printsigmask(ucp->uc_sigmask);
893         if (!abbrev(tcp)) {
894                 tprintf(", uc_stack={ss_sp=%#lx, ss_size=%d, ss_flags=",
895                         (unsigned long) ucp->uc_stack.ss_sp,
896                         ucp->uc_stack.ss_size);
897                 if (!printflags(sigaltstack_flags, ucp->uc_stack.ss_flags))
898                         tprintf("0");
899                 tprintf("}");
900         }
901         tprintf(", ...}");
902 }
903
904 int
905 sys_getcontext(tcp)
906 struct tcb *tcp;
907 {
908         ucontext_t uc;
909
910         if (entering(tcp)) {
911                 if (!tcp->u_arg[0])
912                         tprintf("NULL");
913                 else if (umove(tcp, tcp->u_arg[0], &uc) < 0)
914                         tprintf("{...}");
915                 else
916                         printcontext(tcp, &uc);
917         }
918         return 0;
919 }
920
921 int
922 sys_setcontext(tcp)
923 struct tcb *tcp;
924 {
925         ucontext_t uc;
926
927         if (entering(tcp)) {
928                 if (!tcp->u_arg[0])
929                         tprintf("NULL");
930                 else if (umove(tcp, tcp->u_arg[0], &uc) < 0)
931                         tprintf("{...}");
932                 else
933                         printcontext(tcp, &uc);
934         }
935         else {
936                 tcp->u_rval = tcp->u_error = 0;
937                 if (tcp->u_arg[0] == 0)
938                         return 0;
939                 return RVAL_NONE;
940         }
941         return 0;
942 }
943
944 #endif /* SVR4 */
945
946 #ifdef LINUX
947
948 static int
949 print_stack_t(tcp, addr)
950 struct tcb *tcp;
951 unsigned long addr;
952 {
953         stack_t ss;
954         if (umove(tcp, addr, &ss) < 0)
955                 return -1;
956         tprintf("{ss_sp=%#lx, ss_flags=", (unsigned long) ss.ss_sp);
957         if (!printflags(sigaltstack_flags, ss.ss_flags))
958                 tprintf("0");
959         tprintf(", ss_size=%lu}", (unsigned long) ss.ss_size);
960         return 0;
961 }
962
963 int
964 sys_sigaltstack(tcp)
965         struct tcb *tcp;
966 {
967         if (entering(tcp)) {
968                 if (tcp->u_arg[0] == 0)
969                         tprintf("NULL");
970                 else if (print_stack_t(tcp, tcp->u_arg[0]) < 0)
971                         return -1;
972         }
973         else {
974                 tprintf(", ");
975                 if (tcp->u_arg[1] == 0)
976                         tprintf("NULL");
977                 else if (print_stack_t(tcp, tcp->u_arg[1]) < 0)
978                         return -1;
979         }
980         return 0;
981 }
982 #endif
983
984 #ifdef HAVE_SIGACTION
985
986 int
987 sys_sigprocmask(tcp)
988 struct tcb *tcp;
989 {
990 #ifdef ALPHA
991         if (entering(tcp)) {
992                 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
993                 tprintf(", ");
994                 printsigmask(tcp->u_arg[1]);
995         }
996         else if (!syserror(tcp)) {
997                 tcp->auxstr = sprintsigmask("old mask ", tcp->u_rval);
998                 return RVAL_HEX | RVAL_STR;
999         }
1000 #else /* !ALPHA */
1001         sigset_t sigset;
1002 #ifdef LINUX
1003         sigemptyset(&sigset);
1004 #endif
1005
1006         if (entering(tcp)) {
1007 #ifdef SVR4
1008                 if (tcp->u_arg[0] == 0)
1009                         tprintf("0");
1010                 else
1011 #endif /* SVR4 */
1012                 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1013                 tprintf(", ");
1014                 if (!tcp->u_arg[1])
1015                         tprintf("NULL, ");
1016 #ifdef LINUX
1017                 else if (umoven(tcp, tcp->u_arg[1], 4, (char *) &sigset.__val[0]) < 0)
1018                         tprintf("%#lx, ", tcp->u_arg[1]);
1019 #else
1020                 else if (umove(tcp, tcp->u_arg[1], &sigset) < 0)
1021                         tprintf("%#lx, ", tcp->u_arg[1]);
1022 #endif
1023                 else {
1024                         printsigmask(&sigset);
1025                         tprintf(", ");
1026                 }
1027         }
1028         else {
1029                 if (!tcp->u_arg[2])
1030                         tprintf("NULL");
1031                 else if (syserror(tcp))
1032                         tprintf("%#lx", tcp->u_arg[2]);
1033 #ifdef LINUX
1034                 else if (umoven(tcp, tcp->u_arg[2], 4, (char *) &sigset.__val[0]) < 0)
1035                         tprintf("[?]");
1036 #else
1037                 else if (umove(tcp, tcp->u_arg[2], &sigset) < 0)
1038                         tprintf("[?]");
1039 #endif
1040                 else
1041                         printsigmask(&sigset);
1042         }
1043 #endif /* !ALPHA */
1044         return 0;
1045 }
1046
1047 #endif /* HAVE_SIGACTION */
1048
1049 int
1050 sys_kill(tcp)
1051 struct tcb *tcp;
1052 {
1053         if (entering(tcp)) {
1054                 tprintf("%ld, %s", tcp->u_arg[0], signame(tcp->u_arg[1]));
1055         }
1056         return 0;
1057 }
1058
1059 int
1060 sys_killpg(tcp)
1061 struct tcb *tcp;
1062 {
1063         return sys_kill(tcp);
1064 }
1065
1066 int
1067 sys_sigpending(tcp)
1068 struct tcb *tcp;
1069 {
1070         sigset_t sigset;
1071 #ifdef LINUX
1072    sigemptyset(&sigset);
1073 #endif
1074
1075         if (exiting(tcp)) {
1076                 if (syserror(tcp))
1077                         tprintf("%#lx", tcp->u_arg[0]);
1078 #ifdef LINUX
1079                 else if (umoven(tcp, tcp->u_arg[0], 4, (char *) &sigset.__val[0]) < 0)
1080                         tprintf("[?]");
1081 #else
1082                 else if (umove(tcp, tcp->u_arg[0], &sigset) < 0)
1083                         tprintf("[?]");
1084 #endif
1085                 else
1086                         printsigmask(sigset);
1087         }
1088         return 0;
1089 }
1090
1091 #ifdef LINUX
1092
1093         int
1094 sys_rt_sigprocmask(tcp)
1095         struct tcb *tcp;
1096 {
1097         sigset_t sigset;
1098
1099         if (entering(tcp)) {
1100                 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1101                 tprintf(", ");
1102                 if (!tcp->u_arg[1])
1103                         tprintf("NULL, ");
1104                 else if (umove(tcp, tcp->u_arg[1], &sigset) < 0)
1105                         tprintf("%#lx, ", tcp->u_arg[1]);
1106                 else {
1107                         printsigmask(&sigset);
1108                         tprintf(", ");
1109                 }
1110         }
1111         else {
1112                 if (!tcp->u_arg[2])
1113
1114                         tprintf("NULL");
1115                 else if (syserror(tcp))
1116                         tprintf("%#lx", tcp->u_arg[2]);
1117                 else if (umove(tcp, tcp->u_arg[2], &sigset) < 0)
1118                         tprintf("[?]");
1119                 else
1120                         printsigmask(&sigset);
1121                 tprintf(", %lu", tcp->u_arg[3]);
1122         }
1123         return 0;
1124 }
1125
1126 #if __GLIBC_MINOR__ < 1
1127 /* Type for data associated with a signal.  */
1128 typedef union sigval
1129 {
1130         int sival_int;
1131         void *sival_ptr;
1132 } sigval_t;
1133
1134 # define __SI_MAX_SIZE     128
1135 # define __SI_PAD_SIZE     ((__SI_MAX_SIZE / sizeof (int)) - 3)
1136
1137 typedef struct siginfo
1138 {
1139         int si_signo;               /* Signal number.  */
1140         int si_errno;               /* If non-zero, an errno value associated with
1141                                                                    this signal, as defined in <errno.h>.  */
1142         int si_code;                /* Signal code.  */
1143
1144         union
1145         {
1146                 int _pad[__SI_PAD_SIZE];
1147
1148                 /* kill().  */
1149                 struct
1150                 {
1151                         __pid_t si_pid;     /* Sending process ID.  */
1152                         __uid_t si_uid;     /* Real user ID of sending process.  */
1153                 } _kill;
1154
1155                 /* POSIX.1b timers.  */
1156                 struct
1157                 {
1158                         unsigned int _timer1;
1159                         unsigned int _timer2;
1160                 } _timer;
1161
1162                 /* POSIX.1b signals.  */
1163                 struct
1164                 {
1165                         __pid_t si_pid;     /* Sending process ID.  */
1166                         __uid_t si_uid;     /* Real user ID of sending process.  */
1167                         sigval_t si_sigval; /* Signal value.  */
1168                 } _rt;
1169
1170                 /* SIGCHLD.  */
1171                 struct
1172                 {
1173                         __pid_t si_pid;     /* Which child.  */
1174                         int si_status;      /* Exit value or signal.  */
1175                         __clock_t si_utime;
1176                         __clock_t si_stime;
1177                 } _sigchld;
1178
1179                 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS.  */
1180                 struct
1181                 {
1182                         void *si_addr;      /* Faulting insn/memory ref.  */
1183                 } _sigfault;
1184
1185                 /* SIGPOLL.  */
1186                 struct
1187                 {
1188                         int si_band;        /* Band event for SIGPOLL.  */
1189                         int si_fd;
1190                 } _sigpoll;
1191         } _sifields;
1192 } siginfo_t;
1193 #endif
1194
1195 /* Structure describing the action to be taken when a signal arrives.  */
1196 struct new_sigaction
1197 {
1198         union
1199         {
1200                 __sighandler_t __sa_handler;
1201                 void (*__sa_sigaction) (int, siginfo_t *, void *);
1202         }
1203         __sigaction_handler;
1204         unsigned long sa_flags;
1205         void (*sa_restorer) (void);
1206         unsigned long int sa_mask[2];
1207 };
1208
1209
1210         int
1211 sys_rt_sigaction(tcp)
1212         struct tcb *tcp;
1213 {
1214         struct new_sigaction sa;
1215         sigset_t sigset;
1216         long addr;
1217         sigemptyset(&sigset);
1218
1219         if (entering(tcp)) {
1220                 printsignal(tcp->u_arg[0]);
1221                 tprintf(", ");
1222                 addr = tcp->u_arg[1];
1223         } else
1224                 addr = tcp->u_arg[2];
1225         if (addr == 0)
1226                 tprintf("NULL");
1227         else if (!verbose(tcp))
1228                 tprintf("%#lx", addr);
1229         else if (umove(tcp, addr, &sa) < 0)
1230                 tprintf("{...}");
1231         else {
1232                 switch ((long) sa.__sigaction_handler.__sa_handler) {
1233                         case (long) SIG_ERR:
1234                                 tprintf("{SIG_ERR}");
1235                                 break;
1236                         case (long) SIG_DFL:
1237                                 tprintf("{SIG_DFL}");
1238                                 break;
1239                         case (long) SIG_IGN:
1240                                 tprintf("{SIG_IGN}");
1241                                 break;
1242                         default:
1243                                 tprintf("{%#lx, ",
1244                                                 (long) sa.__sigaction_handler.__sa_handler);
1245                                 sigset.__val[0] = sa.sa_mask[0];
1246                                 sigset.__val[1] = sa.sa_mask[1];
1247                                 printsigmask(&sigset);
1248                                 tprintf(", ");
1249                                 if (!printflags(sigact_flags, sa.sa_flags))
1250                                         tprintf("0");
1251                                 tprintf("}");
1252                 }
1253         }
1254         if (entering(tcp))
1255                 tprintf(", ");
1256         else
1257                 tprintf(", %lu", addr = tcp->u_arg[3]);
1258         return 0;
1259 }
1260
1261         int
1262 sys_rt_sigpending(tcp)
1263         struct tcb *tcp;
1264 {
1265         sigset_t sigset;
1266         sigemptyset(&sigset);
1267
1268         if (exiting(tcp)) {
1269                 if (syserror(tcp))
1270                         tprintf("%#lx", tcp->u_arg[0]);
1271                 else if (umoven(tcp, tcp->u_arg[0], tcp->u_arg[1],
1272                                         (char *) &sigset.__val[0]) < 0)
1273                         tprintf("[?]");
1274                 else
1275                         printsigmask(sigset);
1276         }
1277         return 0;
1278 }
1279         int
1280 sys_rt_sigsuspend(tcp)
1281         struct tcb *tcp;
1282 {
1283         if (entering(tcp)) {
1284                 sigset_t sigm;
1285                 sigemptyset(&sigm);
1286                 umoven(tcp, tcp->u_arg[0], tcp->u_arg[1], (char *) &sigm);
1287                 printsigmask(&sigm);
1288         }
1289         return 0;
1290 }
1291 #ifndef ILL_ILLOPC
1292 #define ILL_ILLOPC      1       /* illegal opcode */
1293 #define ILL_ILLOPN      2       /* illegal operand */
1294 #define ILL_ILLADR      3       /* illegal addressing mode */
1295 #define ILL_ILLTRP      4       /* illegal trap */
1296 #define ILL_PRVOPC      5       /* privileged opcode */
1297 #define ILL_PRVREG      6       /* privileged register */
1298 #define ILL_COPROC      7       /* coprocessor error */
1299 #define ILL_BADSTK      8       /* internal stack error */
1300 #define FPE_INTDIV      1       /* integer divide by zero */
1301 #define FPE_INTOVF      2       /* integer overflow */
1302 #define FPE_FLTDIV      3       /* floating point divide by zero */
1303 #define FPE_FLTOVF      4       /* floating point overflow */
1304 #define FPE_FLTUND      5       /* floating point underflow */
1305 #define FPE_FLTRES      6       /* floating point inexact result */
1306 #define FPE_FLTINV      7       /* floating point invalid operation */
1307 #define FPE_FLTSUB      8       /* subscript out of range */
1308 #define SEGV_MAPERR     1       /* address not mapped to object */
1309 #define SEGV_ACCERR     2       /* invalid permissions for mapped object */
1310 #define BUS_ADRALN      1       /* invalid address alignment */
1311 #define BUS_ADRERR      2       /* non-existant physical address */
1312 #define BUS_OBJERR      3       /* object specific hardware error */
1313 #define TRAP_BRKPT      1       /* process breakpoint */
1314 #define TRAP_TRACE      2       /* process trace trap */
1315 #define CLD_EXITED      1       /* child has exited */
1316 #define CLD_KILLED      2       /* child was killed */
1317 #define CLD_DUMPED      3       /* child terminated abnormally */
1318 #define CLD_TRAPPED     4       /* traced child has trapped */
1319 #define CLD_STOPPED     5       /* child has stopped */
1320 #define CLD_CONTINUED   6       /* stopped child has continued */
1321 #define POLL_IN         1       /* data input available */
1322 #define POLL_OUT        2       /* output buffers available */
1323 #define POLL_MSG        3       /* input message available */
1324 #define POLL_ERR        4       /* i/o error */
1325 #define POLL_PRI        5       /* high priority input available */
1326 #define POLL_HUP        6       /* device disconnected */
1327 #define SI_USER         0       /* sent by kill, sigsend, raise */
1328 #define SI_QUEUE        -1      /* sent by sigqueue */
1329 #define SI_TIMER        -2      /* sent by timer expiration */
1330 #define SI_MESGQ        -3      /* sent by real time mesq state change */
1331 #define SI_ASYNCIO      -4      /* sent by AIO completion */
1332 #else
1333 #undef si_pid
1334 #undef si_uid
1335 #undef si_status
1336 #undef si_utime
1337 #undef si_stime
1338 #undef si_value
1339 #undef si_int
1340 #undef si_ptr
1341 #undef si_addr
1342 #undef si_band
1343 #undef si_fd
1344 #endif
1345
1346 static struct xlat sigill_flags[] = {
1347         {ILL_ILLOPC, "ILL_ILLOPC"},
1348         {ILL_ILLOPN, "ILL_ILLOPN"},
1349         {ILL_ILLADR, "ILL_ILLADR"},
1350         {ILL_ILLTRP, "ILL_ILLTRP"},
1351         {ILL_PRVOPC, "ILL_PRVOPC"},
1352         {ILL_PRVREG, "ILL_PRVREG"},
1353         {ILL_COPROC, "ILL_COPROC"},
1354         {ILL_BADSTK, "ILL_BADSTK"},
1355         {0, NULL}
1356 };
1357
1358 static struct xlat sigfpe_flags[] = {
1359         {FPE_INTDIV, "FPE_INTDIV"},
1360         {FPE_INTOVF, "FPE_INTOVF"},
1361         {FPE_FLTDIV, "FPE_FLTDIV"},
1362         {FPE_FLTOVF, "FPE_FLTOVF"},
1363         {FPE_FLTUND, "FPE_FLTUND"},
1364         {FPE_FLTRES, "FPE_FLTRES"},
1365         {FPE_FLTINV, "FPE_FLTINV"},
1366         {FPE_FLTSUB, "FPE_FLTSUB"},
1367         {0, NULL}
1368 };
1369
1370 static struct xlat sigsegv_flags[] = {
1371         {SEGV_MAPERR, "SEGV_MAPERR"},
1372         {SEGV_ACCERR, "SEGV_ACCERR"},
1373         {0, NULL}
1374 };
1375
1376 static struct xlat sigbus_flags[] = {
1377         {BUS_ADRALN, "BUS_ADRALN"},
1378         {BUS_ADRERR, "BUS_ADRERR"},
1379         {BUS_OBJERR, "BUS_OBJERR"},
1380         {0, NULL}
1381 };
1382
1383 static struct xlat sigtrap_flags[] = {
1384         {TRAP_BRKPT, "TRAP_BRKPT"},
1385         {TRAP_TRACE, "TRAP_TRACE"},
1386         {0, NULL}
1387 };
1388
1389 static struct xlat sigchld_flags[] = {
1390         {CLD_EXITED, "CLD_EXITED"},
1391         {CLD_KILLED, "CLD_KILLED"},
1392         {CLD_DUMPED, "CLD_DUMPED"},
1393         {CLD_TRAPPED, "CLD_TRAPPED"},
1394         {CLD_STOPPED, "CLD_STOPPED"},
1395         {CLD_CONTINUED, "CLD_CONTINUED"},
1396         {0, NULL}
1397 };
1398
1399 static struct xlat sigpoll_flags[] = {
1400         {POLL_IN, "POLL_IN"},
1401         {POLL_OUT, "POLL_OUT"},
1402         {POLL_MSG, "POLL_MSG"},
1403         {POLL_ERR, "POLL_ERR"},
1404         {POLL_PRI, "POLL_PRI"},
1405         {POLL_HUP, "POLL_HUP"},
1406         {0, NULL}
1407 };
1408
1409 static struct xlat siginfo_flags[] = {
1410         {SI_USER, "SI_USER"},
1411         {SI_QUEUE, "SI_QUEUE"},
1412         {SI_TIMER, "SI_TIMER"},
1413         {SI_MESGQ, "SI_MESGQ"},
1414         {SI_ASYNCIO, "SI_ASYNCIO"},
1415         {0, NULL}
1416 };
1417
1418         static void
1419 printsiginfo(tcp, si)
1420         struct tcb *tcp;
1421         siginfo_t *si;
1422 {
1423         tprintf("{si_signo=");
1424         printsignal(si->si_signo);
1425         tprintf(", si_errno=%d, si_code=", si->si_errno);
1426         switch(si->si_signo)
1427         {
1428                 case SIGILL:
1429                         if (!printflags(sigill_flags, si->si_code))
1430                                 tprintf("%d /* ILL_??? */", si->si_code);
1431                         tprintf(", si_addr=%lx",
1432                                         (unsigned long) si->_sifields._sigfault.si_addr);
1433                         break;
1434                 case SIGFPE:
1435                         if (!printflags(sigfpe_flags, si->si_code))
1436                                 tprintf("%d /* FPE_??? */", si->si_code);
1437                         tprintf(", si_addr=%lx",
1438                                         (unsigned long) si->_sifields._sigfault.si_addr);
1439                         break;
1440                 case SIGSEGV:
1441                         if (!printflags(sigsegv_flags, si->si_code))
1442                                 tprintf("%d /* SEGV_??? */", si->si_code);
1443                         tprintf(", si_addr=%lx",
1444                                         (unsigned long) si->_sifields._sigfault.si_addr);
1445                         break;
1446                 case SIGBUS:
1447                         if (!printflags(sigbus_flags, si->si_code))
1448                                 tprintf("%d /* BUS_??? */", si->si_code);
1449                         tprintf(", si_addr=%lx",
1450                                         (unsigned long) si->_sifields._sigfault.si_addr);
1451                         break;
1452                 case SIGTRAP:
1453                         if (!printflags(sigtrap_flags, si->si_code))
1454                                 tprintf("%d /* TRAP_??? */", si->si_code);
1455                         break;
1456                 case SIGCHLD:
1457                         if (!printflags(sigchld_flags, si->si_code))
1458                                 tprintf("%d /* CLD_??? */", si->si_code);
1459                         if (!verbose(tcp))
1460                                 tprintf(", ...");
1461                         else
1462                                 tprintf(", si_pid=%d, si_uid=%d, si_status=%d, si_utime=%lu, si_stime=%lu",
1463                                                 si->_sifields._kill.si_pid,
1464                                                 si->_sifields._kill.si_uid,
1465                                                 si->_sifields._sigchld.si_status,
1466                                                 si->_sifields._sigchld.si_utime,
1467                                                 si->_sifields._sigchld.si_stime);
1468                         break;
1469                 case SIGPOLL:
1470                         if (!printflags(sigpoll_flags, si->si_code))
1471                                 tprintf("%d /* POLL_??? */", si->si_code);
1472                         if (si->si_code == POLL_IN
1473                                         || si->si_code == POLL_OUT
1474                                         || si->si_code == POLL_MSG)
1475                                 tprintf(", si_bind=%lu, si_fd=%d",
1476                                                 (unsigned long) si->_sifields._sigpoll.si_band,
1477                                                 si->_sifields._sigpoll.si_fd);
1478                         break;
1479                 default:
1480                         if (!printflags(siginfo_flags, si->si_code))
1481                                 tprintf("%d /* SI_??? */", si->si_code);
1482                         tprintf(", si_pid=%lu, si_uid=%lu, si_value={",
1483                                         (unsigned long) si->_sifields._rt.si_pid,
1484                                         (unsigned long) si->_sifields._rt.si_uid);
1485                         if (!verbose(tcp))
1486                                 tprintf("...");
1487                         else {
1488                                 tprintf("sival_int=%u, sival_ptr=%#lx",
1489                                                 si->_sifields._rt.si_sigval.sival_int,
1490                                                 (unsigned long) si->_sifields._rt.si_sigval.sival_ptr);
1491                         }
1492                         tprintf("}");
1493                         break;
1494         }
1495         tprintf("}");
1496 }
1497
1498         int
1499 sys_rt_sigqueueinfo(tcp)
1500         struct tcb *tcp;
1501 {
1502         if (entering(tcp)) {
1503                 siginfo_t si;
1504                 tprintf("%lu, ", tcp->u_arg[0]);
1505                 printsignal(tcp->u_arg[1]);
1506                 tprintf(", ");
1507                 if (umove(tcp, tcp->u_arg[2], &si) < 0)
1508                         tprintf("%#lx", tcp->u_arg[2]);
1509                 else
1510                         printsiginfo(&si);
1511         }
1512         return 0;
1513 }
1514
1515 int sys_rt_sigtimedwait(tcp)
1516         struct tcb *tcp;
1517 {
1518         if (entering(tcp)) {
1519                 sigset_t sigset;
1520                 sigemptyset(&sigset);
1521
1522                 if (umoven(tcp, tcp->u_arg[0], tcp->u_arg[3],
1523                                         (char *) &sigset.__val[0]) < 0)
1524                         tprintf("[?]");
1525                 else
1526                         printsigmask(sigset);
1527                 tprintf(", ");
1528         }
1529         else {
1530                 if (syserror(tcp))
1531                         tprintf("%#lx", tcp->u_arg[0]);
1532                 else {
1533                         siginfo_t si;
1534                         if (umove(tcp, tcp->u_arg[1], &si) < 0)
1535                                 tprintf("%#lx", tcp->u_arg[1]);
1536                         else
1537                                 printsiginfo(&si);
1538                         /* XXX For now */
1539                         tprintf(", %#lx", tcp->u_arg[2]);
1540                         tprintf(", %d", (int) tcp->u_arg[3]);
1541                 }
1542         }
1543         return 0;
1544 };
1545
1546 #endif /* LINUX */
1547