summaryrefslogtreecommitdiff
path: root/signal.c
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2012-03-15 00:45:33 -0400
committerDmitry V. Levin <ldv@altlinux.org>2012-03-15 20:14:17 +0000
commitdde045c13f77ca477aa59e19d0b50ae4afa906b6 (patch)
treee7c000ef625a75d260545b4fb741f0c5ba2ea699 /signal.c
parent384b0ada7d821f3797bf5d72dcf096032d662193 (diff)
downloadstrace-dde045c13f77ca477aa59e19d0b50ae4afa906b6.tar.gz
strace-dde045c13f77ca477aa59e19d0b50ae4afa906b6.tar.bz2
strace-dde045c13f77ca477aa59e19d0b50ae4afa906b6.tar.xz
alpha: fix decode of osf_sigprocmask
The alpha sigprocmask syscall is special in that it comes from OSF rather than the style that everyone else uses. Tested with this simple code: $ cat test.c #include <signal.h> main() { sigset_t set, oldset; sigemptyset(&set); sigaddset(&set, SIGINT); sigaddset(&set, SIGHUP); sigprocmask(SIG_SETMASK, &set, &oldset); sigprocmask(SIG_UNBLOCK, &oldset, &set); sleep(3); } $ gcc test.c && ./strace ./a.out ... osf_sigprocmask(SIG_SETMASK, [HUP INT]) = 0 (old mask []) osf_sigprocmask(SIG_UNBLOCK, []) = 0x3 (old mask [HUP INT]) osf_sigprocmask(SIG_BLOCK, [CHLD]) = 0x3 (old mask [HUP INT]) ... * linux/alpha/syscallent.h: Call sys_sigprocmask for osf_sigprocmask, and change number of arguments to two. * signal.c (sys_sigprocmask): Fix decoding of alpha osf sigprocmask. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'signal.c')
-rw-r--r--signal.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/signal.c b/signal.c
index bffdec0..5ff89e4 100644
--- a/signal.c
+++ b/signal.c
@@ -1180,13 +1180,27 @@ int
sys_sigprocmask(struct tcb *tcp)
{
#ifdef ALPHA
+ sigset_t ss;
if (entering(tcp)) {
+ /*
+ * Alpha/OSF is different: it doesn't pass in two pointers,
+ * but rather passes in the new bitmask as an argument and
+ * then returns the old bitmask. This "works" because we
+ * only have 64 signals to worry about. If you want more,
+ * use of the rt_sigprocmask syscall is required.
+ * Alpha:
+ * old = osf_sigprocmask(how, new);
+ * Everyone else:
+ * ret = sigprocmask(how, &new, &old, ...);
+ */
+ memcpy(&ss, &tcp->u_arg[1], sizeof(long));
printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???");
tprints(", ");
- printsigmask(tcp->u_arg[1], 0);
+ printsigmask(&ss, 0);
}
else if (!syserror(tcp)) {
- tcp->auxstr = sprintsigmask("old mask ", tcp->u_rval, 0);
+ memcpy(&ss, &tcp->u_rval, sizeof(long));
+ tcp->auxstr = sprintsigmask("old mask ", &ss, 0);
return RVAL_HEX | RVAL_STR;
}
#else /* !ALPHA */