diff options
| author | Rich Felker <dalias@aerifal.cx> | 2024-12-13 11:31:40 +0000 | 
|---|---|---|
| committer | Rich Felker <dalias@aerifal.cx> | 2024-12-13 11:31:40 +0000 | 
| commit | 47fa6e4fcc5f61c365c91a9bc90e7ed8b3a178ef (patch) | |
| tree | e0a4e4858f0d2f193a7557be7ed11ed03d866e3d | |
| parent | 61399d4bd02ae1ec03068445aa7ffe9174466bfd (diff) | |
| download | musl-47fa6e4fcc5f61c365c91a9bc90e7ed8b3a178ef.tar.gz | |
SIGEV_THREAD timers: fix fatal signal if internal SIGTIMER becomes unblocked
commit 6ae2568bc2367b4d47e0ea1cb043fd56e697912f introduced a fatal
signal condition if the internal timer signal used for SIGEV_THREAD
timers is unblocked. this can happen whenever the application alters
the signal mask with SIG_SETMASK, since sigset_t objects never include
the bits used for implementation-internal signals.
this patch effectively reverts the breakage by adding back a no-op
signal handler.
overruns will not be accounted if the timer signal becomes unblocked,
but POSIX does not specify them except for SIGEV_SIGNAL timers anyway.
| -rw-r--r-- | src/time/timer_create.c | 9 | 
1 files changed, 8 insertions, 1 deletions
| diff --git a/src/time/timer_create.c b/src/time/timer_create.c index 424c70b7..2d8a62bd 100644 --- a/src/time/timer_create.c +++ b/src/time/timer_create.c @@ -22,6 +22,10 @@ static void dummy_0()  }  weak_alias(dummy_0, __pthread_tsd_run_dtors); +static void timer_handler(int sig, siginfo_t *si, void *ctx) +{ +} +  static void cleanup_fromsig(void *p)  {  	pthread_t self = __pthread_self(); @@ -98,7 +102,10 @@ int timer_create(clockid_t clk, struct sigevent *restrict evp, timer_t *restrict  		break;  	case SIGEV_THREAD:  		if (!init) { -			struct sigaction sa = { .sa_handler = SIG_DFL }; +			struct sigaction sa = { +				.sa_sigaction = timer_handler, +				.sa_flags = SA_SIGINFO | SA_RESTART +			};  			__libc_sigaction(SIGTIMER, &sa, 0);  			a_store(&init, 1);  		} | 
