blob: c99598b12b14485d3ba4fb48fb948ebfc642b8dc [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>
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00005 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
7 * Linux for s390 port by D.J. Barrow
8 * <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00009 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 * $Id$
34 */
35
36#include "defs.h"
37
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000038#include <signal.h>
39#include <sys/user.h>
40#include <fcntl.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000041
42#ifdef SVR4
43#include <sys/ucontext.h>
44#endif /* SVR4 */
45
Wichert Akkerman15dea971999-10-06 13:06:34 +000046#if HAVE_LINUX_PTRACE_H
47#undef PTRACE_SYSCALL
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000048#include <linux/ptrace.h>
Wichert Akkerman36915a11999-07-13 15:45:02 +000049#endif
50
51#ifdef HAVE_SYS_REG_H
52# include <sys/reg.h>
Wichert Akkerman15dea971999-10-06 13:06:34 +000053#ifndef PTRACE_PEEKUSR
Wichert Akkerman36915a11999-07-13 15:45:02 +000054# define PTRACE_PEEKUSR PTRACE_PEEKUSER
Wichert Akkerman15dea971999-10-06 13:06:34 +000055#endif
56#ifndef PTRACE_POKEUSR
Wichert Akkerman36915a11999-07-13 15:45:02 +000057# define PTRACE_POKEUSR PTRACE_POKEUSER
Wichert Akkerman2e2553a1999-05-09 00:29:58 +000058#endif
Wichert Akkerman15dea971999-10-06 13:06:34 +000059#endif
Wichert Akkerman36915a11999-07-13 15:45:02 +000060
61#ifdef LINUX
62
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000063#ifdef HAVE_ASM_SIGCONTEXT_H
64#include <asm/sigcontext.h>
65#ifdef SPARC
Wichert Akkerman9ce1a631999-08-29 23:15:07 +000066#include <asm/reg.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000067typedef struct {
Wichert Akkerman9ce1a631999-08-29 23:15:07 +000068 struct regs si_regs;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000069 int si_mask;
70} m_siginfo_t;
71#endif
72#else /* !HAVE_ASM_SIGCONTEXT_H */
73#ifdef I386
74struct sigcontext_struct {
75 unsigned short gs, __gsh;
76 unsigned short fs, __fsh;
77 unsigned short es, __esh;
78 unsigned short ds, __dsh;
79 unsigned long edi;
80 unsigned long esi;
81 unsigned long ebp;
82 unsigned long esp;
83 unsigned long ebx;
84 unsigned long edx;
85 unsigned long ecx;
86 unsigned long eax;
87 unsigned long trapno;
88 unsigned long err;
89 unsigned long eip;
90 unsigned short cs, __csh;
91 unsigned long eflags;
92 unsigned long esp_at_signal;
93 unsigned short ss, __ssh;
94 unsigned long i387;
95 unsigned long oldmask;
96 unsigned long cr2;
97};
98#else /* !I386 */
99#ifdef M68K
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000100struct sigcontext
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000101{
102 unsigned long sc_mask;
103 unsigned long sc_usp;
104 unsigned long sc_d0;
105 unsigned long sc_d1;
106 unsigned long sc_a0;
107 unsigned long sc_a1;
108 unsigned short sc_sr;
109 unsigned long sc_pc;
110 unsigned short sc_formatvec;
111};
112#endif /* M68K */
113#endif /* !I386 */
114#endif /* !HAVE_ASM_SIGCONTEXT_H */
115#ifndef NSIG
116#define NSIG 32
117#endif
118#ifdef ARM
119#undef NSIG
120#define NSIG 32
121#endif
122#endif /* LINUX */
123
124char *signalent0[] = {
125#include "signalent.h"
126};
127int nsignals0 = sizeof signalent0 / sizeof signalent0[0];
128
129#if SUPPORTED_PERSONALITIES >= 2
130char *signalent1[] = {
131#include "signalent1.h"
132};
133int nsignals1 = sizeof signalent1 / sizeof signalent1[0];
134#endif /* SUPPORTED_PERSONALITIES >= 2 */
135
136#if SUPPORTED_PERSONALITIES >= 3
137char *signalent2[] = {
138#include "signalent2.h"
139};
140int nsignals2 = sizeof signalent2 / sizeof signalent2[0];
141#endif /* SUPPORTED_PERSONALITIES >= 3 */
142
143char **signalent;
144int nsignals;
145
146#ifdef SUNOS4
147
148static struct xlat sigvec_flags[] = {
149 { SV_ONSTACK, "SV_ONSTACK" },
150 { SV_INTERRUPT, "SV_INTERRUPT" },
151 { SV_RESETHAND, "SV_RESETHAND" },
152 { SA_NOCLDSTOP, "SA_NOCLDSTOP" },
153 { 0, NULL },
154};
155
156#endif /* SUNOS4 */
157
158#ifdef HAVE_SIGACTION
159
160static struct xlat sigact_flags[] = {
161#ifdef SA_STACK
162 { SA_STACK, "SA_STACK" },
163#endif
164#ifdef SA_RESTART
165 { SA_RESTART, "SA_RESTART" },
166#endif
167#ifdef SA_INTERRUPT
168 { SA_INTERRUPT, "SA_INTERRUPT" },
169#endif
170#ifdef SA_NOMASK
171 { SA_NOMASK, "SA_NOMASK" },
172#endif
173#ifdef SA_ONESHOT
174 { SA_ONESHOT, "SA_ONESHOT" },
175#endif
176#ifdef SA_SIGINFO
177 { SA_SIGINFO, "SA_SIGINFO" },
178#endif
179#ifdef SA_RESETHAND
180 { SA_RESETHAND, "SA_RESETHAND" },
181#endif
182#ifdef SA_ONSTACK
183 { SA_ONSTACK, "SA_ONSTACK" },
184#endif
185#ifdef SA_NODEFER
186 { SA_NODEFER, "SA_NODEFER" },
187#endif
188#ifdef SA_NOCLDSTOP
189 { SA_NOCLDSTOP, "SA_NOCLDSTOP" },
190#endif
191#ifdef SA_NOCLDWAIT
192 { SA_NOCLDWAIT, "SA_NOCLDWAIT" },
193#endif
194#ifdef _SA_BSDCALL
195 { _SA_BSDCALL, "_SA_BSDCALL" },
196#endif
197 { 0, NULL },
198};
199
200static struct xlat sigprocmaskcmds[] = {
201 { SIG_BLOCK, "SIG_BLOCK" },
202 { SIG_UNBLOCK, "SIG_UNBLOCK" },
203 { SIG_SETMASK, "SIG_SETMASK" },
204#ifdef SIG_SETMASK32
205 { SIG_SETMASK32,"SIG_SETMASK32" },
206#endif
207 { 0, NULL },
208};
209
210#endif /* HAVE_SIGACTION */
211
Nate Sammonsce780fc1999-03-29 23:23:13 +0000212/* Anonymous realtime signals. */
213/* Under glibc 2.1, SIGRTMIN et al are functions, but __SIGRTMIN is a
214 constant. This is what we want. Otherwise, just use SIGRTMIN. */
215#ifdef SIGRTMIN
216#ifndef __SIGRTMIN
217#define __SIGRTMIN SIGRTMIN
218#define __SIGRTMAX SIGRTMAX /* likewise */
219#endif
220#endif
221
222char *
223signame(sig)
224int sig;
225{
226 static char buf[30];
227 if (sig < nsignals) {
228 return signalent[sig];
229#ifdef SIGRTMIN
Nate Sammons3080aa41999-03-30 00:16:41 +0000230 } else if (sig >= __SIGRTMIN && sig <= __SIGRTMAX) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000231 sprintf(buf, "SIGRT_%ld", (long)(sig - __SIGRTMIN));
Nate Sammonsce780fc1999-03-29 23:23:13 +0000232 return buf;
233#endif /* SIGRTMIN */
234 } else {
235 sprintf(buf, "%d", sig);
236 return buf;
237 }
238}
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000239
Wichert Akkerman9ce1a631999-08-29 23:15:07 +0000240#ifndef UNIXWARE
Nate Sammons4a121431999-04-06 01:19:39 +0000241static void
242long_to_sigset(l, s)
243long l;
244sigset_t *s;
245{
246 sigemptyset(s);
247 *(long *)s = l;
248}
Wichert Akkerman9ce1a631999-08-29 23:15:07 +0000249#endif
Nate Sammons4a121431999-04-06 01:19:39 +0000250
251static int
252copy_sigset_len(tcp, addr, s, len)
253struct tcb *tcp;
254int addr;
255sigset_t *s;
256int len;
257{
258 if (len > sizeof(*s))
259 len = sizeof(*s);
260 sigemptyset(s);
261 if (umoven(tcp, addr, len, (char *)s) < 0)
262 return -1;
263 return 0;
264}
265
266#ifdef LINUX
267/* Original sigset is unsigned long */
268#define copy_sigset(tcp, addr, s) copy_sigset_len(tcp, addr, s, sizeof(long))
269#else
270#define copy_sigset(tcp, addr, s) copy_sigset_len(tcp, addr, s, sizeof(sigset_t))
271#endif
272
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000273static char *
Nate Sammons4a121431999-04-06 01:19:39 +0000274sprintsigmask(s, mask, rt)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000275char *s;
276sigset_t *mask;
Nate Sammons4a121431999-04-06 01:19:39 +0000277int rt; /* set might include realtime sigs */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000278{
279 int i, nsigs;
Nate Sammons4a121431999-04-06 01:19:39 +0000280 int maxsigs;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000281 char *format;
282 static char outstr[256];
283
284 strcpy(outstr, s);
285 s = outstr + strlen(outstr);
286 nsigs = 0;
Nate Sammons4a121431999-04-06 01:19:39 +0000287 maxsigs = nsignals;
288#ifdef __SIGRTMAX
289 if (rt)
290 maxsigs = __SIGRTMAX; /* instead */
291#endif
292 for (i = 1; i < maxsigs; i++) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000293 if (sigismember(mask, i) == 1)
294 nsigs++;
295 }
296 if (nsigs >= nsignals * 2 / 3) {
297 *s++ = '~';
Nate Sammons4a121431999-04-06 01:19:39 +0000298 for (i = 1; i < maxsigs; i++) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000299 switch (sigismember(mask, i)) {
300 case 1:
301 sigdelset(mask, i);
302 break;
303 case 0:
304 sigaddset(mask, i);
305 break;
306 }
307 }
308 }
309 format = "%s";
310 *s++ = '[';
Nate Sammons4a121431999-04-06 01:19:39 +0000311 for (i = 1; i < maxsigs; i++) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000312 if (sigismember(mask, i) == 1) {
Nate Sammonsce780fc1999-03-29 23:23:13 +0000313 sprintf(s, format, signame(i) + 3); s += strlen(s);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000314 format = " %s";
315 }
316 }
317 *s++ = ']';
318 *s = '\0';
319 return outstr;
320}
321
322static void
Nate Sammons4a121431999-04-06 01:19:39 +0000323printsigmask(mask, rt)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000324sigset_t *mask;
Nate Sammons4a121431999-04-06 01:19:39 +0000325int rt;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000326{
Nate Sammons4a121431999-04-06 01:19:39 +0000327 tprintf("%s", sprintsigmask("", mask, rt));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000328}
329
330void
331printsignal(nr)
332int nr;
333{
Nate Sammonsce780fc1999-03-29 23:23:13 +0000334 tprintf(signame(nr));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000335}
336
337/*
338 * Check process TCP for the disposition of signal SIG.
339 * Return 1 if the process would somehow manage to survive signal SIG,
340 * else return 0. This routine will never be called with SIGKILL.
341 */
342int
343sigishandled(tcp, sig)
344struct tcb *tcp;
345int sig;
346{
347#ifdef LINUX
348 int sfd;
349 char sname[32];
350 char buf[1024];
351 char *s;
352 int i;
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000353 unsigned int signalled, blocked, ignored, caught;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000354
355 /* This is incredibly costly but it's worth it. */
356 sprintf(sname, "/proc/%d/stat", tcp->pid);
357 if ((sfd = open(sname, O_RDONLY)) == -1) {
358 perror(sname);
359 return 1;
360 }
361 i = read(sfd, buf, 1024);
362 buf[i] = '\0';
363 close(sfd);
364 /*
365 * Skip the extraneous fields. This loses if the
366 * command name has any spaces in it. So be it.
367 */
368 for (i = 0, s = buf; i < 30; i++) {
369 while (*++s != ' ') {
370 if (!*s)
371 break;
372 }
373 }
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000374 if (sscanf(s, "%u%u%u%u",
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000375 &signalled, &blocked, &ignored, &caught) != 4) {
376 fprintf(stderr, "/proc/pid/stat format error\n");
377 return 1;
378 }
379#ifdef DEBUG
380 fprintf(stderr, "sigs: %08x %08x %08x %08x\n",
381 signalled, blocked, ignored, caught);
382#endif
383 if ((ignored & sigmask(sig)) || (caught & sigmask(sig)))
384 return 1;
385#endif /* LINUX */
386
387#ifdef SUNOS4
388 void (*u_signal)();
389
390 if (upeek(tcp->pid, uoff(u_signal[0]) + sig*sizeof(u_signal),
391 (long *) &u_signal) < 0) {
392 return 0;
393 }
394 if (u_signal != SIG_DFL)
395 return 1;
396#endif /* SUNOS4 */
397
398#ifdef SVR4
399 /*
400 * Since procfs doesn't interfere with wait I think it is safe
401 * to punt on this question. If not, the information is there.
402 */
403 return 1;
404#else /* !SVR4 */
405 switch (sig) {
406 case SIGCONT:
407 case SIGSTOP:
408 case SIGTSTP:
409 case SIGTTIN:
410 case SIGTTOU:
411 case SIGCHLD:
412 case SIGIO:
413#if defined(SIGURG) && SIGURG != SIGIO
414 case SIGURG:
415#endif
416 case SIGWINCH:
417 /* Gloria Gaynor says ... */
418 return 1;
419 default:
420 break;
421 }
422 return 0;
423#endif /* !SVR4 */
424}
425
426#if defined(SUNOS4)
427
428int
429sys_sigvec(tcp)
430struct tcb *tcp;
431{
432 struct sigvec sv;
433 long addr;
434
435 if (entering(tcp)) {
436 printsignal(tcp->u_arg[0]);
437 tprintf(", ");
438 addr = tcp->u_arg[1];
439 } else {
440 addr = tcp->u_arg[2];
441 }
442 if (addr == 0)
443 tprintf("NULL");
444 else if (!verbose(tcp))
445 tprintf("%#lx", addr);
446 else if (umove(tcp, addr, &sv) < 0)
447 tprintf("{...}");
448 else {
449 switch ((int) sv.sv_handler) {
450 case (int) SIG_ERR:
451 tprintf("{SIG_ERR}");
452 break;
453 case (int) SIG_DFL:
454 tprintf("{SIG_DFL}");
455 break;
456 case (int) SIG_IGN:
457 if (tcp->u_arg[0] == SIGTRAP) {
458 tcp->flags |= TCB_SIGTRAPPED;
459 kill(tcp->pid, SIGSTOP);
460 }
461 tprintf("{SIG_IGN}");
462 break;
463 case (int) SIG_HOLD:
464 if (tcp->u_arg[0] == SIGTRAP) {
465 tcp->flags |= TCB_SIGTRAPPED;
466 kill(tcp->pid, SIGSTOP);
467 }
468 tprintf("SIG_HOLD");
469 break;
470 default:
471 if (tcp->u_arg[0] == SIGTRAP) {
472 tcp->flags |= TCB_SIGTRAPPED;
473 kill(tcp->pid, SIGSTOP);
474 }
475 tprintf("{%#lx, ", (unsigned long) sv.sv_handler);
Nate Sammons4a121431999-04-06 01:19:39 +0000476 printsigmask(&sv.sv_mask, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000477 tprintf(", ");
478 if (!printflags(sigvec_flags, sv.sv_flags))
479 tprintf("0");
480 tprintf("}");
481 }
482 }
483 if (entering(tcp))
484 tprintf(", ");
485 return 0;
486}
487
488int
489sys_sigpause(tcp)
490struct tcb *tcp;
491{
492 if (entering(tcp)) { /* WTA: UD had a bug here: he forgot the braces */
Nate Sammons4a121431999-04-06 01:19:39 +0000493 sigset_t sigm;
494 long_to_sigset(tcp->u_arg[0], &sigm);
495 printsigmask(&sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000496 }
497 return 0;
498}
499
500int
501sys_sigstack(tcp)
502struct tcb *tcp;
503{
504 struct sigstack ss;
505 long addr;
506
507 if (entering(tcp))
508 addr = tcp->u_arg[0];
509 else
510 addr = tcp->u_arg[1];
511 if (addr == 0)
512 tprintf("NULL");
513 else if (umove(tcp, addr, &ss) < 0)
514 tprintf("%#lx", addr);
515 else {
516 tprintf("{ss_sp %#lx ", (unsigned long) ss.ss_sp);
517 tprintf("ss_onstack %s}", ss.ss_onstack ? "YES" : "NO");
518 }
519 if (entering(tcp))
520 tprintf(", ");
521 return 0;
522}
523
524int
525sys_sigcleanup(tcp)
526struct tcb *tcp;
527{
528 return 0;
529}
530
531#endif /* SUNOS4 */
532
533#ifndef SVR4
534
535int
536sys_sigsetmask(tcp)
537struct tcb *tcp;
538{
539 if (entering(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000540 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000541 long_to_sigset(tcp->u_arg[0], &sigm);
542 printsigmask(&sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000543 if ((tcp->u_arg[0] & sigmask(SIGTRAP))) {
544 /* Mark attempt to block SIGTRAP */
545 tcp->flags |= TCB_SIGTRAPPED;
546 /* Send unblockable signal */
547 kill(tcp->pid, SIGSTOP);
548 }
549 }
550 else if (!syserror(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000551 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000552 long_to_sigset(tcp->u_rval, &sigm);
553 tcp->auxstr = sprintsigmask("old mask ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000554
555 return RVAL_HEX | RVAL_STR;
556 }
557 return 0;
558}
559
560int
561sys_sigblock(tcp)
562struct tcb *tcp;
563{
564 return sys_sigsetmask(tcp);
565}
566
567#endif /* !SVR4 */
568
569#ifdef HAVE_SIGACTION
570
571#ifdef LINUX
572struct old_sigaction {
573 __sighandler_t __sa_handler;
574 unsigned long sa_mask;
575 unsigned long sa_flags;
576 void (*sa_restorer)(void);
577};
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000578#define SA_HANDLER __sa_handler
579#endif /* LINUX */
580
581#ifndef SA_HANDLER
582#define SA_HANDLER sa_handler
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000583#endif
584
585int
586sys_sigaction(tcp)
587struct tcb *tcp;
588{
589 long addr;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000590 sigset_t sigset;
Nate Sammons4a121431999-04-06 01:19:39 +0000591#ifdef LINUX
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000592 struct old_sigaction sa;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000593#else
594 struct sigaction sa;
595#endif
596
597
598 if (entering(tcp)) {
599 printsignal(tcp->u_arg[0]);
600 tprintf(", ");
601 addr = tcp->u_arg[1];
602 } else
603 addr = tcp->u_arg[2];
604 if (addr == 0)
605 tprintf("NULL");
606 else if (!verbose(tcp))
607 tprintf("%#lx", addr);
608 else if (umove(tcp, addr, &sa) < 0)
609 tprintf("{...}");
610 else {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000611 switch ((long) sa.SA_HANDLER) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000612 case (long) SIG_ERR:
613 tprintf("{SIG_ERR}");
614 break;
615 case (long) SIG_DFL:
616 tprintf("{SIG_DFL}");
617 break;
618 case (long) SIG_IGN:
619#ifndef SVR4
620 if (tcp->u_arg[0] == SIGTRAP) {
621 tcp->flags |= TCB_SIGTRAPPED;
622 kill(tcp->pid, SIGSTOP);
623 }
624#endif /* !SVR4 */
625 tprintf("{SIG_IGN}");
626 break;
627 default:
628#ifndef SVR4
629 if (tcp->u_arg[0] == SIGTRAP) {
630 tcp->flags |= TCB_SIGTRAPPED;
631 kill(tcp->pid, SIGSTOP);
632 }
633#endif /* !SVR4 */
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000634 tprintf("{%#lx, ", (long) sa.SA_HANDLER);
Wichert Akkerman48214be1999-11-26 09:55:42 +0000635#ifndef LINUX
636 printsigmask (&sa.sa_mask, 0);
637#else
Nate Sammons4a121431999-04-06 01:19:39 +0000638 long_to_sigset(sa.sa_mask, &sigset);
639 printsigmask(&sigset, 0);
Wichert Akkerman48214be1999-11-26 09:55:42 +0000640#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000641 tprintf(", ");
642 if (!printflags(sigact_flags, sa.sa_flags))
643 tprintf("0");
644 tprintf("}");
645 }
646 }
647 if (entering(tcp))
648 tprintf(", ");
649#ifdef LINUX
650 else
651 tprintf(", %#lx", (unsigned long) sa.sa_restorer);
652#endif
653 return 0;
654}
655
656int
657sys_signal(tcp)
658struct tcb *tcp;
659{
660 if (entering(tcp)) {
661 printsignal(tcp->u_arg[0]);
662 switch (tcp->u_arg[1]) {
663 case (int) SIG_ERR:
664 tprintf("SIG_ERR");
665 break;
666 case (int) SIG_DFL:
667 tprintf("SIG_DFL");
668 break;
669 case (int) SIG_IGN:
670#ifndef SVR4
671 if (tcp->u_arg[0] == SIGTRAP) {
672 tcp->flags |= TCB_SIGTRAPPED;
673 kill(tcp->pid, SIGSTOP);
674 }
675#endif /* !SVR4 */
676 tprintf("SIG_IGN");
677 break;
678 default:
679#ifndef SVR4
680 if (tcp->u_arg[0] == SIGTRAP) {
681 tcp->flags |= TCB_SIGTRAPPED;
682 kill(tcp->pid, SIGSTOP);
683 }
684#endif /* !SVR4 */
685 tprintf("%#lx", tcp->u_arg[1]);
686 }
687 }
688 return 0;
689}
690
691#endif /* HAVE_SIGACTION */
692
693#ifdef LINUX
694
695int
696sys_sigreturn(tcp)
697struct tcb *tcp;
698{
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +0000699#ifdef S390
700 long usp;
701 struct sigcontext_struct sc;
702
703 if (entering(tcp)) {
704 tcp->u_arg[0] = 0;
705 if (upeek(tcp->pid,PT_GPR15,&usp)<0)
706 return 0;
707 if (umove(tcp, usp+__SIGNAL_FRAMESIZE, &sc) < 0)
708 return 0;
709 tcp->u_arg[0] = 1;
710 memcpy(&tcp->u_arg[1],&sc.oldmask[0],sizeof(sigset_t));
711 } else {
712 tcp->u_rval = tcp->u_error = 0;
713 if (tcp->u_arg[0] == 0)
714 return 0;
715 tcp->auxstr = sprintsigmask("mask now ",(sigset_t *)&tcp->u_arg[1]);
716 return RVAL_NONE | RVAL_STR;
717 }
718 return 0;
719#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000720#ifdef I386
721 long esp;
722 struct sigcontext_struct sc;
723
724 if (entering(tcp)) {
725 tcp->u_arg[0] = 0;
726 if (upeek(tcp->pid, 4*UESP, &esp) < 0)
727 return 0;
728 if (umove(tcp, esp, &sc) < 0)
729 return 0;
730 tcp->u_arg[0] = 1;
731 tcp->u_arg[1] = sc.oldmask;
732 }
733 else {
734 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000735 long_to_sigset(tcp->u_arg[1], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000736 tcp->u_rval = tcp->u_error = 0;
737 if (tcp->u_arg[0] == 0)
738 return 0;
Nate Sammons4a121431999-04-06 01:19:39 +0000739 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000740 return RVAL_NONE | RVAL_STR;
741 }
742 return 0;
743#else /* !I386 */
744#ifdef POWERPC
745 long esp;
746 struct sigcontext_struct sc;
747
748 if (entering(tcp)) {
749 tcp->u_arg[0] = 0;
750 if (upeek(tcp->pid, 4*PT_R1, &esp) < 0)
751 return 0;
752 if (umove(tcp, esp, &sc) < 0)
753 return 0;
754 tcp->u_arg[0] = 1;
755 tcp->u_arg[1] = sc.oldmask;
756 }
757 else {
758 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000759 long_to_sigset(tcp->u_arg[1], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000760 tcp->u_rval = tcp->u_error = 0;
761 if (tcp->u_arg[0] == 0)
762 return 0;
Nate Sammons4a121431999-04-06 01:19:39 +0000763 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000764 return RVAL_NONE | RVAL_STR;
765 }
766 return 0;
767#else /* !POWERPC */
768#ifdef M68K
769 long usp;
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000770 struct sigcontext sc;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000771
772 if (entering(tcp)) {
773 tcp->u_arg[0] = 0;
774 if (upeek(tcp->pid, 4*PT_USP, &usp) < 0)
775 return 0;
776 if (umove(tcp, usp, &sc) < 0)
777 return 0;
778 tcp->u_arg[0] = 1;
779 tcp->u_arg[1] = sc.sc_mask;
780 }
781 else {
782 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000783 long_to_sigset(tcp->u_arg[1], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000784 tcp->u_rval = tcp->u_error = 0;
785 if (tcp->u_arg[0] == 0)
786 return 0;
Nate Sammons4a121431999-04-06 01:19:39 +0000787 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000788 return RVAL_NONE | RVAL_STR;
789 }
790 return 0;
791#else /* !M68K */
792#ifdef ALPHA
793 long fp;
794 struct sigcontext_struct sc;
795
796 if (entering(tcp)) {
797 tcp->u_arg[0] = 0;
798 if (upeek(tcp->pid, REG_FP, &fp) < 0)
799 return 0;
800 if (umove(tcp, fp, &sc) < 0)
801 return 0;
802 tcp->u_arg[0] = 1;
803 tcp->u_arg[1] = sc.sc_mask;
804 }
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;
815#else
816#ifdef SPARC
817 long i1;
Wichert Akkerman9ce1a631999-08-29 23:15:07 +0000818 struct regs regs;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000819 m_siginfo_t si;
820
821 if(ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
822 perror("sigreturn: PTRACE_GETREGS ");
823 return 0;
824 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000825 if(entering(tcp)) {
826 tcp->u_arg[0] = 0;
Wichert Akkerman9ce1a631999-08-29 23:15:07 +0000827 i1 = regs.r_o1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000828 if(umove(tcp, i1, &si) < 0) {
829 perror("sigreturn: umove ");
830 return 0;
831 }
832 tcp->u_arg[0] = 1;
833 tcp->u_arg[1] = si.si_mask;
834 } else {
835 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000836 long_to_sigset(tcp->u_arg[1], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000837 tcp->u_rval = tcp->u_error = 0;
838 if(tcp->u_arg[0] == 0)
839 return 0;
Nate Sammons4a121431999-04-06 01:19:39 +0000840 tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000841 return RVAL_NONE | RVAL_STR;
842 }
843 return 0;
Wichert Akkermanf90da011999-10-31 21:15:38 +0000844#else
845#ifdef MIPS
846 long sp;
847 struct sigcontext sc;
848
849 if(entering(tcp)) {
850 tcp->u_arg[0] = 0;
851 if (upeek(tcp->pid, REG_SP, &sp) < 0)
852 return 0;
853 if (umove(tcp, sp, &sc) < 0)
854 return 0;
855 tcp->u_arg[0] = 1;
856 tcp->u_arg[1] = sc.sc_sigset;
857 } else {
858 tcp->u_rval = tcp->u_error = 0;
859 if(tcp->u_arg[0] == 0)
860 return 0;
861 tcp->auxstr = sprintsigmask("mask now ", tcp->u_arg[1]);
862 return RVAL_NONE | RVAL_STR;
863 }
864 return 0;
865#endif /* MIPS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000866#endif /* SPARC */
867#endif /* ALPHA */
868#endif /* !M68K */
869#endif /* !POWERPC */
870#endif /* !I386 */
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +0000871#endif /* S390 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000872}
873
874int
875sys_siggetmask(tcp)
876struct tcb *tcp;
877{
878 if (exiting(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000879 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000880 long_to_sigset(tcp->u_rval, &sigm);
881 tcp->auxstr = sprintsigmask("mask ", &sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000882 }
883 return RVAL_HEX | RVAL_STR;
884}
885
886int
887sys_sigsuspend(tcp)
888struct tcb *tcp;
889{
890 if (entering(tcp)) {
891 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +0000892 long_to_sigset(tcp->u_arg[2], &sigm);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000893#if 0
894 /* first two are not really arguments, but print them anyway */
895 /* nevermind, they are an anachronism now, too bad... */
896 tprintf("%d, %#x, ", tcp->u_arg[0], tcp->u_arg[1]);
897#endif
Nate Sammons4a121431999-04-06 01:19:39 +0000898 printsigmask(&sigm, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000899 }
900 return 0;
901}
902
903#endif /* LINUX */
904
905#ifdef SVR4
906
907int
908sys_sigsuspend(tcp)
909struct tcb *tcp;
910{
911 sigset_t sigset;
912
913 if (entering(tcp)) {
914 if (umove(tcp, tcp->u_arg[0], &sigset) < 0)
915 tprintf("[?]");
916 else
Wichert Akkerman46956571999-11-26 10:12:59 +0000917 printsigmask(&sigset, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000918 }
919 return 0;
920}
921static struct xlat ucontext_flags[] = {
922 { UC_SIGMASK, "UC_SIGMASK" },
923 { UC_STACK, "UC_STACK" },
924 { UC_CPU, "UC_CPU" },
925#ifdef UC_FPU
926 { UC_FPU, "UC_FPU" },
927#endif
928#ifdef UC_INTR
929 { UC_INTR, "UC_INTR" },
930#endif
931 { 0, NULL },
932};
933
934#endif
935
936#if defined SVR4 || defined LINUX
937#if defined LINUX && !defined SS_ONSTACK
938#define SS_ONSTACK 1
939#define SS_DISABLE 2
940#if __GLIBC_MINOR__ == 0
941typedef struct
942{
943 __ptr_t ss_sp;
944 int ss_flags;
945 size_t ss_size;
946} stack_t;
947#endif
948#endif
949
950static struct xlat sigaltstack_flags[] = {
951 { SS_ONSTACK, "SS_ONSTACK" },
952 { SS_DISABLE, "SS_DISABLE" },
953 { 0, NULL },
954};
955#endif
956
957#ifdef SVR4
958static void
959printcontext(tcp, ucp)
960struct tcb *tcp;
961ucontext_t *ucp;
962{
963 tprintf("{");
964 if (!abbrev(tcp)) {
965 tprintf("uc_flags=");
966 if (!printflags(ucontext_flags, ucp->uc_flags))
967 tprintf("0");
968 tprintf(", uc_link=%#lx, ", (unsigned long) ucp->uc_link);
969 }
970 tprintf("uc_sigmask=");
Nate Sammons4a121431999-04-06 01:19:39 +0000971 printsigmask(ucp->uc_sigmask, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000972 if (!abbrev(tcp)) {
973 tprintf(", uc_stack={ss_sp=%#lx, ss_size=%d, ss_flags=",
974 (unsigned long) ucp->uc_stack.ss_sp,
975 ucp->uc_stack.ss_size);
976 if (!printflags(sigaltstack_flags, ucp->uc_stack.ss_flags))
977 tprintf("0");
978 tprintf("}");
979 }
980 tprintf(", ...}");
981}
982
983int
984sys_getcontext(tcp)
985struct tcb *tcp;
986{
987 ucontext_t uc;
988
989 if (entering(tcp)) {
990 if (!tcp->u_arg[0])
991 tprintf("NULL");
992 else if (umove(tcp, tcp->u_arg[0], &uc) < 0)
993 tprintf("{...}");
994 else
995 printcontext(tcp, &uc);
996 }
997 return 0;
998}
999
1000int
1001sys_setcontext(tcp)
1002struct tcb *tcp;
1003{
1004 ucontext_t uc;
1005
1006 if (entering(tcp)) {
1007 if (!tcp->u_arg[0])
1008 tprintf("NULL");
1009 else if (umove(tcp, tcp->u_arg[0], &uc) < 0)
1010 tprintf("{...}");
1011 else
1012 printcontext(tcp, &uc);
1013 }
1014 else {
1015 tcp->u_rval = tcp->u_error = 0;
1016 if (tcp->u_arg[0] == 0)
1017 return 0;
1018 return RVAL_NONE;
1019 }
1020 return 0;
1021}
1022
1023#endif /* SVR4 */
1024
1025#ifdef LINUX
1026
1027static int
1028print_stack_t(tcp, addr)
1029struct tcb *tcp;
1030unsigned long addr;
1031{
1032 stack_t ss;
1033 if (umove(tcp, addr, &ss) < 0)
1034 return -1;
1035 tprintf("{ss_sp=%#lx, ss_flags=", (unsigned long) ss.ss_sp);
1036 if (!printflags(sigaltstack_flags, ss.ss_flags))
1037 tprintf("0");
1038 tprintf(", ss_size=%lu}", (unsigned long) ss.ss_size);
1039 return 0;
1040}
1041
1042int
1043sys_sigaltstack(tcp)
1044 struct tcb *tcp;
1045{
1046 if (entering(tcp)) {
1047 if (tcp->u_arg[0] == 0)
1048 tprintf("NULL");
1049 else if (print_stack_t(tcp, tcp->u_arg[0]) < 0)
1050 return -1;
1051 }
1052 else {
1053 tprintf(", ");
1054 if (tcp->u_arg[1] == 0)
1055 tprintf("NULL");
1056 else if (print_stack_t(tcp, tcp->u_arg[1]) < 0)
1057 return -1;
1058 }
1059 return 0;
1060}
1061#endif
1062
1063#ifdef HAVE_SIGACTION
1064
1065int
1066sys_sigprocmask(tcp)
1067struct tcb *tcp;
1068{
1069#ifdef ALPHA
1070 if (entering(tcp)) {
1071 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1072 tprintf(", ");
Nate Sammons4a121431999-04-06 01:19:39 +00001073 printsigmask(tcp->u_arg[1], 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001074 }
1075 else if (!syserror(tcp)) {
Nate Sammons4a121431999-04-06 01:19:39 +00001076 tcp->auxstr = sprintsigmask("old mask ", tcp->u_rval, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001077 return RVAL_HEX | RVAL_STR;
1078 }
1079#else /* !ALPHA */
1080 sigset_t sigset;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001081
1082 if (entering(tcp)) {
1083#ifdef SVR4
1084 if (tcp->u_arg[0] == 0)
1085 tprintf("0");
1086 else
1087#endif /* SVR4 */
1088 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1089 tprintf(", ");
1090 if (!tcp->u_arg[1])
1091 tprintf("NULL, ");
Nate Sammons4a121431999-04-06 01:19:39 +00001092 else if (copy_sigset(tcp, tcp->u_arg[1], &sigset) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001093 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001094 else {
Nate Sammons4a121431999-04-06 01:19:39 +00001095 printsigmask(&sigset, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001096 tprintf(", ");
1097 }
1098 }
1099 else {
1100 if (!tcp->u_arg[2])
1101 tprintf("NULL");
1102 else if (syserror(tcp))
1103 tprintf("%#lx", tcp->u_arg[2]);
Nate Sammons4a121431999-04-06 01:19:39 +00001104 else if (copy_sigset(tcp, tcp->u_arg[2], &sigset) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001105 tprintf("[?]");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001106 else
Nate Sammons4a121431999-04-06 01:19:39 +00001107 printsigmask(&sigset, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001108 }
1109#endif /* !ALPHA */
1110 return 0;
1111}
1112
1113#endif /* HAVE_SIGACTION */
1114
1115int
1116sys_kill(tcp)
1117struct tcb *tcp;
1118{
1119 if (entering(tcp)) {
Nate Sammonsce780fc1999-03-29 23:23:13 +00001120 tprintf("%ld, %s", tcp->u_arg[0], signame(tcp->u_arg[1]));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001121 }
1122 return 0;
1123}
1124
1125int
1126sys_killpg(tcp)
1127struct tcb *tcp;
1128{
1129 return sys_kill(tcp);
1130}
1131
1132int
1133sys_sigpending(tcp)
1134struct tcb *tcp;
1135{
1136 sigset_t sigset;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001137
1138 if (exiting(tcp)) {
1139 if (syserror(tcp))
1140 tprintf("%#lx", tcp->u_arg[0]);
Nate Sammons4a121431999-04-06 01:19:39 +00001141 else if (copy_sigset(tcp, tcp->u_arg[0], &sigset) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001142 tprintf("[?]");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001143 else
Wichert Akkerman46956571999-11-26 10:12:59 +00001144 printsigmask(&sigset, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001145 }
1146 return 0;
1147}
1148
1149#ifdef LINUX
1150
1151 int
1152sys_rt_sigprocmask(tcp)
1153 struct tcb *tcp;
1154{
1155 sigset_t sigset;
1156
Nate Sammons4a121431999-04-06 01:19:39 +00001157 /* Note: arg[3] is the length of the sigset. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001158 if (entering(tcp)) {
1159 printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
1160 tprintf(", ");
1161 if (!tcp->u_arg[1])
1162 tprintf("NULL, ");
Nate Sammons4a121431999-04-06 01:19:39 +00001163 else if (copy_sigset_len(tcp, tcp->u_arg[1], &sigset, tcp->u_arg[3]) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001164 tprintf("%#lx, ", tcp->u_arg[1]);
1165 else {
Nate Sammons4a121431999-04-06 01:19:39 +00001166 printsigmask(&sigset, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001167 tprintf(", ");
1168 }
1169 }
1170 else {
1171 if (!tcp->u_arg[2])
1172
1173 tprintf("NULL");
1174 else if (syserror(tcp))
1175 tprintf("%#lx", tcp->u_arg[2]);
Nate Sammons4a121431999-04-06 01:19:39 +00001176 else if (copy_sigset_len(tcp, tcp->u_arg[2], &sigset, tcp->u_arg[3]) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001177 tprintf("[?]");
1178 else
Nate Sammons4a121431999-04-06 01:19:39 +00001179 printsigmask(&sigset, 1);
Nate Sammonsdab325a1999-03-29 23:33:35 +00001180 tprintf(", %lu", tcp->u_arg[3]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001181 }
1182 return 0;
1183}
1184
1185#if __GLIBC_MINOR__ < 1
1186/* Type for data associated with a signal. */
1187typedef union sigval
1188{
1189 int sival_int;
1190 void *sival_ptr;
1191} sigval_t;
1192
1193# define __SI_MAX_SIZE 128
1194# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 3)
1195
1196typedef struct siginfo
1197{
1198 int si_signo; /* Signal number. */
1199 int si_errno; /* If non-zero, an errno value associated with
1200 this signal, as defined in <errno.h>. */
1201 int si_code; /* Signal code. */
1202
1203 union
1204 {
1205 int _pad[__SI_PAD_SIZE];
1206
1207 /* kill(). */
1208 struct
1209 {
1210 __pid_t si_pid; /* Sending process ID. */
1211 __uid_t si_uid; /* Real user ID of sending process. */
1212 } _kill;
1213
1214 /* POSIX.1b timers. */
1215 struct
1216 {
1217 unsigned int _timer1;
1218 unsigned int _timer2;
1219 } _timer;
1220
1221 /* POSIX.1b signals. */
1222 struct
1223 {
1224 __pid_t si_pid; /* Sending process ID. */
1225 __uid_t si_uid; /* Real user ID of sending process. */
1226 sigval_t si_sigval; /* Signal value. */
1227 } _rt;
1228
1229 /* SIGCHLD. */
1230 struct
1231 {
1232 __pid_t si_pid; /* Which child. */
1233 int si_status; /* Exit value or signal. */
1234 __clock_t si_utime;
1235 __clock_t si_stime;
1236 } _sigchld;
1237
1238 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS. */
1239 struct
1240 {
1241 void *si_addr; /* Faulting insn/memory ref. */
1242 } _sigfault;
1243
1244 /* SIGPOLL. */
1245 struct
1246 {
1247 int si_band; /* Band event for SIGPOLL. */
1248 int si_fd;
1249 } _sigpoll;
1250 } _sifields;
1251} siginfo_t;
1252#endif
1253
1254/* Structure describing the action to be taken when a signal arrives. */
1255struct new_sigaction
1256{
1257 union
1258 {
1259 __sighandler_t __sa_handler;
1260 void (*__sa_sigaction) (int, siginfo_t *, void *);
1261 }
1262 __sigaction_handler;
1263 unsigned long sa_flags;
1264 void (*sa_restorer) (void);
1265 unsigned long int sa_mask[2];
1266};
1267
1268
1269 int
1270sys_rt_sigaction(tcp)
1271 struct tcb *tcp;
1272{
1273 struct new_sigaction sa;
1274 sigset_t sigset;
1275 long addr;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001276
1277 if (entering(tcp)) {
1278 printsignal(tcp->u_arg[0]);
1279 tprintf(", ");
1280 addr = tcp->u_arg[1];
1281 } else
1282 addr = tcp->u_arg[2];
1283 if (addr == 0)
1284 tprintf("NULL");
1285 else if (!verbose(tcp))
1286 tprintf("%#lx", addr);
1287 else if (umove(tcp, addr, &sa) < 0)
1288 tprintf("{...}");
1289 else {
1290 switch ((long) sa.__sigaction_handler.__sa_handler) {
1291 case (long) SIG_ERR:
1292 tprintf("{SIG_ERR}");
1293 break;
1294 case (long) SIG_DFL:
1295 tprintf("{SIG_DFL}");
1296 break;
1297 case (long) SIG_IGN:
1298 tprintf("{SIG_IGN}");
1299 break;
1300 default:
1301 tprintf("{%#lx, ",
1302 (long) sa.__sigaction_handler.__sa_handler);
Nate Sammons4a121431999-04-06 01:19:39 +00001303 sigemptyset(&sigset);
Wichert Akkermandacfb6e1999-06-03 14:21:07 +00001304#ifdef LINUXSPARC
1305 if (tcp->u_arg[4] <= sizeof(sigset))
1306 memcpy(&sigset, &sa.sa_mask, tcp->u_arg[4]);
1307#else
Nate Sammons4a121431999-04-06 01:19:39 +00001308 if (tcp->u_arg[3] <= sizeof(sigset))
1309 memcpy(&sigset, &sa.sa_mask, tcp->u_arg[3]);
Wichert Akkermandacfb6e1999-06-03 14:21:07 +00001310#endif
Nate Sammons4a121431999-04-06 01:19:39 +00001311 else
1312 memcpy(&sigset, &sa.sa_mask, sizeof(sigset));
1313 printsigmask(&sigset, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001314 tprintf(", ");
1315 if (!printflags(sigact_flags, sa.sa_flags))
1316 tprintf("0");
1317 tprintf("}");
1318 }
1319 }
1320 if (entering(tcp))
1321 tprintf(", ");
1322 else
Wichert Akkermandacfb6e1999-06-03 14:21:07 +00001323#ifdef LINUXSPARC
1324 tprintf(", %#lx, %lu", tcp->u_arg[3], tcp->u_arg[4]);
1325#elif defined(ALPHA)
1326 tprintf(", %lu, %#lx", tcp->u_arg[3], tcp->u_arg[4]);
1327#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001328 tprintf(", %lu", addr = tcp->u_arg[3]);
Wichert Akkermandacfb6e1999-06-03 14:21:07 +00001329#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001330 return 0;
1331}
1332
1333 int
1334sys_rt_sigpending(tcp)
1335 struct tcb *tcp;
1336{
1337 sigset_t sigset;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001338
1339 if (exiting(tcp)) {
1340 if (syserror(tcp))
1341 tprintf("%#lx", tcp->u_arg[0]);
Nate Sammons4a121431999-04-06 01:19:39 +00001342 else if (copy_sigset_len(tcp, tcp->u_arg[0],
1343 &sigset, tcp->u_arg[1]) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001344 tprintf("[?]");
1345 else
Wichert Akkerman46956571999-11-26 10:12:59 +00001346 printsigmask(&sigset, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001347 }
1348 return 0;
1349}
1350 int
1351sys_rt_sigsuspend(tcp)
1352 struct tcb *tcp;
1353{
1354 if (entering(tcp)) {
1355 sigset_t sigm;
Nate Sammons4a121431999-04-06 01:19:39 +00001356 if (copy_sigset_len(tcp, tcp->u_arg[0], &sigm, tcp->u_arg[1]) < 0)
1357 tprintf("[?]");
1358 else
1359 printsigmask(&sigm, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001360 }
1361 return 0;
1362}
1363#ifndef ILL_ILLOPC
1364#define ILL_ILLOPC 1 /* illegal opcode */
1365#define ILL_ILLOPN 2 /* illegal operand */
1366#define ILL_ILLADR 3 /* illegal addressing mode */
1367#define ILL_ILLTRP 4 /* illegal trap */
1368#define ILL_PRVOPC 5 /* privileged opcode */
1369#define ILL_PRVREG 6 /* privileged register */
1370#define ILL_COPROC 7 /* coprocessor error */
1371#define ILL_BADSTK 8 /* internal stack error */
1372#define FPE_INTDIV 1 /* integer divide by zero */
1373#define FPE_INTOVF 2 /* integer overflow */
1374#define FPE_FLTDIV 3 /* floating point divide by zero */
1375#define FPE_FLTOVF 4 /* floating point overflow */
1376#define FPE_FLTUND 5 /* floating point underflow */
1377#define FPE_FLTRES 6 /* floating point inexact result */
1378#define FPE_FLTINV 7 /* floating point invalid operation */
1379#define FPE_FLTSUB 8 /* subscript out of range */
1380#define SEGV_MAPERR 1 /* address not mapped to object */
1381#define SEGV_ACCERR 2 /* invalid permissions for mapped object */
1382#define BUS_ADRALN 1 /* invalid address alignment */
1383#define BUS_ADRERR 2 /* non-existant physical address */
1384#define BUS_OBJERR 3 /* object specific hardware error */
1385#define TRAP_BRKPT 1 /* process breakpoint */
1386#define TRAP_TRACE 2 /* process trace trap */
1387#define CLD_EXITED 1 /* child has exited */
1388#define CLD_KILLED 2 /* child was killed */
1389#define CLD_DUMPED 3 /* child terminated abnormally */
1390#define CLD_TRAPPED 4 /* traced child has trapped */
1391#define CLD_STOPPED 5 /* child has stopped */
1392#define CLD_CONTINUED 6 /* stopped child has continued */
1393#define POLL_IN 1 /* data input available */
1394#define POLL_OUT 2 /* output buffers available */
1395#define POLL_MSG 3 /* input message available */
1396#define POLL_ERR 4 /* i/o error */
1397#define POLL_PRI 5 /* high priority input available */
1398#define POLL_HUP 6 /* device disconnected */
1399#define SI_USER 0 /* sent by kill, sigsend, raise */
1400#define SI_QUEUE -1 /* sent by sigqueue */
1401#define SI_TIMER -2 /* sent by timer expiration */
1402#define SI_MESGQ -3 /* sent by real time mesq state change */
1403#define SI_ASYNCIO -4 /* sent by AIO completion */
1404#else
1405#undef si_pid
1406#undef si_uid
1407#undef si_status
1408#undef si_utime
1409#undef si_stime
1410#undef si_value
1411#undef si_int
1412#undef si_ptr
1413#undef si_addr
1414#undef si_band
1415#undef si_fd
1416#endif
1417
1418static struct xlat sigill_flags[] = {
1419 {ILL_ILLOPC, "ILL_ILLOPC"},
1420 {ILL_ILLOPN, "ILL_ILLOPN"},
1421 {ILL_ILLADR, "ILL_ILLADR"},
1422 {ILL_ILLTRP, "ILL_ILLTRP"},
1423 {ILL_PRVOPC, "ILL_PRVOPC"},
1424 {ILL_PRVREG, "ILL_PRVREG"},
1425 {ILL_COPROC, "ILL_COPROC"},
1426 {ILL_BADSTK, "ILL_BADSTK"},
1427 {0, NULL}
1428};
1429
1430static struct xlat sigfpe_flags[] = {
1431 {FPE_INTDIV, "FPE_INTDIV"},
1432 {FPE_INTOVF, "FPE_INTOVF"},
1433 {FPE_FLTDIV, "FPE_FLTDIV"},
1434 {FPE_FLTOVF, "FPE_FLTOVF"},
1435 {FPE_FLTUND, "FPE_FLTUND"},
1436 {FPE_FLTRES, "FPE_FLTRES"},
1437 {FPE_FLTINV, "FPE_FLTINV"},
1438 {FPE_FLTSUB, "FPE_FLTSUB"},
1439 {0, NULL}
1440};
1441
1442static struct xlat sigsegv_flags[] = {
1443 {SEGV_MAPERR, "SEGV_MAPERR"},
1444 {SEGV_ACCERR, "SEGV_ACCERR"},
1445 {0, NULL}
1446};
1447
1448static struct xlat sigbus_flags[] = {
1449 {BUS_ADRALN, "BUS_ADRALN"},
1450 {BUS_ADRERR, "BUS_ADRERR"},
1451 {BUS_OBJERR, "BUS_OBJERR"},
1452 {0, NULL}
1453};
1454
1455static struct xlat sigtrap_flags[] = {
1456 {TRAP_BRKPT, "TRAP_BRKPT"},
1457 {TRAP_TRACE, "TRAP_TRACE"},
1458 {0, NULL}
1459};
1460
1461static struct xlat sigchld_flags[] = {
1462 {CLD_EXITED, "CLD_EXITED"},
1463 {CLD_KILLED, "CLD_KILLED"},
1464 {CLD_DUMPED, "CLD_DUMPED"},
1465 {CLD_TRAPPED, "CLD_TRAPPED"},
1466 {CLD_STOPPED, "CLD_STOPPED"},
1467 {CLD_CONTINUED, "CLD_CONTINUED"},
1468 {0, NULL}
1469};
1470
1471static struct xlat sigpoll_flags[] = {
1472 {POLL_IN, "POLL_IN"},
1473 {POLL_OUT, "POLL_OUT"},
1474 {POLL_MSG, "POLL_MSG"},
1475 {POLL_ERR, "POLL_ERR"},
1476 {POLL_PRI, "POLL_PRI"},
1477 {POLL_HUP, "POLL_HUP"},
1478 {0, NULL}
1479};
1480
1481static struct xlat siginfo_flags[] = {
1482 {SI_USER, "SI_USER"},
1483 {SI_QUEUE, "SI_QUEUE"},
1484 {SI_TIMER, "SI_TIMER"},
1485 {SI_MESGQ, "SI_MESGQ"},
1486 {SI_ASYNCIO, "SI_ASYNCIO"},
1487 {0, NULL}
1488};
1489
1490 static void
1491printsiginfo(tcp, si)
1492 struct tcb *tcp;
1493 siginfo_t *si;
1494{
1495 tprintf("{si_signo=");
1496 printsignal(si->si_signo);
1497 tprintf(", si_errno=%d, si_code=", si->si_errno);
1498 switch(si->si_signo)
1499 {
1500 case SIGILL:
1501 if (!printflags(sigill_flags, si->si_code))
1502 tprintf("%d /* ILL_??? */", si->si_code);
1503 tprintf(", si_addr=%lx",
1504 (unsigned long) si->_sifields._sigfault.si_addr);
1505 break;
1506 case SIGFPE:
1507 if (!printflags(sigfpe_flags, si->si_code))
1508 tprintf("%d /* FPE_??? */", si->si_code);
1509 tprintf(", si_addr=%lx",
1510 (unsigned long) si->_sifields._sigfault.si_addr);
1511 break;
1512 case SIGSEGV:
1513 if (!printflags(sigsegv_flags, si->si_code))
1514 tprintf("%d /* SEGV_??? */", si->si_code);
1515 tprintf(", si_addr=%lx",
1516 (unsigned long) si->_sifields._sigfault.si_addr);
1517 break;
1518 case SIGBUS:
1519 if (!printflags(sigbus_flags, si->si_code))
1520 tprintf("%d /* BUS_??? */", si->si_code);
1521 tprintf(", si_addr=%lx",
1522 (unsigned long) si->_sifields._sigfault.si_addr);
1523 break;
1524 case SIGTRAP:
1525 if (!printflags(sigtrap_flags, si->si_code))
1526 tprintf("%d /* TRAP_??? */", si->si_code);
1527 break;
1528 case SIGCHLD:
1529 if (!printflags(sigchld_flags, si->si_code))
1530 tprintf("%d /* CLD_??? */", si->si_code);
1531 if (!verbose(tcp))
1532 tprintf(", ...");
1533 else
1534 tprintf(", si_pid=%d, si_uid=%d, si_status=%d, si_utime=%lu, si_stime=%lu",
1535 si->_sifields._kill.si_pid,
1536 si->_sifields._kill.si_uid,
1537 si->_sifields._sigchld.si_status,
1538 si->_sifields._sigchld.si_utime,
1539 si->_sifields._sigchld.si_stime);
1540 break;
1541 case SIGPOLL:
1542 if (!printflags(sigpoll_flags, si->si_code))
1543 tprintf("%d /* POLL_??? */", si->si_code);
1544 if (si->si_code == POLL_IN
1545 || si->si_code == POLL_OUT
1546 || si->si_code == POLL_MSG)
1547 tprintf(", si_bind=%lu, si_fd=%d",
1548 (unsigned long) si->_sifields._sigpoll.si_band,
1549 si->_sifields._sigpoll.si_fd);
1550 break;
1551 default:
1552 if (!printflags(siginfo_flags, si->si_code))
1553 tprintf("%d /* SI_??? */", si->si_code);
1554 tprintf(", si_pid=%lu, si_uid=%lu, si_value={",
1555 (unsigned long) si->_sifields._rt.si_pid,
1556 (unsigned long) si->_sifields._rt.si_uid);
1557 if (!verbose(tcp))
1558 tprintf("...");
1559 else {
1560 tprintf("sival_int=%u, sival_ptr=%#lx",
1561 si->_sifields._rt.si_sigval.sival_int,
1562 (unsigned long) si->_sifields._rt.si_sigval.sival_ptr);
1563 }
1564 tprintf("}");
1565 break;
1566 }
1567 tprintf("}");
1568}
1569
1570 int
1571sys_rt_sigqueueinfo(tcp)
1572 struct tcb *tcp;
1573{
1574 if (entering(tcp)) {
1575 siginfo_t si;
1576 tprintf("%lu, ", tcp->u_arg[0]);
1577 printsignal(tcp->u_arg[1]);
1578 tprintf(", ");
1579 if (umove(tcp, tcp->u_arg[2], &si) < 0)
1580 tprintf("%#lx", tcp->u_arg[2]);
1581 else
1582 printsiginfo(&si);
1583 }
1584 return 0;
1585}
1586
1587int sys_rt_sigtimedwait(tcp)
1588 struct tcb *tcp;
1589{
1590 if (entering(tcp)) {
1591 sigset_t sigset;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001592
Nate Sammons4a121431999-04-06 01:19:39 +00001593 if (copy_sigset_len(tcp, tcp->u_arg[0],
1594 &sigset, tcp->u_arg[3]) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001595 tprintf("[?]");
1596 else
Wichert Akkerman46956571999-11-26 10:12:59 +00001597 printsigmask(&sigset, 1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001598 tprintf(", ");
1599 }
1600 else {
1601 if (syserror(tcp))
1602 tprintf("%#lx", tcp->u_arg[0]);
1603 else {
1604 siginfo_t si;
1605 if (umove(tcp, tcp->u_arg[1], &si) < 0)
1606 tprintf("%#lx", tcp->u_arg[1]);
1607 else
1608 printsiginfo(&si);
1609 /* XXX For now */
1610 tprintf(", %#lx", tcp->u_arg[2]);
1611 tprintf(", %d", (int) tcp->u_arg[3]);
1612 }
1613 }
1614 return 0;
1615};
1616
1617#endif /* LINUX */
1618