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