blob: edad17fa6595f3633fd5e9c3a4b658836515a719 [file] [log] [blame]
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001/*
2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * $Id$
30 */
31
32#include "defs.h"
33
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000034#include <signal.h>
35#include <sys/user.h>
36#include <fcntl.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000037
38#ifdef SVR4
39#include <sys/ucontext.h>
40#endif /* SVR4 */
41
Wichert Akkerman15dea971999-10-06 13:06:34 +000042#if HAVE_LINUX_PTRACE_H
43#undef PTRACE_SYSCALL
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000044#include <linux/ptrace.h>
Wichert Akkerman36915a11999-07-13 15:45:02 +000045#endif
46
47#ifdef HAVE_SYS_REG_H
48# include <sys/reg.h>
Wichert Akkerman15dea971999-10-06 13:06:34 +000049#ifndef PTRACE_PEEKUSR
Wichert Akkerman36915a11999-07-13 15:45:02 +000050# define PTRACE_PEEKUSR PTRACE_PEEKUSER
Wichert Akkerman15dea971999-10-06 13:06:34 +000051#endif
52#ifndef PTRACE_POKEUSR
Wichert Akkerman36915a11999-07-13 15:45:02 +000053# define PTRACE_POKEUSR PTRACE_POKEUSER
Wichert Akkerman2e2553a1999-05-09 00:29:58 +000054#endif
Wichert Akkerman15dea971999-10-06 13:06:34 +000055#endif
Wichert Akkerman36915a11999-07-13 15:45:02 +000056
57#ifdef LINUX
58
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000059#ifdef HAVE_ASM_SIGCONTEXT_H
60#include <asm/sigcontext.h>
61#ifdef SPARC
Wichert Akkerman9ce1a631999-08-29 23:15:07 +000062#include <asm/reg.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000063typedef struct {
Wichert Akkerman9ce1a631999-08-29 23:15:07 +000064 struct regs si_regs;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000065 int si_mask;
66} m_siginfo_t;
67#endif
68#else /* !HAVE_ASM_SIGCONTEXT_H */
69#ifdef I386
70struct 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
Wichert Akkerman2e2553a1999-05-09 00:29:58 +000096struct sigcontext
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000097{
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
120char *signalent0[] = {
121#include "signalent.h"
122};
123int nsignals0 = sizeof signalent0 / sizeof signalent0[0];
124
125#if SUPPORTED_PERSONALITIES >= 2
126char *signalent1[] = {
127#include "signalent1.h"
128};
129int nsignals1 = sizeof signalent1 / sizeof signalent1[0];
130#endif /* SUPPORTED_PERSONALITIES >= 2 */
131
132#if SUPPORTED_PERSONALITIES >= 3
133char *signalent2[] = {
134#include "signalent2.h"
135};
136int nsignals2 = sizeof signalent2 / sizeof signalent2[0];
137#endif /* SUPPORTED_PERSONALITIES >= 3 */
138
139char **signalent;
140int nsignals;
141
142#ifdef SUNOS4
143
144static 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
156static 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
196static 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
Nate Sammonsce780fc1999-03-29 23:23:13 +0000208/* 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
218char *
219signame(sig)
220int sig;
221{
222 static char buf[30];
223 if (sig < nsignals) {
224 return signalent[sig];
225#ifdef SIGRTMIN
Nate Sammons3080aa41999-03-30 00:16:41 +0000226 } else if (sig >= __SIGRTMIN && sig <= __SIGRTMAX) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000227 sprintf(buf, "SIGRT_%ld", (long)(sig - __SIGRTMIN));
Nate Sammonsce780fc1999-03-29 23:23:13 +0000228 return buf;
229#endif /* SIGRTMIN */
230 } else {
231 sprintf(buf, "%d", sig);
232 return buf;
233 }
234}
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000235
Wichert Akkerman9ce1a631999-08-29 23:15:07 +0000236#ifndef UNIXWARE
Nate Sammons4a121431999-04-06 01:19:39 +0000237static void
238long_to_sigset(l, s)
239long l;
240sigset_t *s;
241{
242 sigemptyset(s);
243 *(long *)s = l;
244}
Wichert Akkerman9ce1a631999-08-29 23:15:07 +0000245#endif
Nate Sammons4a121431999-04-06 01:19:39 +0000246
247static int
248copy_sigset_len(tcp, addr, s, len)
249struct tcb *tcp;
250int addr;
251sigset_t *s;
252int 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
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000269static char *
Nate Sammons4a121431999-04-06 01:19:39 +0000270sprintsigmask(s, mask, rt)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000271char *s;
272sigset_t *mask;
Nate Sammons4a121431999-04-06 01:19:39 +0000273int rt; /* set might include realtime sigs */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000274{
275 int i, nsigs;
Nate Sammons4a121431999-04-06 01:19:39 +0000276 int maxsigs;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000277 char *format;
278 static char outstr[256];
279
280 strcpy(outstr, s);
281 s = outstr + strlen(outstr);
282 nsigs = 0;
Nate Sammons4a121431999-04-06 01:19:39 +0000283 maxsigs = nsignals;
284#ifdef __SIGRTMAX
285 if (rt)
286 maxsigs = __SIGRTMAX; /* instead */
287#endif
288 for (i = 1; i < maxsigs; i++) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000289 if (sigismember(mask, i) == 1)
290 nsigs++;
291 }
292 if (nsigs >= nsignals * 2 / 3) {
293 *s++ = '~';
Nate Sammons4a121431999-04-06 01:19:39 +0000294 for (i = 1; i < maxsigs; i++) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000295 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++ = '[';
Nate Sammons4a121431999-04-06 01:19:39 +0000307 for (i = 1; i < maxsigs; i++) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000308 if (sigismember(mask, i) == 1) {
Nate Sammonsce780fc1999-03-29 23:23:13 +0000309 sprintf(s, format, signame(i) + 3); s += strlen(s);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000310 format = " %s";
311 }
312 }
313 *s++ = ']';
314 *s = '\0';
315 return outstr;
316}
317
318static void
Nate Sammons4a121431999-04-06 01:19:39 +0000319printsigmask(mask, rt)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000320sigset_t *mask;
Nate Sammons4a121431999-04-06 01:19:39 +0000321int rt;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000322{
Nate Sammons4a121431999-04-06 01:19:39 +0000323 tprintf("%s", sprintsigmask("", mask, rt));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000324}
325
326void
327printsignal(nr)
328int nr;
329{
Nate Sammonsce780fc1999-03-29 23:23:13 +0000330 tprintf(signame(nr));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000331}
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 */
338int
339sigishandled(tcp, sig)
340struct tcb *tcp;
341int sig;
342{
343#ifdef LINUX
344 int sfd;
345 char sname[32];
346 char buf[1024];
347 char *s;
348 int i;
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000349 unsigned int signalled, blocked, ignored, caught;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000350
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 }
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000370 if (sscanf(s, "%u%u%u%u",
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000371 &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
424int
425sys_sigvec(tcp)
426struct 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);
Nate Sammons4a121431999-04-06 01:19:39 +0000472 printsigmask(&sv.sv_mask, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000473 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
484int
485sys_sigpause(tcp)
486struct tcb *tcp;
487{
488 if (entering(tcp)) { /* WTA: UD had a bug here: he forgot the braces */
Nate Sammons4a121431999-04-06 01:19:39 +0000489 sigset_t sigm;
490 long_to_sigset(tcp->u_arg[0], &sigm);
491 printsigmask(&sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000492 }
493 return 0;
494}
495
496int
497sys_sigstack(tcp)
498struct 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
520int
521sys_sigcleanup(tcp)
522struct tcb *tcp;
523{
524 return 0;
525}
526
527#endif /* SUNOS4 */
528
529#ifndef SVR4
530
531int
532sys_sigsetmask(tcp)
533struct tcb *tcp;
534{
535 if (entering(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000536 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000537 long_to_sigset(tcp->u_arg[0], &sigm);
538 printsigmask(&sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000539 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)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000547 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000548 long_to_sigset(tcp->u_rval, &sigm);
549 tcp->auxstr = sprintsigmask("old mask ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000550
551 return RVAL_HEX | RVAL_STR;
552 }
553 return 0;
554}
555
556int
557sys_sigblock(tcp)
558struct tcb *tcp;
559{
560 return sys_sigsetmask(tcp);
561}
562
563#endif /* !SVR4 */
564
565#ifdef HAVE_SIGACTION
566
567#ifdef LINUX
568struct old_sigaction {
569 __sighandler_t __sa_handler;
570 unsigned long sa_mask;
571 unsigned long sa_flags;
572 void (*sa_restorer)(void);
573};
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000574#define SA_HANDLER __sa_handler
575#endif /* LINUX */
576
577#ifndef SA_HANDLER
578#define SA_HANDLER sa_handler
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000579#endif
580
581int
582sys_sigaction(tcp)
583struct tcb *tcp;
584{
585 long addr;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000586 sigset_t sigset;
Nate Sammons4a121431999-04-06 01:19:39 +0000587#ifdef LINUX
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000588 struct old_sigaction sa;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000589#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 {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000607 switch ((long) sa.SA_HANDLER) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000608 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 */
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000630 tprintf("{%#lx, ", (long) sa.SA_HANDLER);
Wichert Akkerman48214be1999-11-26 09:55:42 +0000631#ifndef LINUX
632 printsigmask (&sa.sa_mask, 0);
633#else
Nate Sammons4a121431999-04-06 01:19:39 +0000634 long_to_sigset(sa.sa_mask, &sigset);
635 printsigmask(&sigset, 0);
Wichert Akkerman48214be1999-11-26 09:55:42 +0000636#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000637 tprintf(", ");
638 if (!printflags(sigact_flags, sa.sa_flags))
639 tprintf("0");
640 tprintf("}");
641 }
642 }
643 if (entering(tcp))
644 tprintf(", ");
645#ifdef LINUX
646 else
647 tprintf(", %#lx", (unsigned long) sa.sa_restorer);
648#endif
649 return 0;
650}
651
652int
653sys_signal(tcp)
654struct tcb *tcp;
655{
656 if (entering(tcp)) {
657 printsignal(tcp->u_arg[0]);
658 switch (tcp->u_arg[1]) {
659 case (int) SIG_ERR:
660 tprintf("SIG_ERR");
661 break;
662 case (int) SIG_DFL:
663 tprintf("SIG_DFL");
664 break;
665 case (int) SIG_IGN:
666#ifndef SVR4
667 if (tcp->u_arg[0] == SIGTRAP) {
668 tcp->flags |= TCB_SIGTRAPPED;
669 kill(tcp->pid, SIGSTOP);
670 }
671#endif /* !SVR4 */
672 tprintf("SIG_IGN");
673 break;
674 default:
675#ifndef SVR4
676 if (tcp->u_arg[0] == SIGTRAP) {
677 tcp->flags |= TCB_SIGTRAPPED;
678 kill(tcp->pid, SIGSTOP);
679 }
680#endif /* !SVR4 */
681 tprintf("%#lx", tcp->u_arg[1]);
682 }
683 }
684 return 0;
685}
686
687#endif /* HAVE_SIGACTION */
688
689#ifdef LINUX
690
691int
692sys_sigreturn(tcp)
693struct tcb *tcp;
694{
695#ifdef I386
696 long esp;
697 struct sigcontext_struct sc;
698
699 if (entering(tcp)) {
700 tcp->u_arg[0] = 0;
701 if (upeek(tcp->pid, 4*UESP, &esp) < 0)
702 return 0;
703 if (umove(tcp, esp, &sc) < 0)
704 return 0;
705 tcp->u_arg[0] = 1;
706 tcp->u_arg[1] = sc.oldmask;
707 }
708 else {
709 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000710 long_to_sigset(tcp->u_arg[1], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000711 tcp->u_rval = tcp->u_error = 0;
712 if (tcp->u_arg[0] == 0)
713 return 0;
Nate Sammons4a121431999-04-06 01:19:39 +0000714 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000715 return RVAL_NONE | RVAL_STR;
716 }
717 return 0;
718#else /* !I386 */
719#ifdef POWERPC
720 long esp;
721 struct sigcontext_struct sc;
722
723 if (entering(tcp)) {
724 tcp->u_arg[0] = 0;
725 if (upeek(tcp->pid, 4*PT_R1, &esp) < 0)
726 return 0;
727 if (umove(tcp, esp, &sc) < 0)
728 return 0;
729 tcp->u_arg[0] = 1;
730 tcp->u_arg[1] = sc.oldmask;
731 }
732 else {
733 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000734 long_to_sigset(tcp->u_arg[1], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000735 tcp->u_rval = tcp->u_error = 0;
736 if (tcp->u_arg[0] == 0)
737 return 0;
Nate Sammons4a121431999-04-06 01:19:39 +0000738 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000739 return RVAL_NONE | RVAL_STR;
740 }
741 return 0;
742#else /* !POWERPC */
743#ifdef M68K
744 long usp;
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000745 struct sigcontext sc;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000746
747 if (entering(tcp)) {
748 tcp->u_arg[0] = 0;
749 if (upeek(tcp->pid, 4*PT_USP, &usp) < 0)
750 return 0;
751 if (umove(tcp, usp, &sc) < 0)
752 return 0;
753 tcp->u_arg[0] = 1;
754 tcp->u_arg[1] = sc.sc_mask;
755 }
756 else {
757 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000758 long_to_sigset(tcp->u_arg[1], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000759 tcp->u_rval = tcp->u_error = 0;
760 if (tcp->u_arg[0] == 0)
761 return 0;
Nate Sammons4a121431999-04-06 01:19:39 +0000762 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000763 return RVAL_NONE | RVAL_STR;
764 }
765 return 0;
766#else /* !M68K */
767#ifdef ALPHA
768 long fp;
769 struct sigcontext_struct sc;
770
771 if (entering(tcp)) {
772 tcp->u_arg[0] = 0;
773 if (upeek(tcp->pid, REG_FP, &fp) < 0)
774 return 0;
775 if (umove(tcp, fp, &sc) < 0)
776 return 0;
777 tcp->u_arg[0] = 1;
778 tcp->u_arg[1] = sc.sc_mask;
779 }
780 else {
781 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000782 long_to_sigset(tcp->u_arg[1], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000783 tcp->u_rval = tcp->u_error = 0;
784 if (tcp->u_arg[0] == 0)
785 return 0;
Nate Sammons4a121431999-04-06 01:19:39 +0000786 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000787 return RVAL_NONE | RVAL_STR;
788 }
789 return 0;
790#else
791#ifdef SPARC
792 long i1;
Wichert Akkerman9ce1a631999-08-29 23:15:07 +0000793 struct regs regs;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000794 m_siginfo_t si;
795
796 if(ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
797 perror("sigreturn: PTRACE_GETREGS ");
798 return 0;
799 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000800 if(entering(tcp)) {
801 tcp->u_arg[0] = 0;
Wichert Akkerman9ce1a631999-08-29 23:15:07 +0000802 i1 = regs.r_o1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000803 if(umove(tcp, i1, &si) < 0) {
804 perror("sigreturn: umove ");
805 return 0;
806 }
807 tcp->u_arg[0] = 1;
808 tcp->u_arg[1] = si.si_mask;
809 } else {
810 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000811 long_to_sigset(tcp->u_arg[1], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000812 tcp->u_rval = tcp->u_error = 0;
813 if(tcp->u_arg[0] == 0)
814 return 0;
Nate Sammons4a121431999-04-06 01:19:39 +0000815 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000816 return RVAL_NONE | RVAL_STR;
817 }
818 return 0;
Wichert Akkermanf90da011999-10-31 21:15:38 +0000819#else
820#ifdef MIPS
821 long sp;
822 struct sigcontext sc;
823
824 if(entering(tcp)) {
825 tcp->u_arg[0] = 0;
826 if (upeek(tcp->pid, REG_SP, &sp) < 0)
827 return 0;
828 if (umove(tcp, sp, &sc) < 0)
829 return 0;
830 tcp->u_arg[0] = 1;
831 tcp->u_arg[1] = sc.sc_sigset;
832 } else {
833 tcp->u_rval = tcp->u_error = 0;
834 if(tcp->u_arg[0] == 0)
835 return 0;
836 tcp->auxstr = sprintsigmask("mask now ", tcp->u_arg[1]);
837 return RVAL_NONE | RVAL_STR;
838 }
839 return 0;
840#endif /* MIPS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000841#endif /* SPARC */
842#endif /* ALPHA */
843#endif /* !M68K */
844#endif /* !POWERPC */
845#endif /* !I386 */
846}
847
848int
849sys_siggetmask(tcp)
850struct tcb *tcp;
851{
852 if (exiting(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000853 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000854 long_to_sigset(tcp->u_rval, &sigm);
855 tcp->auxstr = sprintsigmask("mask ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000856 }
857 return RVAL_HEX | RVAL_STR;
858}
859
860int
861sys_sigsuspend(tcp)
862struct tcb *tcp;
863{
864 if (entering(tcp)) {
865 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000866 long_to_sigset(tcp->u_arg[2], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000867#if 0
868 /* first two are not really arguments, but print them anyway */
869 /* nevermind, they are an anachronism now, too bad... */
870 tprintf("%d, %#x, ", tcp->u_arg[0], tcp->u_arg[1]);
871#endif
Nate Sammons4a121431999-04-06 01:19:39 +0000872 printsigmask(&sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000873 }
874 return 0;
875}
876
877#endif /* LINUX */
878
879#ifdef SVR4
880
881int
882sys_sigsuspend(tcp)
883struct tcb *tcp;
884{
885 sigset_t sigset;
886
887 if (entering(tcp)) {
888 if (umove(tcp, tcp->u_arg[0], &sigset) < 0)
889 tprintf("[?]");
890 else
Wichert Akkerman46956571999-11-26 10:12:59 +0000891 printsigmask(&sigset, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000892 }
893 return 0;
894}
895static struct xlat ucontext_flags[] = {
896 { UC_SIGMASK, "UC_SIGMASK" },
897 { UC_STACK, "UC_STACK" },
898 { UC_CPU, "UC_CPU" },
899#ifdef UC_FPU
900 { UC_FPU, "UC_FPU" },
901#endif
902#ifdef UC_INTR
903 { UC_INTR, "UC_INTR" },
904#endif
905 { 0, NULL },
906};
907
908#endif
909
910#if defined SVR4 || defined LINUX
911#if defined LINUX && !defined SS_ONSTACK
912#define SS_ONSTACK 1
913#define SS_DISABLE 2
914#if __GLIBC_MINOR__ == 0
915typedef struct
916{
917 __ptr_t ss_sp;
918 int ss_flags;
919 size_t ss_size;
920} stack_t;
921#endif
922#endif
923
924static struct xlat sigaltstack_flags[] = {
925 { SS_ONSTACK, "SS_ONSTACK" },
926 { SS_DISABLE, "SS_DISABLE" },
927 { 0, NULL },
928};
929#endif
930
931#ifdef SVR4
932static void
933printcontext(tcp, ucp)
934struct tcb *tcp;
935ucontext_t *ucp;
936{
937 tprintf("{");
938 if (!abbrev(tcp)) {
939 tprintf("uc_flags=");
940 if (!printflags(ucontext_flags, ucp->uc_flags))
941 tprintf("0");
942 tprintf(", uc_link=%#lx, ", (unsigned long) ucp->uc_link);
943 }
944 tprintf("uc_sigmask=");
Nate Sammons4a121431999-04-06 01:19:39 +0000945 printsigmask(ucp->uc_sigmask, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000946 if (!abbrev(tcp)) {
947 tprintf(", uc_stack={ss_sp=%#lx, ss_size=%d, ss_flags=",
948 (unsigned long) ucp->uc_stack.ss_sp,
949 ucp->uc_stack.ss_size);
950 if (!printflags(sigaltstack_flags, ucp->uc_stack.ss_flags))
951 tprintf("0");
952 tprintf("}");
953 }
954 tprintf(", ...}");
955}
956
957int
958sys_getcontext(tcp)
959struct tcb *tcp;
960{
961 ucontext_t uc;
962
963 if (entering(tcp)) {
964 if (!tcp->u_arg[0])
965 tprintf("NULL");
966 else if (umove(tcp, tcp->u_arg[0], &uc) < 0)
967 tprintf("{...}");
968 else
969 printcontext(tcp, &uc);
970 }
971 return 0;
972}
973
974int
975sys_setcontext(tcp)
976struct tcb *tcp;
977{
978 ucontext_t uc;
979
980 if (entering(tcp)) {
981 if (!tcp->u_arg[0])
982 tprintf("NULL");
983 else if (umove(tcp, tcp->u_arg[0], &uc) < 0)
984 tprintf("{...}");
985 else
986 printcontext(tcp, &uc);
987 }
988 else {
989 tcp->u_rval = tcp->u_error = 0;
990 if (tcp->u_arg[0] == 0)
991 return 0;
992 return RVAL_NONE;
993 }
994 return 0;
995}
996
997#endif /* SVR4 */
998
999#ifdef LINUX
1000
1001static int
1002print_stack_t(tcp, addr)
1003struct tcb *tcp;
1004unsigned long addr;
1005{
1006 stack_t ss;
1007 if (umove(tcp, addr, &ss) < 0)
1008 return -1;
1009 tprintf("{ss_sp=%#lx, ss_flags=", (unsigned long) ss.ss_sp);
1010 if (!printflags(sigaltstack_flags, ss.ss_flags))
1011 tprintf("0");
1012 tprintf(", ss_size=%lu}", (unsigned long) ss.ss_size);
1013 return 0;
1014}
1015
1016int
1017sys_sigaltstack(tcp)
1018 struct tcb *tcp;
1019{
1020 if (entering(tcp)) {
1021 if (tcp->u_arg[0] == 0)
1022 tprintf("NULL");
1023 else if (print_stack_t(tcp, tcp->u_arg[0]) < 0)
1024 return -1;
1025 }
1026 else {
1027 tprintf(", ");
1028 if (tcp->u_arg[1] == 0)
1029 tprintf("NULL");
1030 else if (print_stack_t(tcp, tcp->u_arg[1]) < 0)
1031 return -1;
1032 }
1033 return 0;
1034}
1035#endif
1036
1037#ifdef HAVE_SIGACTION
1038
1039int
1040sys_sigprocmask(tcp)
1041struct tcb *tcp;
1042{
1043#ifdef ALPHA
1044 if (entering(tcp)) {
1045 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1046 tprintf(", ");
Nate Sammons4a121431999-04-06 01:19:39 +00001047 printsigmask(tcp->u_arg[1], 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001048 }
1049 else if (!syserror(tcp)) {
Nate Sammons4a121431999-04-06 01:19:39 +00001050 tcp->auxstr = sprintsigmask("old mask ", tcp->u_rval, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001051 return RVAL_HEX | RVAL_STR;
1052 }
1053#else /* !ALPHA */
1054 sigset_t sigset;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001055
1056 if (entering(tcp)) {
1057#ifdef SVR4
1058 if (tcp->u_arg[0] == 0)
1059 tprintf("0");
1060 else
1061#endif /* SVR4 */
1062 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1063 tprintf(", ");
1064 if (!tcp->u_arg[1])
1065 tprintf("NULL, ");
Nate Sammons4a121431999-04-06 01:19:39 +00001066 else if (copy_sigset(tcp, tcp->u_arg[1], &sigset) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001067 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001068 else {
Nate Sammons4a121431999-04-06 01:19:39 +00001069 printsigmask(&sigset, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001070 tprintf(", ");
1071 }
1072 }
1073 else {
1074 if (!tcp->u_arg[2])
1075 tprintf("NULL");
1076 else if (syserror(tcp))
1077 tprintf("%#lx", tcp->u_arg[2]);
Nate Sammons4a121431999-04-06 01:19:39 +00001078 else if (copy_sigset(tcp, tcp->u_arg[2], &sigset) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001079 tprintf("[?]");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001080 else
Nate Sammons4a121431999-04-06 01:19:39 +00001081 printsigmask(&sigset, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001082 }
1083#endif /* !ALPHA */
1084 return 0;
1085}
1086
1087#endif /* HAVE_SIGACTION */
1088
1089int
1090sys_kill(tcp)
1091struct tcb *tcp;
1092{
1093 if (entering(tcp)) {
Nate Sammonsce780fc1999-03-29 23:23:13 +00001094 tprintf("%ld, %s", tcp->u_arg[0], signame(tcp->u_arg[1]));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001095 }
1096 return 0;
1097}
1098
1099int
1100sys_killpg(tcp)
1101struct tcb *tcp;
1102{
1103 return sys_kill(tcp);
1104}
1105
1106int
1107sys_sigpending(tcp)
1108struct tcb *tcp;
1109{
1110 sigset_t sigset;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001111
1112 if (exiting(tcp)) {
1113 if (syserror(tcp))
1114 tprintf("%#lx", tcp->u_arg[0]);
Nate Sammons4a121431999-04-06 01:19:39 +00001115 else if (copy_sigset(tcp, tcp->u_arg[0], &sigset) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001116 tprintf("[?]");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001117 else
Wichert Akkerman46956571999-11-26 10:12:59 +00001118 printsigmask(&sigset, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001119 }
1120 return 0;
1121}
1122
1123#ifdef LINUX
1124
1125 int
1126sys_rt_sigprocmask(tcp)
1127 struct tcb *tcp;
1128{
1129 sigset_t sigset;
1130
Nate Sammons4a121431999-04-06 01:19:39 +00001131 /* Note: arg[3] is the length of the sigset. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001132 if (entering(tcp)) {
1133 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1134 tprintf(", ");
1135 if (!tcp->u_arg[1])
1136 tprintf("NULL, ");
Nate Sammons4a121431999-04-06 01:19:39 +00001137 else if (copy_sigset_len(tcp, tcp->u_arg[1], &sigset, tcp->u_arg[3]) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001138 tprintf("%#lx, ", tcp->u_arg[1]);
1139 else {
Nate Sammons4a121431999-04-06 01:19:39 +00001140 printsigmask(&sigset, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001141 tprintf(", ");
1142 }
1143 }
1144 else {
1145 if (!tcp->u_arg[2])
1146
1147 tprintf("NULL");
1148 else if (syserror(tcp))
1149 tprintf("%#lx", tcp->u_arg[2]);
Nate Sammons4a121431999-04-06 01:19:39 +00001150 else if (copy_sigset_len(tcp, tcp->u_arg[2], &sigset, tcp->u_arg[3]) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001151 tprintf("[?]");
1152 else
Nate Sammons4a121431999-04-06 01:19:39 +00001153 printsigmask(&sigset, 1);
Nate Sammonsdab325a1999-03-29 23:33:35 +00001154 tprintf(", %lu", tcp->u_arg[3]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001155 }
1156 return 0;
1157}
1158
1159#if __GLIBC_MINOR__ < 1
1160/* Type for data associated with a signal. */
1161typedef union sigval
1162{
1163 int sival_int;
1164 void *sival_ptr;
1165} sigval_t;
1166
1167# define __SI_MAX_SIZE 128
1168# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 3)
1169
1170typedef struct siginfo
1171{
1172 int si_signo; /* Signal number. */
1173 int si_errno; /* If non-zero, an errno value associated with
1174 this signal, as defined in <errno.h>. */
1175 int si_code; /* Signal code. */
1176
1177 union
1178 {
1179 int _pad[__SI_PAD_SIZE];
1180
1181 /* kill(). */
1182 struct
1183 {
1184 __pid_t si_pid; /* Sending process ID. */
1185 __uid_t si_uid; /* Real user ID of sending process. */
1186 } _kill;
1187
1188 /* POSIX.1b timers. */
1189 struct
1190 {
1191 unsigned int _timer1;
1192 unsigned int _timer2;
1193 } _timer;
1194
1195 /* POSIX.1b signals. */
1196 struct
1197 {
1198 __pid_t si_pid; /* Sending process ID. */
1199 __uid_t si_uid; /* Real user ID of sending process. */
1200 sigval_t si_sigval; /* Signal value. */
1201 } _rt;
1202
1203 /* SIGCHLD. */
1204 struct
1205 {
1206 __pid_t si_pid; /* Which child. */
1207 int si_status; /* Exit value or signal. */
1208 __clock_t si_utime;
1209 __clock_t si_stime;
1210 } _sigchld;
1211
1212 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS. */
1213 struct
1214 {
1215 void *si_addr; /* Faulting insn/memory ref. */
1216 } _sigfault;
1217
1218 /* SIGPOLL. */
1219 struct
1220 {
1221 int si_band; /* Band event for SIGPOLL. */
1222 int si_fd;
1223 } _sigpoll;
1224 } _sifields;
1225} siginfo_t;
1226#endif
1227
1228/* Structure describing the action to be taken when a signal arrives. */
1229struct new_sigaction
1230{
1231 union
1232 {
1233 __sighandler_t __sa_handler;
1234 void (*__sa_sigaction) (int, siginfo_t *, void *);
1235 }
1236 __sigaction_handler;
1237 unsigned long sa_flags;
1238 void (*sa_restorer) (void);
1239 unsigned long int sa_mask[2];
1240};
1241
1242
1243 int
1244sys_rt_sigaction(tcp)
1245 struct tcb *tcp;
1246{
1247 struct new_sigaction sa;
1248 sigset_t sigset;
1249 long addr;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001250
1251 if (entering(tcp)) {
1252 printsignal(tcp->u_arg[0]);
1253 tprintf(", ");
1254 addr = tcp->u_arg[1];
1255 } else
1256 addr = tcp->u_arg[2];
1257 if (addr == 0)
1258 tprintf("NULL");
1259 else if (!verbose(tcp))
1260 tprintf("%#lx", addr);
1261 else if (umove(tcp, addr, &sa) < 0)
1262 tprintf("{...}");
1263 else {
1264 switch ((long) sa.__sigaction_handler.__sa_handler) {
1265 case (long) SIG_ERR:
1266 tprintf("{SIG_ERR}");
1267 break;
1268 case (long) SIG_DFL:
1269 tprintf("{SIG_DFL}");
1270 break;
1271 case (long) SIG_IGN:
1272 tprintf("{SIG_IGN}");
1273 break;
1274 default:
1275 tprintf("{%#lx, ",
1276 (long) sa.__sigaction_handler.__sa_handler);
Nate Sammons4a121431999-04-06 01:19:39 +00001277 sigemptyset(&sigset);
Wichert Akkermandacfb6e1999-06-03 14:21:07 +00001278#ifdef LINUXSPARC
1279 if (tcp->u_arg[4] <= sizeof(sigset))
1280 memcpy(&sigset, &sa.sa_mask, tcp->u_arg[4]);
1281#else
Nate Sammons4a121431999-04-06 01:19:39 +00001282 if (tcp->u_arg[3] <= sizeof(sigset))
1283 memcpy(&sigset, &sa.sa_mask, tcp->u_arg[3]);
Wichert Akkermandacfb6e1999-06-03 14:21:07 +00001284#endif
Nate Sammons4a121431999-04-06 01:19:39 +00001285 else
1286 memcpy(&sigset, &sa.sa_mask, sizeof(sigset));
1287 printsigmask(&sigset, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001288 tprintf(", ");
1289 if (!printflags(sigact_flags, sa.sa_flags))
1290 tprintf("0");
1291 tprintf("}");
1292 }
1293 }
1294 if (entering(tcp))
1295 tprintf(", ");
1296 else
Wichert Akkermandacfb6e1999-06-03 14:21:07 +00001297#ifdef LINUXSPARC
1298 tprintf(", %#lx, %lu", tcp->u_arg[3], tcp->u_arg[4]);
1299#elif defined(ALPHA)
1300 tprintf(", %lu, %#lx", tcp->u_arg[3], tcp->u_arg[4]);
1301#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001302 tprintf(", %lu", addr = tcp->u_arg[3]);
Wichert Akkermandacfb6e1999-06-03 14:21:07 +00001303#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001304 return 0;
1305}
1306
1307 int
1308sys_rt_sigpending(tcp)
1309 struct tcb *tcp;
1310{
1311 sigset_t sigset;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001312
1313 if (exiting(tcp)) {
1314 if (syserror(tcp))
1315 tprintf("%#lx", tcp->u_arg[0]);
Nate Sammons4a121431999-04-06 01:19:39 +00001316 else if (copy_sigset_len(tcp, tcp->u_arg[0],
1317 &sigset, tcp->u_arg[1]) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001318 tprintf("[?]");
1319 else
Wichert Akkerman46956571999-11-26 10:12:59 +00001320 printsigmask(&sigset, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001321 }
1322 return 0;
1323}
1324 int
1325sys_rt_sigsuspend(tcp)
1326 struct tcb *tcp;
1327{
1328 if (entering(tcp)) {
1329 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +00001330 if (copy_sigset_len(tcp, tcp->u_arg[0], &sigm, tcp->u_arg[1]) < 0)
1331 tprintf("[?]");
1332 else
1333 printsigmask(&sigm, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001334 }
1335 return 0;
1336}
1337#ifndef ILL_ILLOPC
1338#define ILL_ILLOPC 1 /* illegal opcode */
1339#define ILL_ILLOPN 2 /* illegal operand */
1340#define ILL_ILLADR 3 /* illegal addressing mode */
1341#define ILL_ILLTRP 4 /* illegal trap */
1342#define ILL_PRVOPC 5 /* privileged opcode */
1343#define ILL_PRVREG 6 /* privileged register */
1344#define ILL_COPROC 7 /* coprocessor error */
1345#define ILL_BADSTK 8 /* internal stack error */
1346#define FPE_INTDIV 1 /* integer divide by zero */
1347#define FPE_INTOVF 2 /* integer overflow */
1348#define FPE_FLTDIV 3 /* floating point divide by zero */
1349#define FPE_FLTOVF 4 /* floating point overflow */
1350#define FPE_FLTUND 5 /* floating point underflow */
1351#define FPE_FLTRES 6 /* floating point inexact result */
1352#define FPE_FLTINV 7 /* floating point invalid operation */
1353#define FPE_FLTSUB 8 /* subscript out of range */
1354#define SEGV_MAPERR 1 /* address not mapped to object */
1355#define SEGV_ACCERR 2 /* invalid permissions for mapped object */
1356#define BUS_ADRALN 1 /* invalid address alignment */
1357#define BUS_ADRERR 2 /* non-existant physical address */
1358#define BUS_OBJERR 3 /* object specific hardware error */
1359#define TRAP_BRKPT 1 /* process breakpoint */
1360#define TRAP_TRACE 2 /* process trace trap */
1361#define CLD_EXITED 1 /* child has exited */
1362#define CLD_KILLED 2 /* child was killed */
1363#define CLD_DUMPED 3 /* child terminated abnormally */
1364#define CLD_TRAPPED 4 /* traced child has trapped */
1365#define CLD_STOPPED 5 /* child has stopped */
1366#define CLD_CONTINUED 6 /* stopped child has continued */
1367#define POLL_IN 1 /* data input available */
1368#define POLL_OUT 2 /* output buffers available */
1369#define POLL_MSG 3 /* input message available */
1370#define POLL_ERR 4 /* i/o error */
1371#define POLL_PRI 5 /* high priority input available */
1372#define POLL_HUP 6 /* device disconnected */
1373#define SI_USER 0 /* sent by kill, sigsend, raise */
1374#define SI_QUEUE -1 /* sent by sigqueue */
1375#define SI_TIMER -2 /* sent by timer expiration */
1376#define SI_MESGQ -3 /* sent by real time mesq state change */
1377#define SI_ASYNCIO -4 /* sent by AIO completion */
1378#else
1379#undef si_pid
1380#undef si_uid
1381#undef si_status
1382#undef si_utime
1383#undef si_stime
1384#undef si_value
1385#undef si_int
1386#undef si_ptr
1387#undef si_addr
1388#undef si_band
1389#undef si_fd
1390#endif
1391
1392static struct xlat sigill_flags[] = {
1393 {ILL_ILLOPC, "ILL_ILLOPC"},
1394 {ILL_ILLOPN, "ILL_ILLOPN"},
1395 {ILL_ILLADR, "ILL_ILLADR"},
1396 {ILL_ILLTRP, "ILL_ILLTRP"},
1397 {ILL_PRVOPC, "ILL_PRVOPC"},
1398 {ILL_PRVREG, "ILL_PRVREG"},
1399 {ILL_COPROC, "ILL_COPROC"},
1400 {ILL_BADSTK, "ILL_BADSTK"},
1401 {0, NULL}
1402};
1403
1404static struct xlat sigfpe_flags[] = {
1405 {FPE_INTDIV, "FPE_INTDIV"},
1406 {FPE_INTOVF, "FPE_INTOVF"},
1407 {FPE_FLTDIV, "FPE_FLTDIV"},
1408 {FPE_FLTOVF, "FPE_FLTOVF"},
1409 {FPE_FLTUND, "FPE_FLTUND"},
1410 {FPE_FLTRES, "FPE_FLTRES"},
1411 {FPE_FLTINV, "FPE_FLTINV"},
1412 {FPE_FLTSUB, "FPE_FLTSUB"},
1413 {0, NULL}
1414};
1415
1416static struct xlat sigsegv_flags[] = {
1417 {SEGV_MAPERR, "SEGV_MAPERR"},
1418 {SEGV_ACCERR, "SEGV_ACCERR"},
1419 {0, NULL}
1420};
1421
1422static struct xlat sigbus_flags[] = {
1423 {BUS_ADRALN, "BUS_ADRALN"},
1424 {BUS_ADRERR, "BUS_ADRERR"},
1425 {BUS_OBJERR, "BUS_OBJERR"},
1426 {0, NULL}
1427};
1428
1429static struct xlat sigtrap_flags[] = {
1430 {TRAP_BRKPT, "TRAP_BRKPT"},
1431 {TRAP_TRACE, "TRAP_TRACE"},
1432 {0, NULL}
1433};
1434
1435static struct xlat sigchld_flags[] = {
1436 {CLD_EXITED, "CLD_EXITED"},
1437 {CLD_KILLED, "CLD_KILLED"},
1438 {CLD_DUMPED, "CLD_DUMPED"},
1439 {CLD_TRAPPED, "CLD_TRAPPED"},
1440 {CLD_STOPPED, "CLD_STOPPED"},
1441 {CLD_CONTINUED, "CLD_CONTINUED"},
1442 {0, NULL}
1443};
1444
1445static struct xlat sigpoll_flags[] = {
1446 {POLL_IN, "POLL_IN"},
1447 {POLL_OUT, "POLL_OUT"},
1448 {POLL_MSG, "POLL_MSG"},
1449 {POLL_ERR, "POLL_ERR"},
1450 {POLL_PRI, "POLL_PRI"},
1451 {POLL_HUP, "POLL_HUP"},
1452 {0, NULL}
1453};
1454
1455static struct xlat siginfo_flags[] = {
1456 {SI_USER, "SI_USER"},
1457 {SI_QUEUE, "SI_QUEUE"},
1458 {SI_TIMER, "SI_TIMER"},
1459 {SI_MESGQ, "SI_MESGQ"},
1460 {SI_ASYNCIO, "SI_ASYNCIO"},
1461 {0, NULL}
1462};
1463
1464 static void
1465printsiginfo(tcp, si)
1466 struct tcb *tcp;
1467 siginfo_t *si;
1468{
1469 tprintf("{si_signo=");
1470 printsignal(si->si_signo);
1471 tprintf(", si_errno=%d, si_code=", si->si_errno);
1472 switch(si->si_signo)
1473 {
1474 case SIGILL:
1475 if (!printflags(sigill_flags, si->si_code))
1476 tprintf("%d /* ILL_??? */", si->si_code);
1477 tprintf(", si_addr=%lx",
1478 (unsigned long) si->_sifields._sigfault.si_addr);
1479 break;
1480 case SIGFPE:
1481 if (!printflags(sigfpe_flags, si->si_code))
1482 tprintf("%d /* FPE_??? */", si->si_code);
1483 tprintf(", si_addr=%lx",
1484 (unsigned long) si->_sifields._sigfault.si_addr);
1485 break;
1486 case SIGSEGV:
1487 if (!printflags(sigsegv_flags, si->si_code))
1488 tprintf("%d /* SEGV_??? */", si->si_code);
1489 tprintf(", si_addr=%lx",
1490 (unsigned long) si->_sifields._sigfault.si_addr);
1491 break;
1492 case SIGBUS:
1493 if (!printflags(sigbus_flags, si->si_code))
1494 tprintf("%d /* BUS_??? */", si->si_code);
1495 tprintf(", si_addr=%lx",
1496 (unsigned long) si->_sifields._sigfault.si_addr);
1497 break;
1498 case SIGTRAP:
1499 if (!printflags(sigtrap_flags, si->si_code))
1500 tprintf("%d /* TRAP_??? */", si->si_code);
1501 break;
1502 case SIGCHLD:
1503 if (!printflags(sigchld_flags, si->si_code))
1504 tprintf("%d /* CLD_??? */", si->si_code);
1505 if (!verbose(tcp))
1506 tprintf(", ...");
1507 else
1508 tprintf(", si_pid=%d, si_uid=%d, si_status=%d, si_utime=%lu, si_stime=%lu",
1509 si->_sifields._kill.si_pid,
1510 si->_sifields._kill.si_uid,
1511 si->_sifields._sigchld.si_status,
1512 si->_sifields._sigchld.si_utime,
1513 si->_sifields._sigchld.si_stime);
1514 break;
1515 case SIGPOLL:
1516 if (!printflags(sigpoll_flags, si->si_code))
1517 tprintf("%d /* POLL_??? */", si->si_code);
1518 if (si->si_code == POLL_IN
1519 || si->si_code == POLL_OUT
1520 || si->si_code == POLL_MSG)
1521 tprintf(", si_bind=%lu, si_fd=%d",
1522 (unsigned long) si->_sifields._sigpoll.si_band,
1523 si->_sifields._sigpoll.si_fd);
1524 break;
1525 default:
1526 if (!printflags(siginfo_flags, si->si_code))
1527 tprintf("%d /* SI_??? */", si->si_code);
1528 tprintf(", si_pid=%lu, si_uid=%lu, si_value={",
1529 (unsigned long) si->_sifields._rt.si_pid,
1530 (unsigned long) si->_sifields._rt.si_uid);
1531 if (!verbose(tcp))
1532 tprintf("...");
1533 else {
1534 tprintf("sival_int=%u, sival_ptr=%#lx",
1535 si->_sifields._rt.si_sigval.sival_int,
1536 (unsigned long) si->_sifields._rt.si_sigval.sival_ptr);
1537 }
1538 tprintf("}");
1539 break;
1540 }
1541 tprintf("}");
1542}
1543
1544 int
1545sys_rt_sigqueueinfo(tcp)
1546 struct tcb *tcp;
1547{
1548 if (entering(tcp)) {
1549 siginfo_t si;
1550 tprintf("%lu, ", tcp->u_arg[0]);
1551 printsignal(tcp->u_arg[1]);
1552 tprintf(", ");
1553 if (umove(tcp, tcp->u_arg[2], &si) < 0)
1554 tprintf("%#lx", tcp->u_arg[2]);
1555 else
1556 printsiginfo(&si);
1557 }
1558 return 0;
1559}
1560
1561int sys_rt_sigtimedwait(tcp)
1562 struct tcb *tcp;
1563{
1564 if (entering(tcp)) {
1565 sigset_t sigset;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001566
Nate Sammons4a121431999-04-06 01:19:39 +00001567 if (copy_sigset_len(tcp, tcp->u_arg[0],
1568 &sigset, tcp->u_arg[3]) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001569 tprintf("[?]");
1570 else
Wichert Akkerman46956571999-11-26 10:12:59 +00001571 printsigmask(&sigset, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001572 tprintf(", ");
1573 }
1574 else {
1575 if (syserror(tcp))
1576 tprintf("%#lx", tcp->u_arg[0]);
1577 else {
1578 siginfo_t si;
1579 if (umove(tcp, tcp->u_arg[1], &si) < 0)
1580 tprintf("%#lx", tcp->u_arg[1]);
1581 else
1582 printsiginfo(&si);
1583 /* XXX For now */
1584 tprintf(", %#lx", tcp->u_arg[2]);
1585 tprintf(", %d", (int) tcp->u_arg[3]);
1586 }
1587 }
1588 return 0;
1589};
1590
1591#endif /* LINUX */
1592