diff options
author | Elliott Hughes <enh@google.com> | 2013-02-21 11:22:23 -0800 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2013-02-21 11:22:23 -0800 |
commit | fae89fc4042ee4c360842234dfda7831c313bd44 (patch) | |
tree | aa35c41ee98aad9b065591a5497515163534e956 /tests/signal_test.cpp | |
parent | ccd403161cdcc88a0ffcaecd1bc707e2d4c88a1c (diff) | |
download | android_bionic-fae89fc4042ee4c360842234dfda7831c313bd44.tar.gz android_bionic-fae89fc4042ee4c360842234dfda7831c313bd44.tar.bz2 android_bionic-fae89fc4042ee4c360842234dfda7831c313bd44.zip |
Fix raise(3) so it works in signal handlers.
We could special-case raise(3) in non-threaded programs, but the more
conservative course is to make pthread_kill(3) work in signal handlers
at the cost of a race shared by other C libraries.
Change-Id: I59fb23d03bdabf403435e731704b33acdf3e0234
Diffstat (limited to 'tests/signal_test.cpp')
-rw-r--r-- | tests/signal_test.cpp | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/tests/signal_test.cpp b/tests/signal_test.cpp index b100372c9..e41dc1cb5 100644 --- a/tests/signal_test.cpp +++ b/tests/signal_test.cpp @@ -76,6 +76,25 @@ static void TestSigSet2(Fn fn) { ASSERT_EQ(0, errno); } +class ScopedSignalHandler { + public: + ScopedSignalHandler(int signal_number, void (*handler)(int)) : signal_number_(signal_number) { + sigemptyset(&action_.sa_mask); + action_.sa_flags = 0; + action_.sa_handler = handler; + sigaction(signal_number_, &action_, &old_action_); + } + + ~ScopedSignalHandler() { + sigaction(signal_number_, &old_action_, NULL); + } + + private: + struct sigaction action_; + struct sigaction old_action_; + const int signal_number_; +}; + TEST(signal, sigismember_invalid) { TestSigSet2(sigismember); } @@ -102,16 +121,25 @@ TEST(signal, raise_invalid) { ASSERT_EQ(EINVAL, errno); } +static void raise_in_signal_handler_helper(int signal_number) { + ASSERT_EQ(SIGALRM, signal_number); + static int count = 0; + if (++count == 1) { + raise(SIGALRM); + } +} + +TEST(signal, raise_in_signal_handler) { + ScopedSignalHandler ssh(SIGALRM, raise_in_signal_handler_helper); + raise(SIGALRM); +} + static void HandleSIGALRM(int signal_number) { ASSERT_EQ(SIGALRM, signal_number); } TEST(signal, sigwait) { - struct sigaction action; - sigemptyset(&action.sa_mask); - action.sa_flags = 0; - action.sa_handler = HandleSIGALRM; - sigaction(SIGALRM, &action, NULL); + ScopedSignalHandler ssh(SIGALRM, HandleSIGALRM); sigset_t wait_set; sigemptyset(&wait_set); |