summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco S Hyman <marc@cvs.openbsd.org>2003-01-20 19:24:25 +0000
committerMarco S Hyman <marc@cvs.openbsd.org>2003-01-20 19:24:25 +0000
commit8df73b7dbb7606e5b8a8e6cc448536da6e34f7a1 (patch)
treef0d722c7ecf9910e1d145e9025c02d32cb538d1e
parentcfd5ef4e3cc9207e4d477e14b5d0dd8fe59e5988 (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.c40
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 */