diff options
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 d2ca81e00..7cb668cda 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; +} |