]> granicus.if.org Git - strace/commitdiff
alpha: fix decode of osf_sigprocmask
authorMike Frysinger <vapier@gentoo.org>
Thu, 15 Mar 2012 04:45:33 +0000 (00:45 -0400)
committerDmitry V. Levin <ldv@altlinux.org>
Thu, 15 Mar 2012 20:14:17 +0000 (20:14 +0000)
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>
linux/alpha/syscallent.h
signal.c

index c7297cd0b4404c52f63f6fe9dbfce9e853de970b..85c341a40b8336cbb74c94e8ed3fb8c803703e1a 100644 (file)
@@ -76,7 +76,7 @@
        { 3,    TD|TF,  sys_open,               "open"                  }, /* 45 */
        { 5,    0,      printargs,              "osf_old_sigaction"     }, /* 46, not implemented */
        { 1,    NF,     sys_getgid,             "getxgid"               }, /* 47 */
-       { 3,    TS,     printargs,              "osf_sigprocmask"       }, /* 48 */
+       { 2,    TS,     sys_sigprocmask,        "osf_sigprocmask"       }, /* 48 */
        { 5,    0,      printargs,              "osf_getlogin"          }, /* 49, not implemented */
        { 5,    0,      printargs,              "osf_setlogin"          }, /* 50, not implemented */
        { 1,    TF,     sys_acct,               "acct"                  }, /* 51 */
index bffdec042abfbf0b4d7deaa32723d1b3e9e55ae5..5ff89e43bb26a8310957e6d3b32bb46196a38ded 100644 (file)
--- 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 */