10c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw#include <semaphore.h> 20c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw#include <signal.h> 30c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw#include <setjmp.h> 40c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw#include <errno.h> 50c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw#include <assert.h> 60c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw 70c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjwstatic sigjmp_buf env; 80c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw 90c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw/* 100c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw * Newer glibc crashes on really bogus semaphors. 110c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw * Catch a SIGABRT and turn it into a EINVAL. 120c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw */ 130c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjwstatic void abrt_handler( int signum, siginfo_t *siginfo, void *sigcontext ) { 140c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw siglongjmp( env, EINVAL ); 150c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw} 160c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw 170c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjwstatic int safe_sem_post( sem_t *sem ) { 180c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw struct sigaction sa; 190c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw struct sigaction oldsa; 200c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw int r, e; 210c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw 220c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw sa.sa_handler = NULL; 230c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw sa.sa_sigaction = abrt_handler; 240c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw sigemptyset( &sa.sa_mask ); 250c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw sa.sa_flags = SA_SIGINFO; 260c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw 270c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw sigaction( SIGABRT, &sa, &oldsa ); 280c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw 290c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw if ( ( e = sigsetjmp( env, 1 ) ) == 0 ) { 300c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw r = sem_post( sem ); 310c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw } else { 320c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw r = -1; 330c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw } 340c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw errno = e; 350c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw 360c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw sigaction( SIGABRT, &oldsa, NULL ); 370c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw 380c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw return r; 390c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw} 400c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw 410c66d2e4293ee50ddb9b248107bfcdfffa96ccdamjw#define sem_post safe_sem_post 42