#include <semaphore.h>
#include <signal.h>
#include <setjmp.h>
#include <errno.h>
#include <assert.h>
static sigjmp_buf env;
/*
* Newer glibc crashes on really bogus semaphors.
* Catch a SIGABRT and turn it into a EINVAL.
*/
static void abrt_handler( int signum, siginfo_t *siginfo, void *sigcontext ) {
siglongjmp( env, EINVAL );
}
static int safe_sem_post( sem_t *sem ) {
struct sigaction sa;
struct sigaction oldsa;
int r, e;
sa.sa_handler = NULL;
sa.sa_sigaction = abrt_handler;
sigemptyset( &sa.sa_mask );
sa.sa_flags = SA_SIGINFO;
sigaction( SIGABRT, &sa, &oldsa );
if ( ( e = sigsetjmp( env, 1 ) ) == 0 ) {
r = sem_post( sem );
} else {
r = -1;
}
errno = e;
sigaction( SIGABRT, &oldsa, NULL );
return r;
}
#define sem_post safe_sem_post