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