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 */ 13 static void abrt_handler( int signum, siginfo_t *siginfo, void *sigcontext ) { 14 siglongjmp( env, EINVAL ); 15 } 16 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