diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2015-06-19 15:58:23 +0200 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2015-06-19 16:12:45 +0200 |
commit | 22465796edbfd6f156ca2930f56b3345cc54b164 (patch) | |
tree | a463488dc43aa43c698bf806602ba54975890889 /winsup/cygwin/signal.cc | |
parent | 715ac1e872e495496f9a540a75e8b1f4cbcdf321 (diff) | |
download | newlib-22465796edbfd6f156ca2930f56b3345cc54b164.zip newlib-22465796edbfd6f156ca2930f56b3345cc54b164.tar.gz newlib-22465796edbfd6f156ca2930f56b3345cc54b164.tar.bz2 |
Preliminary infrastructure to implement alternate stack
* libc/include/sys/signal.h: Define SS_ONSTACK and SS_DISABLE
unconditionally.
(sigaltstack): Enable prototype on Cygwin.
* common.din (sigaltstack): Export.
* cygtls.cc (_cygtls::init_thread): Initialize altstack.
* cygtls.h (__tlsstack_t): Rename from __stack_t to distinguish
more clearly from stack_t. Accommodate throughout.
(_cygtls): Add altstack member.
* exceptions.cc (exception::handle): Set SIGSEGV handler to SIG_DFL
if we encounter a stack overflow, and no alternate stack has been
defined.
* include/cygwin/signal.h (MINSIGSTKSZ): Define
(SIGSTKSZ): Define.
(SA_ONSTACK): Define.
* signal.cc (sigaltstack): New function.
* tlsoffset.h: Regenerate.
* tlsoffset64.h: Ditto.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Diffstat (limited to 'winsup/cygwin/signal.cc')
-rw-r--r-- | winsup/cygwin/signal.cc | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc index d2ca81e..7cb668c 100644 --- a/winsup/cygwin/signal.cc +++ b/winsup/cygwin/signal.cc @@ -587,7 +587,7 @@ sigwaitinfo (const sigset_t *set, siginfo_t *info) *info = _my_tls.infodata; res = _my_tls.infodata.si_signo; _my_tls.sig = 0; - if (_my_tls.retaddr () == (__stack_t) sigdelayed) + if (_my_tls.retaddr () == (__tlsstack_t) sigdelayed) _my_tls.pop (); _my_tls.unlock (); } @@ -624,3 +624,41 @@ sigqueue (pid_t pid, int sig, const union sigval value) si.si_value = value; return sig_send (dest, si); } + +extern "C" int +sigaltstack (const stack_t *ss, stack_t *oss) +{ + _cygtls& me = _my_tls; + + if (ss) + { + if (me.altstack.ss_flags == SS_ONSTACK) + { + set_errno (EPERM); + return -1; + } + if (ss->ss_flags == SS_DISABLE) + { + me.altstack.ss_sp = NULL; + me.altstack.ss_flags = 0; + me.altstack.ss_size = 0; + } + else + { + if (ss->ss_flags) + { + set_errno (EINVAL); + return -1; + } + if (ss->ss_size < MINSIGSTKSZ) + { + set_errno (ENOMEM); + return -1; + } + memcpy (&me.altstack, ss, sizeof *ss); + } + } + if (oss) + memcpy (oss, &me.altstack, sizeof *oss); + return 0; +} |