#include #include #include #include #include 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