diff options
-rw-r--r-- | lib/libpthread/uthread/uthread_sigaltstack.c | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/lib/libpthread/uthread/uthread_sigaltstack.c b/lib/libpthread/uthread/uthread_sigaltstack.c index fff62da3be2..93cfc1f0865 100644 --- a/lib/libpthread/uthread/uthread_sigaltstack.c +++ b/lib/libpthread/uthread/uthread_sigaltstack.c @@ -1,4 +1,5 @@ -/* $OpenBSD: uthread_sigaltstack.c,v 1.2 1999/11/25 07:01:44 d Exp $ */ +/* $OpenBSD: uthread_sigaltstack.c,v 1.3 2003/01/20 19:24:24 marc Exp $ */ +/* PUBLIC DOMAIN <marc@snafu.org */ #include <signal.h> #include <errno.h> @@ -7,13 +8,44 @@ #include "pthread_private.h" /* - * placeholder for sigaltstack XXX impl to be done + * IEEE Std 1003.1-2001 says: + * + * "Use of this function by library threads that are not bound to + * kernel-scheduled entities results in undefined behavior." + * + * There exists code (e.g. alpha setjmp) that uses this function + * to get information about the current stack. + * + * The "undefined behaviour" in this implementation is thus: + * o if ss is *not* null return -1 with errno set to EINVAL + * o if oss is *not* null fill it in with information about the + * current stack and return 0. + * + * This lets things like alpha setjmp work in threaded applications. */ int sigaltstack(const struct sigaltstack *ss, struct sigaltstack *oss) { - errno = EINVAL; - return (-1); + struct pthread *curthread = _get_curthread(); + + int ret = 0; + if (ss != NULL) { + errno = EINVAL; + ret = -1; + } else if (oss != NULL) { + /* + * get the requested info from the kernel if there is no + * thread or if the main thread (no thread stack). + */ + if (curthread == NULL || curthread->stack == NULL) + _thread_sys_sigaltstack(ss, oss); + else { + oss->ss_sp = curthread->stack->base; + oss->ss_size = curthread->stack->size; + oss->ss_flags = SS_DISABLE; + } + } + return (ret); } #endif /* _THREAD_SAFE */ |