int _thread_sys_sigblock(int mask) { int omask, n; n = _thread_sys_sigprocmask(SIG_BLOCK, (sigset_t *) & mask, (sigset_t *) & omask); if (n) return (n); return (omask); }
int _thread_sys_sigsetmask(int mask) { int omask, n; n = _thread_sys_sigprocmask(SIG_SETMASK, (sigset_t *) & mask, (sigset_t *) & omask); if (n) return (n); return (omask); }
void abort(void) { struct atexit *p = __atexit; static int cleanup_called = 0; sigset_t mask; sigfillset(&mask); /* * don't block SIGABRT to give any handler a chance; we ignore * any errors -- X311J doesn't allow abort to return anyway. */ sigdelset(&mask, SIGABRT); (void)_thread_sys_sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL); /* * POSIX requires we flush stdio buffers on abort */ if (cleanup_called == 0) { /* the cleanup routine lives in fns[0] on the last page */ while (p != NULL && p->next != NULL) p = p->next; /* the check for fn_dso == NULL is mostly paranoia */ if (p != NULL && p->fns[0].fn_dso == NULL && p->fns[0].fn_ptr.std_func != NULL) { cleanup_called = 1; (*p->fns[0].fn_ptr.std_func)(); } } (void)raise(SIGABRT); /* * if SIGABRT ignored, or caught and the handler returns, do * it again, only harder. */ (void)signal(SIGABRT, SIG_DFL); (void)_thread_sys_sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL); (void)raise(SIGABRT); _exit(1); }
/* * uthread atomic lock: * attempt to acquire a lock (by giving it a non-zero value). * Return zero on success, or the lock's value on failure * This uses signal masking to make sure that no other thread * can modify the lock while processing, hence it is very slow. */ int _thread_slow_atomic_lock(volatile _spinlock_lock_t *lock) { _spinlock_lock_t old; sigset_t oldset, newset = (sigset_t)~0; /* block signals - incurs a context switch */ if (_thread_sys_sigprocmask(SIG_SETMASK, &newset, &oldset) < 0) PANIC("_atomic_lock block"); old = *lock; if (old == _SPINLOCK_UNLOCKED) *lock = _SPINLOCK_LOCKED; /* restore signal mask to what it was */ if (_thread_sys_sigprocmask(SIG_SETMASK, &oldset, NULL) < 0) PANIC("_atomic_lock restore"); return (old != _SPINLOCK_UNLOCKED); }
int sigprocmask(int how, const sigset_t *set, sigset_t *oset) { sigset_t s; if (set != NULL && how != SIG_UNBLOCK && sigismember(set, SIGTHR)) { s = *set; sigdelset(&s, SIGTHR); set = &s; } return (_thread_sys_sigprocmask(how, set, oset)); }
void abort() { sigset_t mask; /* * POSIX requires we flush stdio buffers on abort */ if (__cleanup) (*__cleanup)(); sigfillset(&mask); /* * don't block SIGABRT to give any handler a chance; we ignore * any errors -- X311J doesn't allow abort to return anyway. */ sigdelset(&mask, SIGABRT); #ifdef _THREAD_SAFE (void) _thread_sys_sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL); #else (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL); #endif (void)kill(getpid(), SIGABRT); /* * if SIGABRT ignored, or caught and the handler returns, do * it again, only harder. */ (void)signal(SIGABRT, SIG_DFL); #ifdef _THREAD_SAFE (void) _thread_sys_sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL); #else (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL); #endif (void)kill(getpid(), SIGABRT); exit(1); }
void _thread_exit(const char *fname, int lineno, const char *string) { char s[256]; /* Prepare an error message string: */ s[0] = '\0'; strlcat(s, "pid ", sizeof s); numlcat(s, (int)_thread_sys_getpid(), sizeof s); strlcat(s, ": Fatal error '", sizeof s); strlcat(s, string, sizeof s); strlcat(s, "' at line ", sizeof s); numlcat(s, lineno, sizeof s); strlcat(s, " in file ", sizeof s); strlcat(s, fname, sizeof s); strlcat(s, " (errno = ", sizeof s); numlcat(s, errno, sizeof s); strlcat(s, ")\n", sizeof s); /* Write the string to the standard error file descriptor: */ _thread_sys_write(2, s, strlen(s)); /* Force this process to exit: */ /* XXX - Do we want abort to be conditional on _PTHREADS_INVARIANTS? */ #if defined(_PTHREADS_INVARIANTS) { struct sigaction sa; sigset_t s; /* Ignore everything except ABORT */ sigfillset(&s); sigdelset(&s, SIGABRT); _thread_sys_sigprocmask(SIG_SETMASK, &s, NULL); /* Set the abort handler to default (dump core) */ sa.sa_handler = SIG_DFL; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_SIGINFO; (void)_thread_sys_sigaction(SIGABRT, &sa, NULL); (void)_thread_sys_kill(_thread_sys_getpid(), SIGABRT); for (;;) ; } #else _exit(1); #endif }