1 #include <semaphore.h>
2 #include <signal.h>
3 #include <setjmp.h>
4 #include <errno.h>
5 #include <assert.h>
6
7 static sigjmp_buf env;
8
9 /*
10 * Newer glibc crashes on really bogus semaphors.
11 * Catch a SIGABRT and turn it into a EINVAL.
12 */
abrt_handler(int signum,siginfo_t * siginfo,void * sigcontext)13 static void abrt_handler( int signum, siginfo_t *siginfo, void *sigcontext ) {
14 siglongjmp( env, EINVAL );
15 }
16
safe_sem_post(sem_t * sem)17 static int safe_sem_post( sem_t *sem ) {
18 struct sigaction sa;
19 struct sigaction oldsa;
20 int r, e;
21
22 sa.sa_handler = NULL;
23 sa.sa_sigaction = abrt_handler;
24 sigemptyset( &sa.sa_mask );
25 sa.sa_flags = SA_SIGINFO;
26
27 sigaction( SIGABRT, &sa, &oldsa );
28
29 if ( ( e = sigsetjmp( env, 1 ) ) == 0 ) {
30 r = sem_post( sem );
31 } else {
32 r = -1;
33 }
34 errno = e;
35
36 sigaction( SIGABRT, &oldsa, NULL );
37
38 return r;
39 }
40
41 #define sem_post safe_sem_post
42