1#include <semaphore.h>
2#include <signal.h>
3#include <setjmp.h>
4#include <errno.h>
5#include <assert.h>
6
7static sigjmp_buf env;
8
9/*
10 * Newer glibc crashes on really bogus semaphors.
11 * Catch a SIGABRT and turn it into a EINVAL.
12 */
13static void abrt_handler( int signum, siginfo_t *siginfo, void *sigcontext ) {
14   siglongjmp( env, EINVAL );
15}
16
17static 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