[LTP] [RFC PATCH] A draft of the rt_sigaction syscall wrapper.

Stanislav Kholmanskikh
2014-05-20T12:24:57Z

I think that instead of an addition of "the common syscall preparation" to a define,
it would be better to implement a wrapper to the rt_sigaction syscall.

Like this one.

Its basis is a combination of glibc implementations of sigaction() for different
platforms. But it also accepts '-1' for act, oact to check EFAULT errno code
(glibc implementation doesn't handle such a situtation).

How do you think where the best place is to put this wrapper implementation?

Thank you.

.../kernel/syscalls/rt_sigaction/rt_sigaction01.c | 86 ++++++++++++++++---
1 files changed, 72 insertions(+), 14 deletions(-)

diff --git a/testcases/kernel/syscalls/rt_sigaction/rt_sigaction01.c b/testcases/kernel/syscalls/rt_sigaction/rt_sigaction01.c
index 8f18394..8516396 100644
--- a/testcases/kernel/syscalls/rt_sigaction/rt_sigaction01.c
+++ b/testcases/kernel/syscalls/rt_sigaction/rt_sigaction01.c
@@ -60,6 +60,76 @@ char *TCID = "rt_sigaction01";
int testno;
int TST_TOTAL = 1;

+#define INVAL_SA_PTR ((void *)-1)
+
+/* This is a wrapper for __NR_rt_sigaction syscall.
+ * act/oact values of INVAL_SA_PTR is used to pass
+ * an invalid pointer to syscall(__NR_rt_sigaction).
+ *
+ * Based on glibc/sysdeps/unix/sysv/linux/{...}/sigaction.c
+ */
+static int ltp_rt_sigaction(int signum, const struct sigaction *act,
+ struct sigaction *oact, size_t sigsetsize)
+{
+ int ret;
+ struct kernel_sigaction kact, koact;
+ struct kernel_sigaction *kact_p = NULL;
+ struct kernel_sigaction *koact_p = NULL;
+
+ if (act == INVAL_SA_PTR) {
+ kact_p = INVAL_SA_PTR;
+ } else if (act) {
+ kact.k_sa_handler = act->sa_handler;
+ memcpy(&kact.sa_mask, &act->sa_mask, sizeof(sigset_t));
+ kact.sa_flags = act->sa_flags;
+ kact.sa_restorer = NULL;
+
+ kact_p = &kact;
+ }
+
+ if (oact == INVAL_SA_PTR)
+ koact_p = INVAL_SA_PTR;
+ else if (oact)
+ koact_p = &koact;
+
+#ifdef __sparc__
+# ifdef __arch64__
+ unsigned long stub = ((unsigned long) &__rt_sigreturn_stub) - 8;
+# else
+ unsigned long stub = ((unsigned long) &__sigreturn_stub) - 8;
+# endif
+#endif
+
+#ifdef __x86_64__
+ sig_initial(signum);
+ kact.sa_flags |= SA_RESTORER;
+ kact.sa_restorer = restore_rt;
+#endif
+
+#ifdef __sparc__
+ ret = ltp_syscall(__NR_rt_sigaction, signum,
+ kact_p , koact_p,
+ stub, sigsetsize);
+#else
+ ret = ltp_syscall(__NR_rt_sigaction, signum,
+ kact_p, koact_p,
+ sigsetsize);
+#endif
+
+ if (ret >= 0) {
+ if (oact && (oact != INVAL_SA_PTR)) {
+ oact->sa_handler = koact.k_sa_handler;
+ memcpy(&oact->sa_mask, &koact.sa_mask,
+ sizeof(sigset_t));
+ oact->sa_flags = koact.sa_flags;
+ oact->sa_restorer = koact.sa_restorer;
+ }
+ }
+
+ return ret;
+}
+
+
/* Extern Global Functions */
/******************************************************************************/
/* */
@@ -127,21 +197,14 @@ void handler(int sig)

int set_handler(int sig, int sig_to_mask, int mask_flags)
{
-#ifdef __x86_64__
- struct kernel_sigaction sa, oldaction;
- mask_flags |= SA_RESTORER;
- sa.sa_restorer = restore_rt;
- sa.k_sa_handler = (void *)handler;
-#else
struct sigaction sa, oldaction;
+
sa.sa_handler = (void *)handler;
-#endif
sa.sa_flags = mask_flags;
sigemptyset(&sa.sa_mask);
sigaddset(&sa.sa_mask, sig);

- return ltp_syscall(__NR_rt_sigaction, sig, &sa, &oldaction, SIGSETSIZE);
-
+ return ltp_rt_sigaction(sig, &sa, &oldaction, SIGSETSIZE);
}

int main(int ac, char **av)
@@ -163,11 +226,6 @@ int main(int ac, char **av)
for (testno = 0; testno < TST_TOTAL; ++testno) {

for (signal = SIGRTMIN; signal <= (SIGRTMAX); signal++) { //signal for 34 to 65
-
-#ifdef __x86_64__
- sig_initial(signal);
-#endif
-
for (flag = 0;
flag <
(sizeof(test_flags) /
--
1.7.1

------------------------------------------------------------------------------
"Accelerate Dev Cycles with Automated Cross-Browser Testing - For FREE
Instantly run your Selenium tests across 300+ browser/OS combos.
Get unparalleled scalability from the best Selenium testing platform available
Simple to use. Nothing to install. Get started now for free."