mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 15:03:34 +00:00
Discard ignored signals on New Technology (#592)
This commit is contained in:
parent
4b4ea046c4
commit
7de2f229a7
4 changed files with 57 additions and 1 deletions
|
@ -31,6 +31,7 @@ bool __sig_handle(bool, int, int, ucontext_t *) hidden;
|
||||||
int __sig_add(int, int) hidden;
|
int __sig_add(int, int) hidden;
|
||||||
int __sig_mask(int, const sigset_t *, sigset_t *) hidden;
|
int __sig_mask(int, const sigset_t *, sigset_t *) hidden;
|
||||||
int __sig_raise(int, int) hidden;
|
int __sig_raise(int, int) hidden;
|
||||||
|
void __sig_check_ignore(const int, const unsigned) hidden;
|
||||||
|
|
||||||
COSMOPOLITAN_C_END_
|
COSMOPOLITAN_C_END_
|
||||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||||
|
|
|
@ -246,7 +246,7 @@ textwindows int __sig_add(int sig, int si_code) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enqueues generic signal for delivery on New Technology.
|
* Checks for unblocked signals and delivers them on New Technology.
|
||||||
*
|
*
|
||||||
* @param restartable is for functions like read() but not poll()
|
* @param restartable is for functions like read() but not poll()
|
||||||
* @return true if EINTR should be returned by caller
|
* @return true if EINTR should be returned by caller
|
||||||
|
@ -264,3 +264,38 @@ textwindows bool __sig_check(bool restartable) {
|
||||||
}
|
}
|
||||||
return delivered;
|
return delivered;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if a signal should be ignored and if so discards existing
|
||||||
|
* instances of said signal on New Technology.
|
||||||
|
*
|
||||||
|
* Even blocked signals are discarded.
|
||||||
|
*
|
||||||
|
* @param sig the signal number to remove
|
||||||
|
* @threadsafe
|
||||||
|
*/
|
||||||
|
textwindows void __sig_check_ignore(const int sig, const unsigned rva) {
|
||||||
|
struct Signal *cur, *prev, *next;
|
||||||
|
if (rva != (unsigned)(intptr_t)SIG_IGN &&
|
||||||
|
(rva != (unsigned)(intptr_t)SIG_DFL || __sig_isfatal(sig))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (__sig.queue) {
|
||||||
|
__sig_lock();
|
||||||
|
for (prev = 0, cur = __sig.queue; cur; cur = next) {
|
||||||
|
next = cur->next;
|
||||||
|
if (sig == cur->sig) {
|
||||||
|
if (cur == __sig.queue) {
|
||||||
|
__sig.queue = cur->next;
|
||||||
|
} else if (prev) {
|
||||||
|
prev->next = cur->next;
|
||||||
|
}
|
||||||
|
__sig_handle(false, cur->sig, cur->si_code, 0);
|
||||||
|
__sig_free(cur);
|
||||||
|
} else {
|
||||||
|
prev = cur;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
__sig_unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -258,6 +258,7 @@ static int __sigaction(int sig, const struct sigaction *act,
|
||||||
if (act) {
|
if (act) {
|
||||||
__sighandrvas[sig] = rva;
|
__sighandrvas[sig] = rva;
|
||||||
__sighandflags[sig] = act->sa_flags;
|
__sighandflags[sig] = act->sa_flags;
|
||||||
|
__sig_check_ignore(sig, rva);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
|
|
|
@ -156,3 +156,22 @@ noubsan void ubsanTrumpsSystemsEngineering(void) {
|
||||||
TEST(sigaction, sigFpe_handlerCanEditProcessStateAndRecoverExecution) {
|
TEST(sigaction, sigFpe_handlerCanEditProcessStateAndRecoverExecution) {
|
||||||
ubsanTrumpsSystemsEngineering();
|
ubsanTrumpsSystemsEngineering();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned OnSignalCnt = 0;
|
||||||
|
void OnSignal(int sig, siginfo_t *si, void *ctx) {
|
||||||
|
OnSignalCnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(sigaction, ignoringSignalDiscardsSignal) {
|
||||||
|
struct sigaction sa = {.sa_sigaction = OnSignal, .sa_flags = SA_SIGINFO};
|
||||||
|
ASSERT_EQ(0, sigaction(SIGUSR1, &sa, NULL));
|
||||||
|
sigset_t blocked;
|
||||||
|
sigemptyset(&blocked);
|
||||||
|
sigaddset(&blocked, SIGUSR1);
|
||||||
|
ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &blocked, NULL));
|
||||||
|
ASSERT_EQ(0, raise(SIGUSR1));
|
||||||
|
ASSERT_NE(SIG_ERR, signal(SIGUSR1, SIG_IGN));
|
||||||
|
ASSERT_EQ(0, sigaction(SIGUSR1, &sa, NULL));
|
||||||
|
ASSERT_EQ(0, sigprocmask(SIG_UNBLOCK, &blocked, NULL));
|
||||||
|
EXPECT_EQ(0, OnSignalCnt);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue