diff options
author | Marco S Hyman <marc@cvs.openbsd.org> | 2003-01-20 19:24:25 +0000 |
---|---|---|
committer | Marco S Hyman <marc@cvs.openbsd.org> | 2003-01-20 19:24:25 +0000 |
commit | 8df73b7dbb7606e5b8a8e6cc448536da6e34f7a1 (patch) | |
tree | f0d722c7ecf9910e1d145e9025c02d32cb538d1e | |
parent | cfd5ef4e3cc9207e4d477e14b5d0dd8fe59e5988 (diff) |
Allow the fetching of current stack info from threaded apps.
This is necessary for alpha setjmp. The alpha setjmp/longjmp
regression tests pass with -pthread with this change
-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 */ |