[PATCH] alpha: fix decode of osf_sigprocmask

Mike Frysinger vapier at gentoo.org
Thu Mar 15 04:45:33 UTC 2012


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 at gentoo.org>
---

 linux/alpha/syscallent.h |    2 +-
 signal.c                 |   18 ++++++++++++++++--
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/linux/alpha/syscallent.h b/linux/alpha/syscallent.h
index c7297cd..85c341a 100644
--- a/linux/alpha/syscallent.h
+++ b/linux/alpha/syscallent.h
@@ -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 */
diff --git a/signal.c b/signal.c
index dc0064b..dfa0bfc 100644
--- a/signal.c
+++ b/signal.c
@@ -1179,13 +1179,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 */
-- 
1.7.8.5





More information about the Strace-devel mailing list