From 2283e25cde0fc2683607ed291af95564703956ed Mon Sep 17 00:00:00 2001
From: Graham MacDonald <grahamamacdonald@gmail.com>
Date: Tue, 14 Apr 2020 23:37:54 +0100
Subject: [PATCH] sigaction should set sigaction.sa_restorer

---
 src/header/signal/mod.rs        |  1 +
 tests/Makefile                  |  1 +
 tests/expected/sigaction.stderr |  0
 tests/expected/sigaction.stdout |  5 ++++
 tests/sigaction.c               | 45 +++++++++++++++++++++++++++++++++
 5 files changed, 52 insertions(+)
 create mode 100644 tests/expected/sigaction.stderr
 create mode 100644 tests/expected/sigaction.stdout
 create mode 100644 tests/sigaction.c

diff --git a/src/header/signal/mod.rs b/src/header/signal/mod.rs
index c7868326..1b153c5b 100644
--- a/src/header/signal/mod.rs
+++ b/src/header/signal/mod.rs
@@ -89,6 +89,7 @@ pub unsafe extern "C" fn sigaction(
     let act_opt = act.as_ref().map(|act| {
         let mut act_clone = act.clone();
         act_clone.sa_flags |= SA_RESTORER as c_ulong;
+        act_clone.sa_restorer = Some(__restore_rt);
         act_clone
     });
     Sys::sigaction(sig, act_opt.as_ref(), oact.as_mut())
diff --git a/tests/Makefile b/tests/Makefile
index 9a25da59..716600fa 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -23,6 +23,7 @@ EXPECT_NAMES=\
 	regex \
 	select \
 	setjmp \
+	sigaction \
 	signal \
 	stdio/all \
 	stdio/buffer \
diff --git a/tests/expected/sigaction.stderr b/tests/expected/sigaction.stderr
new file mode 100644
index 00000000..e69de29b
diff --git a/tests/expected/sigaction.stdout b/tests/expected/sigaction.stdout
new file mode 100644
index 00000000..8a6d2448
--- /dev/null
+++ b/tests/expected/sigaction.stdout
@@ -0,0 +1,5 @@
+Raising...
+Signal handler1 called!
+Raising...
+Signal handler2 called!
+Raised.
diff --git a/tests/sigaction.c b/tests/sigaction.c
new file mode 100644
index 00000000..245ad3b7
--- /dev/null
+++ b/tests/sigaction.c
@@ -0,0 +1,45 @@
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "test_helpers.h"
+
+void handler1(int sig) {
+    ERROR_IF(handler, sig, != SIGUSR1);
+    puts("Signal handler1 called!");
+}
+
+void handler2(int sig) {
+    ERROR_IF(handler, sig, != SIGUSR1);
+    puts("Signal handler2 called!");
+}
+
+int main(void) {
+	struct sigaction sa1 = { .sa_handler = handler1 };
+    struct sigaction sa2 = { .sa_handler = handler2 };
+    struct sigaction saold = {0};
+
+	sigemptyset(&sa1.sa_mask);
+    sigemptyset(&sa2.sa_mask);
+
+    int rcode = sigaction(SIGUSR1, &sa1, NULL);
+    ERROR_IF(signal, rcode, != 0);
+
+    puts("Raising...");
+
+    int raise_status = raise(SIGUSR1);
+    ERROR_IF(raise, raise_status, < 0);
+
+	rcode = sigaction(SIGUSR1, &sa2, &saold);
+    ERROR_IF(signal, rcode, != 0);
+    ERROR_IF(signal, saold.sa_handler, != sa1.sa_handler);
+
+    puts("Raising...");
+
+    raise_status = raise(SIGUSR1);
+    ERROR_IF(raise, raise_status, < 0);
+
+    puts("Raised.");
+}
-- 
GitLab