blob: f0b95466c873842930f197d8b8859be0c32e1ea5 [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);
Nate Sammons4a121431999-04-06 01:19:39 +0000631 long_to_sigset(sa.sa_mask, &sigset);
632 printsigmask(&sigset, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000633 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
648int
649sys_signal(tcp)
650struct 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
687int
688sys_sigreturn(tcp)
689struct 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;
Nate Sammons4a121431999-04-06 01:19:39 +0000706 long_to_sigset(tcp->u_arg[1], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000707 tcp->u_rval = tcp->u_error = 0;
708 if (tcp->u_arg[0] == 0)
709 return 0;
Nate Sammons4a121431999-04-06 01:19:39 +0000710 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000711 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;
Nate Sammons4a121431999-04-06 01:19:39 +0000730 long_to_sigset(tcp->u_arg[1], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000731 tcp->u_rval = tcp->u_error = 0;
732 if (tcp->u_arg[0] == 0)
733 return 0;
Nate Sammons4a121431999-04-06 01:19:39 +0000734 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000735 return RVAL_NONE | RVAL_STR;
736 }
737 return 0;
738#else /* !POWERPC */
739#ifdef M68K
740 long usp;
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000741 struct sigcontext sc;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000742
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;
Nate Sammons4a121431999-04-06 01:19:39 +0000754 long_to_sigset(tcp->u_arg[1], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000755 tcp->u_rval = tcp->u_error = 0;
756 if (tcp->u_arg[0] == 0)
757 return 0;
Nate Sammons4a121431999-04-06 01:19:39 +0000758 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000759 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;
Nate Sammons4a121431999-04-06 01:19:39 +0000778 long_to_sigset(tcp->u_arg[1], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000779 tcp->u_rval = tcp->u_error = 0;
780 if (tcp->u_arg[0] == 0)
781 return 0;
Nate Sammons4a121431999-04-06 01:19:39 +0000782 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000783 return RVAL_NONE | RVAL_STR;
784 }
785 return 0;
786#else
787#ifdef SPARC
788 long i1;
Wichert Akkerman9ce1a631999-08-29 23:15:07 +0000789 struct regs regs;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000790 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 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000796 if(entering(tcp)) {
797 tcp->u_arg[0] = 0;
Wichert Akkerman9ce1a631999-08-29 23:15:07 +0000798 i1 = regs.r_o1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000799 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;
Nate Sammons4a121431999-04-06 01:19:39 +0000807 long_to_sigset(tcp->u_arg[1], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000808 tcp->u_rval = tcp->u_error = 0;
809 if(tcp->u_arg[0] == 0)
810 return 0;
Nate Sammons4a121431999-04-06 01:19:39 +0000811 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000812 return RVAL_NONE | RVAL_STR;
813 }
814 return 0;
Wichert Akkermanf90da011999-10-31 21:15:38 +0000815#else
816#ifdef MIPS
817 long sp;
818 struct sigcontext sc;
819
820 if(entering(tcp)) {
821 tcp->u_arg[0] = 0;
822 if (upeek(tcp->pid, REG_SP, &sp) < 0)
823 return 0;
824 if (umove(tcp, sp, &sc) < 0)
825 return 0;
826 tcp->u_arg[0] = 1;
827 tcp->u_arg[1] = sc.sc_sigset;
828 } else {
829 tcp->u_rval = tcp->u_error = 0;
830 if(tcp->u_arg[0] == 0)
831 return 0;
832 tcp->auxstr = sprintsigmask("mask now ", tcp->u_arg[1]);
833 return RVAL_NONE | RVAL_STR;
834 }
835 return 0;
836#endif /* MIPS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000837#endif /* SPARC */
838#endif /* ALPHA */
839#endif /* !M68K */
840#endif /* !POWERPC */
841#endif /* !I386 */
842}
843
844int
845sys_siggetmask(tcp)
846struct tcb *tcp;
847{
848 if (exiting(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000849 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000850 long_to_sigset(tcp->u_rval, &sigm);
851 tcp->auxstr = sprintsigmask("mask ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000852 }
853 return RVAL_HEX | RVAL_STR;
854}
855
856int
857sys_sigsuspend(tcp)
858struct tcb *tcp;
859{
860 if (entering(tcp)) {
861 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000862 long_to_sigset(tcp->u_arg[2], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000863#if 0
864 /* first two are not really arguments, but print them anyway */
865 /* nevermind, they are an anachronism now, too bad... */
866 tprintf("%d, %#x, ", tcp->u_arg[0], tcp->u_arg[1]);
867#endif
Nate Sammons4a121431999-04-06 01:19:39 +0000868 printsigmask(&sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000869 }
870 return 0;
871}
872
873#endif /* LINUX */
874
875#ifdef SVR4
876
877int
878sys_sigsuspend(tcp)
879struct tcb *tcp;
880{
881 sigset_t sigset;
882
883 if (entering(tcp)) {
884 if (umove(tcp, tcp->u_arg[0], &sigset) < 0)
885 tprintf("[?]");
886 else
Nate Sammons4a121431999-04-06 01:19:39 +0000887 printsigmask(sigset, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000888 }
889 return 0;
890}
891static struct xlat ucontext_flags[] = {
892 { UC_SIGMASK, "UC_SIGMASK" },
893 { UC_STACK, "UC_STACK" },
894 { UC_CPU, "UC_CPU" },
895#ifdef UC_FPU
896 { UC_FPU, "UC_FPU" },
897#endif
898#ifdef UC_INTR
899 { UC_INTR, "UC_INTR" },
900#endif
901 { 0, NULL },
902};
903
904#endif
905
906#if defined SVR4 || defined LINUX
907#if defined LINUX && !defined SS_ONSTACK
908#define SS_ONSTACK 1
909#define SS_DISABLE 2
910#if __GLIBC_MINOR__ == 0
911typedef struct
912{
913 __ptr_t ss_sp;
914 int ss_flags;
915 size_t ss_size;
916} stack_t;
917#endif
918#endif
919
920static struct xlat sigaltstack_flags[] = {
921 { SS_ONSTACK, "SS_ONSTACK" },
922 { SS_DISABLE, "SS_DISABLE" },
923 { 0, NULL },
924};
925#endif
926
927#ifdef SVR4
928static void
929printcontext(tcp, ucp)
930struct tcb *tcp;
931ucontext_t *ucp;
932{
933 tprintf("{");
934 if (!abbrev(tcp)) {
935 tprintf("uc_flags=");
936 if (!printflags(ucontext_flags, ucp->uc_flags))
937 tprintf("0");
938 tprintf(", uc_link=%#lx, ", (unsigned long) ucp->uc_link);
939 }
940 tprintf("uc_sigmask=");
Nate Sammons4a121431999-04-06 01:19:39 +0000941 printsigmask(ucp->uc_sigmask, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000942 if (!abbrev(tcp)) {
943 tprintf(", uc_stack={ss_sp=%#lx, ss_size=%d, ss_flags=",
944 (unsigned long) ucp->uc_stack.ss_sp,
945 ucp->uc_stack.ss_size);
946 if (!printflags(sigaltstack_flags, ucp->uc_stack.ss_flags))
947 tprintf("0");
948 tprintf("}");
949 }
950 tprintf(", ...}");
951}
952
953int
954sys_getcontext(tcp)
955struct tcb *tcp;
956{
957 ucontext_t uc;
958
959 if (entering(tcp)) {
960 if (!tcp->u_arg[0])
961 tprintf("NULL");
962 else if (umove(tcp, tcp->u_arg[0], &uc) < 0)
963 tprintf("{...}");
964 else
965 printcontext(tcp, &uc);
966 }
967 return 0;
968}
969
970int
971sys_setcontext(tcp)
972struct tcb *tcp;
973{
974 ucontext_t uc;
975
976 if (entering(tcp)) {
977 if (!tcp->u_arg[0])
978 tprintf("NULL");
979 else if (umove(tcp, tcp->u_arg[0], &uc) < 0)
980 tprintf("{...}");
981 else
982 printcontext(tcp, &uc);
983 }
984 else {
985 tcp->u_rval = tcp->u_error = 0;
986 if (tcp->u_arg[0] == 0)
987 return 0;
988 return RVAL_NONE;
989 }
990 return 0;
991}
992
993#endif /* SVR4 */
994
995#ifdef LINUX
996
997static int
998print_stack_t(tcp, addr)
999struct tcb *tcp;
1000unsigned long addr;
1001{
1002 stack_t ss;
1003 if (umove(tcp, addr, &ss) < 0)
1004 return -1;
1005 tprintf("{ss_sp=%#lx, ss_flags=", (unsigned long) ss.ss_sp);
1006 if (!printflags(sigaltstack_flags, ss.ss_flags))
1007 tprintf("0");
1008 tprintf(", ss_size=%lu}", (unsigned long) ss.ss_size);
1009 return 0;
1010}
1011
1012int
1013sys_sigaltstack(tcp)
1014 struct tcb *tcp;
1015{
1016 if (entering(tcp)) {
1017 if (tcp->u_arg[0] == 0)
1018 tprintf("NULL");
1019 else if (print_stack_t(tcp, tcp->u_arg[0]) < 0)
1020 return -1;
1021 }
1022 else {
1023 tprintf(", ");
1024 if (tcp->u_arg[1] == 0)
1025 tprintf("NULL");
1026 else if (print_stack_t(tcp, tcp->u_arg[1]) < 0)
1027 return -1;
1028 }
1029 return 0;
1030}
1031#endif
1032
1033#ifdef HAVE_SIGACTION
1034
1035int
1036sys_sigprocmask(tcp)
1037struct tcb *tcp;
1038{
1039#ifdef ALPHA
1040 if (entering(tcp)) {
1041 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1042 tprintf(", ");
Nate Sammons4a121431999-04-06 01:19:39 +00001043 printsigmask(tcp->u_arg[1], 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001044 }
1045 else if (!syserror(tcp)) {
Nate Sammons4a121431999-04-06 01:19:39 +00001046 tcp->auxstr = sprintsigmask("old mask ", tcp->u_rval, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001047 return RVAL_HEX | RVAL_STR;
1048 }
1049#else /* !ALPHA */
1050 sigset_t sigset;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001051
1052 if (entering(tcp)) {
1053#ifdef SVR4
1054 if (tcp->u_arg[0] == 0)
1055 tprintf("0");
1056 else
1057#endif /* SVR4 */
1058 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1059 tprintf(", ");
1060 if (!tcp->u_arg[1])
1061 tprintf("NULL, ");
Nate Sammons4a121431999-04-06 01:19:39 +00001062 else if (copy_sigset(tcp, tcp->u_arg[1], &sigset) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001063 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001064 else {
Nate Sammons4a121431999-04-06 01:19:39 +00001065 printsigmask(&sigset, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001066 tprintf(", ");
1067 }
1068 }
1069 else {
1070 if (!tcp->u_arg[2])
1071 tprintf("NULL");
1072 else if (syserror(tcp))
1073 tprintf("%#lx", tcp->u_arg[2]);
Nate Sammons4a121431999-04-06 01:19:39 +00001074 else if (copy_sigset(tcp, tcp->u_arg[2], &sigset) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001075 tprintf("[?]");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001076 else
Nate Sammons4a121431999-04-06 01:19:39 +00001077 printsigmask(&sigset, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001078 }
1079#endif /* !ALPHA */
1080 return 0;
1081}
1082
1083#endif /* HAVE_SIGACTION */
1084
1085int
1086sys_kill(tcp)
1087struct tcb *tcp;
1088{
1089 if (entering(tcp)) {
Nate Sammonsce780fc1999-03-29 23:23:13 +00001090 tprintf("%ld, %s", tcp->u_arg[0], signame(tcp->u_arg[1]));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001091 }
1092 return 0;
1093}
1094
1095int
1096sys_killpg(tcp)
1097struct tcb *tcp;
1098{
1099 return sys_kill(tcp);
1100}
1101
1102int
1103sys_sigpending(tcp)
1104struct tcb *tcp;
1105{
1106 sigset_t sigset;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001107
1108 if (exiting(tcp)) {
1109 if (syserror(tcp))
1110 tprintf("%#lx", tcp->u_arg[0]);
Nate Sammons4a121431999-04-06 01:19:39 +00001111 else if (copy_sigset(tcp, tcp->u_arg[0], &sigset) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001112 tprintf("[?]");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001113 else
Nate Sammons4a121431999-04-06 01:19:39 +00001114 printsigmask(sigset, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001115 }
1116 return 0;
1117}
1118
1119#ifdef LINUX
1120
1121 int
1122sys_rt_sigprocmask(tcp)
1123 struct tcb *tcp;
1124{
1125 sigset_t sigset;
1126
Nate Sammons4a121431999-04-06 01:19:39 +00001127 /* Note: arg[3] is the length of the sigset. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001128 if (entering(tcp)) {
1129 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1130 tprintf(", ");
1131 if (!tcp->u_arg[1])
1132 tprintf("NULL, ");
Nate Sammons4a121431999-04-06 01:19:39 +00001133 else if (copy_sigset_len(tcp, tcp->u_arg[1], &sigset, tcp->u_arg[3]) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001134 tprintf("%#lx, ", tcp->u_arg[1]);
1135 else {
Nate Sammons4a121431999-04-06 01:19:39 +00001136 printsigmask(&sigset, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001137 tprintf(", ");
1138 }
1139 }
1140 else {
1141 if (!tcp->u_arg[2])
1142
1143 tprintf("NULL");
1144 else if (syserror(tcp))
1145 tprintf("%#lx", tcp->u_arg[2]);
Nate Sammons4a121431999-04-06 01:19:39 +00001146 else if (copy_sigset_len(tcp, tcp->u_arg[2], &sigset, tcp->u_arg[3]) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001147 tprintf("[?]");
1148 else
Nate Sammons4a121431999-04-06 01:19:39 +00001149 printsigmask(&sigset, 1);
Nate Sammonsdab325a1999-03-29 23:33:35 +00001150 tprintf(", %lu", tcp->u_arg[3]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001151 }
1152 return 0;
1153}
1154
1155#if __GLIBC_MINOR__ < 1
1156/* Type for data associated with a signal. */
1157typedef union sigval
1158{
1159 int sival_int;
1160 void *sival_ptr;
1161} sigval_t;
1162
1163# define __SI_MAX_SIZE 128
1164# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 3)
1165
1166typedef struct siginfo
1167{
1168 int si_signo; /* Signal number. */
1169 int si_errno; /* If non-zero, an errno value associated with
1170 this signal, as defined in <errno.h>. */
1171 int si_code; /* Signal code. */
1172
1173 union
1174 {
1175 int _pad[__SI_PAD_SIZE];
1176
1177 /* kill(). */
1178 struct
1179 {
1180 __pid_t si_pid; /* Sending process ID. */
1181 __uid_t si_uid; /* Real user ID of sending process. */
1182 } _kill;
1183
1184 /* POSIX.1b timers. */
1185 struct
1186 {
1187 unsigned int _timer1;
1188 unsigned int _timer2;
1189 } _timer;
1190
1191 /* POSIX.1b signals. */
1192 struct
1193 {
1194 __pid_t si_pid; /* Sending process ID. */
1195 __uid_t si_uid; /* Real user ID of sending process. */
1196 sigval_t si_sigval; /* Signal value. */
1197 } _rt;
1198
1199 /* SIGCHLD. */
1200 struct
1201 {
1202 __pid_t si_pid; /* Which child. */
1203 int si_status; /* Exit value or signal. */
1204 __clock_t si_utime;
1205 __clock_t si_stime;
1206 } _sigchld;
1207
1208 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS. */
1209 struct
1210 {
1211 void *si_addr; /* Faulting insn/memory ref. */
1212 } _sigfault;
1213
1214 /* SIGPOLL. */
1215 struct
1216 {
1217 int si_band; /* Band event for SIGPOLL. */
1218 int si_fd;
1219 } _sigpoll;
1220 } _sifields;
1221} siginfo_t;
1222#endif
1223
1224/* Structure describing the action to be taken when a signal arrives. */
1225struct new_sigaction
1226{
1227 union
1228 {
1229 __sighandler_t __sa_handler;
1230 void (*__sa_sigaction) (int, siginfo_t *, void *);
1231 }
1232 __sigaction_handler;
1233 unsigned long sa_flags;
1234 void (*sa_restorer) (void);
1235 unsigned long int sa_mask[2];
1236};
1237
1238
1239 int
1240sys_rt_sigaction(tcp)
1241 struct tcb *tcp;
1242{
1243 struct new_sigaction sa;
1244 sigset_t sigset;
1245 long addr;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001246
1247 if (entering(tcp)) {
1248 printsignal(tcp->u_arg[0]);
1249 tprintf(", ");
1250 addr = tcp->u_arg[1];
1251 } else
1252 addr = tcp->u_arg[2];
1253 if (addr == 0)
1254 tprintf("NULL");
1255 else if (!verbose(tcp))
1256 tprintf("%#lx", addr);
1257 else if (umove(tcp, addr, &sa) < 0)
1258 tprintf("{...}");
1259 else {
1260 switch ((long) sa.__sigaction_handler.__sa_handler) {
1261 case (long) SIG_ERR:
1262 tprintf("{SIG_ERR}");
1263 break;
1264 case (long) SIG_DFL:
1265 tprintf("{SIG_DFL}");
1266 break;
1267 case (long) SIG_IGN:
1268 tprintf("{SIG_IGN}");
1269 break;
1270 default:
1271 tprintf("{%#lx, ",
1272 (long) sa.__sigaction_handler.__sa_handler);
Nate Sammons4a121431999-04-06 01:19:39 +00001273 sigemptyset(&sigset);
Wichert Akkermandacfb6e1999-06-03 14:21:07 +00001274#ifdef LINUXSPARC
1275 if (tcp->u_arg[4] <= sizeof(sigset))
1276 memcpy(&sigset, &sa.sa_mask, tcp->u_arg[4]);
1277#else
Nate Sammons4a121431999-04-06 01:19:39 +00001278 if (tcp->u_arg[3] <= sizeof(sigset))
1279 memcpy(&sigset, &sa.sa_mask, tcp->u_arg[3]);
Wichert Akkermandacfb6e1999-06-03 14:21:07 +00001280#endif
Nate Sammons4a121431999-04-06 01:19:39 +00001281 else
1282 memcpy(&sigset, &sa.sa_mask, sizeof(sigset));
1283 printsigmask(&sigset, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001284 tprintf(", ");
1285 if (!printflags(sigact_flags, sa.sa_flags))
1286 tprintf("0");
1287 tprintf("}");
1288 }
1289 }
1290 if (entering(tcp))
1291 tprintf(", ");
1292 else
Wichert Akkermandacfb6e1999-06-03 14:21:07 +00001293#ifdef LINUXSPARC
1294 tprintf(", %#lx, %lu", tcp->u_arg[3], tcp->u_arg[4]);
1295#elif defined(ALPHA)
1296 tprintf(", %lu, %#lx", tcp->u_arg[3], tcp->u_arg[4]);
1297#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001298 tprintf(", %lu", addr = tcp->u_arg[3]);
Wichert Akkermandacfb6e1999-06-03 14:21:07 +00001299#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001300 return 0;
1301}
1302
1303 int
1304sys_rt_sigpending(tcp)
1305 struct tcb *tcp;
1306{
1307 sigset_t sigset;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001308
1309 if (exiting(tcp)) {
1310 if (syserror(tcp))
1311 tprintf("%#lx", tcp->u_arg[0]);
Nate Sammons4a121431999-04-06 01:19:39 +00001312 else if (copy_sigset_len(tcp, tcp->u_arg[0],
1313 &sigset, tcp->u_arg[1]) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001314 tprintf("[?]");
1315 else
Nate Sammons4a121431999-04-06 01:19:39 +00001316 printsigmask(sigset, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001317 }
1318 return 0;
1319}
1320 int
1321sys_rt_sigsuspend(tcp)
1322 struct tcb *tcp;
1323{
1324 if (entering(tcp)) {
1325 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +00001326 if (copy_sigset_len(tcp, tcp->u_arg[0], &sigm, tcp->u_arg[1]) < 0)
1327 tprintf("[?]");
1328 else
1329 printsigmask(&sigm, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001330 }
1331 return 0;
1332}
1333#ifndef ILL_ILLOPC
1334#define ILL_ILLOPC 1 /* illegal opcode */
1335#define ILL_ILLOPN 2 /* illegal operand */
1336#define ILL_ILLADR 3 /* illegal addressing mode */
1337#define ILL_ILLTRP 4 /* illegal trap */
1338#define ILL_PRVOPC 5 /* privileged opcode */
1339#define ILL_PRVREG 6 /* privileged register */
1340#define ILL_COPROC 7 /* coprocessor error */
1341#define ILL_BADSTK 8 /* internal stack error */
1342#define FPE_INTDIV 1 /* integer divide by zero */
1343#define FPE_INTOVF 2 /* integer overflow */
1344#define FPE_FLTDIV 3 /* floating point divide by zero */
1345#define FPE_FLTOVF 4 /* floating point overflow */
1346#define FPE_FLTUND 5 /* floating point underflow */
1347#define FPE_FLTRES 6 /* floating point inexact result */
1348#define FPE_FLTINV 7 /* floating point invalid operation */
1349#define FPE_FLTSUB 8 /* subscript out of range */
1350#define SEGV_MAPERR 1 /* address not mapped to object */
1351#define SEGV_ACCERR 2 /* invalid permissions for mapped object */
1352#define BUS_ADRALN 1 /* invalid address alignment */
1353#define BUS_ADRERR 2 /* non-existant physical address */
1354#define BUS_OBJERR 3 /* object specific hardware error */
1355#define TRAP_BRKPT 1 /* process breakpoint */
1356#define TRAP_TRACE 2 /* process trace trap */
1357#define CLD_EXITED 1 /* child has exited */
1358#define CLD_KILLED 2 /* child was killed */
1359#define CLD_DUMPED 3 /* child terminated abnormally */
1360#define CLD_TRAPPED 4 /* traced child has trapped */
1361#define CLD_STOPPED 5 /* child has stopped */
1362#define CLD_CONTINUED 6 /* stopped child has continued */
1363#define POLL_IN 1 /* data input available */
1364#define POLL_OUT 2 /* output buffers available */
1365#define POLL_MSG 3 /* input message available */
1366#define POLL_ERR 4 /* i/o error */
1367#define POLL_PRI 5 /* high priority input available */
1368#define POLL_HUP 6 /* device disconnected */
1369#define SI_USER 0 /* sent by kill, sigsend, raise */
1370#define SI_QUEUE -1 /* sent by sigqueue */
1371#define SI_TIMER -2 /* sent by timer expiration */
1372#define SI_MESGQ -3 /* sent by real time mesq state change */
1373#define SI_ASYNCIO -4 /* sent by AIO completion */
1374#else
1375#undef si_pid
1376#undef si_uid
1377#undef si_status
1378#undef si_utime
1379#undef si_stime
1380#undef si_value
1381#undef si_int
1382#undef si_ptr
1383#undef si_addr
1384#undef si_band
1385#undef si_fd
1386#endif
1387
1388static struct xlat sigill_flags[] = {
1389 {ILL_ILLOPC, "ILL_ILLOPC"},
1390 {ILL_ILLOPN, "ILL_ILLOPN"},
1391 {ILL_ILLADR, "ILL_ILLADR"},
1392 {ILL_ILLTRP, "ILL_ILLTRP"},
1393 {ILL_PRVOPC, "ILL_PRVOPC"},
1394 {ILL_PRVREG, "ILL_PRVREG"},
1395 {ILL_COPROC, "ILL_COPROC"},
1396 {ILL_BADSTK, "ILL_BADSTK"},
1397 {0, NULL}
1398};
1399
1400static struct xlat sigfpe_flags[] = {
1401 {FPE_INTDIV, "FPE_INTDIV"},
1402 {FPE_INTOVF, "FPE_INTOVF"},
1403 {FPE_FLTDIV, "FPE_FLTDIV"},
1404 {FPE_FLTOVF, "FPE_FLTOVF"},
1405 {FPE_FLTUND, "FPE_FLTUND"},
1406 {FPE_FLTRES, "FPE_FLTRES"},
1407 {FPE_FLTINV, "FPE_FLTINV"},
1408 {FPE_FLTSUB, "FPE_FLTSUB"},
1409 {0, NULL}
1410};
1411
1412static struct xlat sigsegv_flags[] = {
1413 {SEGV_MAPERR, "SEGV_MAPERR"},
1414 {SEGV_ACCERR, "SEGV_ACCERR"},
1415 {0, NULL}
1416};
1417
1418static struct xlat sigbus_flags[] = {
1419 {BUS_ADRALN, "BUS_ADRALN"},
1420 {BUS_ADRERR, "BUS_ADRERR"},
1421 {BUS_OBJERR, "BUS_OBJERR"},
1422 {0, NULL}
1423};
1424
1425static struct xlat sigtrap_flags[] = {
1426 {TRAP_BRKPT, "TRAP_BRKPT"},
1427 {TRAP_TRACE, "TRAP_TRACE"},
1428 {0, NULL}
1429};
1430
1431static struct xlat sigchld_flags[] = {
1432 {CLD_EXITED, "CLD_EXITED"},
1433 {CLD_KILLED, "CLD_KILLED"},
1434 {CLD_DUMPED, "CLD_DUMPED"},
1435 {CLD_TRAPPED, "CLD_TRAPPED"},
1436 {CLD_STOPPED, "CLD_STOPPED"},
1437 {CLD_CONTINUED, "CLD_CONTINUED"},
1438 {0, NULL}
1439};
1440
1441static struct xlat sigpoll_flags[] = {
1442 {POLL_IN, "POLL_IN"},
1443 {POLL_OUT, "POLL_OUT"},
1444 {POLL_MSG, "POLL_MSG"},
1445 {POLL_ERR, "POLL_ERR"},
1446 {POLL_PRI, "POLL_PRI"},
1447 {POLL_HUP, "POLL_HUP"},
1448 {0, NULL}
1449};
1450
1451static struct xlat siginfo_flags[] = {
1452 {SI_USER, "SI_USER"},
1453 {SI_QUEUE, "SI_QUEUE"},
1454 {SI_TIMER, "SI_TIMER"},
1455 {SI_MESGQ, "SI_MESGQ"},
1456 {SI_ASYNCIO, "SI_ASYNCIO"},
1457 {0, NULL}
1458};
1459
1460 static void
1461printsiginfo(tcp, si)
1462 struct tcb *tcp;
1463 siginfo_t *si;
1464{
1465 tprintf("{si_signo=");
1466 printsignal(si->si_signo);
1467 tprintf(", si_errno=%d, si_code=", si->si_errno);
1468 switch(si->si_signo)
1469 {
1470 case SIGILL:
1471 if (!printflags(sigill_flags, si->si_code))
1472 tprintf("%d /* ILL_??? */", si->si_code);
1473 tprintf(", si_addr=%lx",
1474 (unsigned long) si->_sifields._sigfault.si_addr);
1475 break;
1476 case SIGFPE:
1477 if (!printflags(sigfpe_flags, si->si_code))
1478 tprintf("%d /* FPE_??? */", si->si_code);
1479 tprintf(", si_addr=%lx",
1480 (unsigned long) si->_sifields._sigfault.si_addr);
1481 break;
1482 case SIGSEGV:
1483 if (!printflags(sigsegv_flags, si->si_code))
1484 tprintf("%d /* SEGV_??? */", si->si_code);
1485 tprintf(", si_addr=%lx",
1486 (unsigned long) si->_sifields._sigfault.si_addr);
1487 break;
1488 case SIGBUS:
1489 if (!printflags(sigbus_flags, si->si_code))
1490 tprintf("%d /* BUS_??? */", si->si_code);
1491 tprintf(", si_addr=%lx",
1492 (unsigned long) si->_sifields._sigfault.si_addr);
1493 break;
1494 case SIGTRAP:
1495 if (!printflags(sigtrap_flags, si->si_code))
1496 tprintf("%d /* TRAP_??? */", si->si_code);
1497 break;
1498 case SIGCHLD:
1499 if (!printflags(sigchld_flags, si->si_code))
1500 tprintf("%d /* CLD_??? */", si->si_code);
1501 if (!verbose(tcp))
1502 tprintf(", ...");
1503 else
1504 tprintf(", si_pid=%d, si_uid=%d, si_status=%d, si_utime=%lu, si_stime=%lu",
1505 si->_sifields._kill.si_pid,
1506 si->_sifields._kill.si_uid,
1507 si->_sifields._sigchld.si_status,
1508 si->_sifields._sigchld.si_utime,
1509 si->_sifields._sigchld.si_stime);
1510 break;
1511 case SIGPOLL:
1512 if (!printflags(sigpoll_flags, si->si_code))
1513 tprintf("%d /* POLL_??? */", si->si_code);
1514 if (si->si_code == POLL_IN
1515 || si->si_code == POLL_OUT
1516 || si->si_code == POLL_MSG)
1517 tprintf(", si_bind=%lu, si_fd=%d",
1518 (unsigned long) si->_sifields._sigpoll.si_band,
1519 si->_sifields._sigpoll.si_fd);
1520 break;
1521 default:
1522 if (!printflags(siginfo_flags, si->si_code))
1523 tprintf("%d /* SI_??? */", si->si_code);
1524 tprintf(", si_pid=%lu, si_uid=%lu, si_value={",
1525 (unsigned long) si->_sifields._rt.si_pid,
1526 (unsigned long) si->_sifields._rt.si_uid);
1527 if (!verbose(tcp))
1528 tprintf("...");
1529 else {
1530 tprintf("sival_int=%u, sival_ptr=%#lx",
1531 si->_sifields._rt.si_sigval.sival_int,
1532 (unsigned long) si->_sifields._rt.si_sigval.sival_ptr);
1533 }
1534 tprintf("}");
1535 break;
1536 }
1537 tprintf("}");
1538}
1539
1540 int
1541sys_rt_sigqueueinfo(tcp)
1542 struct tcb *tcp;
1543{
1544 if (entering(tcp)) {
1545 siginfo_t si;
1546 tprintf("%lu, ", tcp->u_arg[0]);
1547 printsignal(tcp->u_arg[1]);
1548 tprintf(", ");
1549 if (umove(tcp, tcp->u_arg[2], &si) < 0)
1550 tprintf("%#lx", tcp->u_arg[2]);
1551 else
1552 printsiginfo(&si);
1553 }
1554 return 0;
1555}
1556
1557int sys_rt_sigtimedwait(tcp)
1558 struct tcb *tcp;
1559{
1560 if (entering(tcp)) {
1561 sigset_t sigset;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001562
Nate Sammons4a121431999-04-06 01:19:39 +00001563 if (copy_sigset_len(tcp, tcp->u_arg[0],
1564 &sigset, tcp->u_arg[3]) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001565 tprintf("[?]");
1566 else
Nate Sammons4a121431999-04-06 01:19:39 +00001567 printsigmask(sigset, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001568 tprintf(", ");
1569 }
1570 else {
1571 if (syserror(tcp))
1572 tprintf("%#lx", tcp->u_arg[0]);
1573 else {
1574 siginfo_t si;
1575 if (umove(tcp, tcp->u_arg[1], &si) < 0)
1576 tprintf("%#lx", tcp->u_arg[1]);
1577 else
1578 printsiginfo(&si);
1579 /* XXX For now */
1580 tprintf(", %#lx", tcp->u_arg[2]);
1581 tprintf(", %d", (int) tcp->u_arg[3]);
1582 }
1583 }
1584 return 0;
1585};
1586
1587#endif /* LINUX */
1588