Skip to content
Snippets Groups Projects
Commit 15dfac35 authored by Nadav Har'El's avatar Nadav Har'El Committed by Pekka Enberg
Browse files

signal handling: support SA_RESETHAND


Add support for SA_RESETHAND signal handler flag, which means that the signal
handler is reset to the default one after handling the signal once.

I admit it's not a very useful feature (our default handler is powering off
the system...) but no reason not to support it.

Signed-off-by: default avatarNadav Har'El <nyh@cloudius-systems.com>
Signed-off-by: default avatarPekka Enberg <penberg@cloudius-systems.com>
parent 80c94e43
No related branches found
No related tags found
No related merge requests found
...@@ -223,12 +223,20 @@ int kill(pid_t pid, int sig) ...@@ -223,12 +223,20 @@ int kill(pid_t pid, int sig)
// very Unix-like behavior, but if we assume that the program doesn't // very Unix-like behavior, but if we assume that the program doesn't
// care which of its threads handle the signal - why not just create // care which of its threads handle the signal - why not just create
// a completely new thread and run it there... // a completely new thread and run it there...
const auto& sa = signal_actions[sig]; const auto sa = signal_actions[sig];
auto t = new sched::thread([=] { auto t = new sched::thread([=] {
if (sa.sa_flags & SA_RESETHAND) {
signal_actions[sig].sa_flags = 0;
signal_actions[sig].sa_handler = SIG_DFL;
}
if (sa.sa_flags & SA_SIGINFO) { if (sa.sa_flags & SA_SIGINFO) {
// FIXME: proper second (siginfo) and third (context) arguments (See example in call_signal_handler) // FIXME: proper second (siginfo) and third (context) arguments (See example in call_signal_handler)
sa.sa_sigaction(sig, nullptr, nullptr); sa.sa_sigaction(sig, nullptr, nullptr);
} else { } else {
if (sa.sa_flags & SA_RESETHAND) {
signal_actions[sig].sa_flags = 0;
signal_actions[sig].sa_handler = SIG_DFL;
}
sa.sa_handler(sig); sa.sa_handler(sig);
} }
}, sched::thread::attr().detached().stack(65536).name("signal_handler")); }, sched::thread::attr().detached().stack(65536).name("signal_handler"));
......
...@@ -113,6 +113,36 @@ int main(int ac, char** av) ...@@ -113,6 +113,36 @@ int main(int ac, char** av)
report(recv_result == -1, "timed out syscall returns -1"); report(recv_result == -1, "timed out syscall returns -1");
report(recv_errno == EWOULDBLOCK, "timed out syscall doesn't return EINTR"); report(recv_errno == EWOULDBLOCK, "timed out syscall doesn't return EINTR");
// Test with and without SA_RESETHAND (for __sysv_signal support)
struct sigaction act = {};
act.sa_handler = handler1;
global = 0;
r = sigaction(SIGUSR1, &act, nullptr);
report(r == 0, "set SIGUSR1 handler");
r = kill(0, SIGUSR1);
report(r == 0, "kill SIGUSR1 succeeds");
for (int i=0; i<100; i++) {
if (global == 1) break;
usleep(10000);
}
report(global == 1, "'global' is now 1");
struct sigaction oldact;
r = sigaction(SIGUSR1, nullptr, &oldact);
report(r == 0 && oldact.sa_handler == handler1, "without SA_RESETHAND, signal handler is not reset");
act.sa_flags = SA_RESETHAND;
r = sigaction(SIGUSR1, &act, nullptr);
report(r == 0, "set SIGUSR1 handler with SA_RESETHAND");
r = kill(0, SIGUSR1);
report(r == 0, "kill SIGUSR1 succeeds");
for (int i=0; i<100; i++) {
if (global == 1) break;
usleep(10000);
}
report(global == 1, "'global' is now 1");
r = sigaction(SIGUSR1, nullptr, &oldact);
report(r == 0 && oldact.sa_handler == SIG_DFL, "with SA_RESETHAND, signal handler is reset");
debug("SUMMARY: %d tests, %d failures\n", tests, fails); debug("SUMMARY: %d tests, %d failures\n", tests, fails);
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment