summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2019-07-12 16:32:45 +0200
committerCorinna Vinschen <corinna@vinschen.de>2019-07-12 17:27:26 +0200
commit948d40e4829e9a6895e6b831ebcb688af849fb90 (patch)
tree3c7c2cb99256a205d709816272ab2b05c30d4850
parent0d24a86822a5ee73d6a6aa69e2a0118aa1e35204 (diff)
downloadcygnal-948d40e4829e9a6895e6b831ebcb688af849fb90.tar.gz
cygnal-948d40e4829e9a6895e6b831ebcb688af849fb90.tar.bz2
cygnal-948d40e4829e9a6895e6b831ebcb688af849fb90.zip
Cygwin: return full sigset_t from sig_send
So far sig_send's return type is int. The problem with this is that sig_send returns a sigset_t on __SIGPENDING, and sigset_t is defined as long type. So the function only returns the lower 32 bit of sigset_t, which is fine on 32 bit, but casts away the pending RT signals on 64 bit. Fix this by changing the return type of sig_send to sigset_t, so as not to narrow down the sigset when returning from handling __SIGPENDING. Make sure to cast correctly in all invocations of sig_send. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
-rw-r--r--winsup/cygwin/fhandler_signalfd.cc2
-rw-r--r--winsup/cygwin/signal.cc4
-rw-r--r--winsup/cygwin/sigproc.cc8
-rw-r--r--winsup/cygwin/sigproc.h6
-rw-r--r--winsup/cygwin/thread.cc4
5 files changed, 12 insertions, 12 deletions
diff --git a/winsup/cygwin/fhandler_signalfd.cc b/winsup/cygwin/fhandler_signalfd.cc
index 6c7da02e9..4d89a6c5b 100644
--- a/winsup/cygwin/fhandler_signalfd.cc
+++ b/winsup/cygwin/fhandler_signalfd.cc
@@ -151,7 +151,7 @@ fhandler_signalfd::write (const void *, size_t)
int
fhandler_signalfd::poll ()
{
- sigset_t outset = (sigset_t) sig_send (myself, __SIGPENDING, &_my_tls);
+ sigset_t outset = sig_send (myself, __SIGPENDING, &_my_tls);
if (outset == SIG_BAD_MASK)
return -1;
if ((outset & sigset) != 0)
diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc
index 9c51ec129..920a533f3 100644
--- a/winsup/cygwin/signal.cc
+++ b/winsup/cygwin/signal.cc
@@ -264,7 +264,7 @@ _pinfo::kill (siginfo_t& si)
if (si.si_signo == 0)
res = 0;
- else if ((res = sig_send (this, si)))
+ else if ((res = (int) sig_send (this, si)))
{
sigproc_printf ("%d = sig_send, %E ", res);
res = -1;
@@ -718,7 +718,7 @@ sigqueue (pid_t pid, int sig, const union sigval value)
si.si_signo = sig;
si.si_code = SI_QUEUE;
si.si_value = value;
- return sig_send (dest, si);
+ return (int) sig_send (dest, si);
}
extern "C" int
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index 3b6492bb4..cba1af785 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -422,7 +422,7 @@ _cygtls::remove_pending_sigs ()
extern "C" int
sigpending (sigset_t *mask)
{
- sigset_t outset = (sigset_t) sig_send (myself, __SIGPENDING, &_my_tls);
+ sigset_t outset = sig_send (myself, __SIGPENDING, &_my_tls);
if (outset == SIG_BAD_MASK)
return -1;
*mask = outset;
@@ -503,7 +503,7 @@ exit_thread (DWORD res)
ExitThread (res);
}
-int __reg3
+sigset_t __reg3
sig_send (_pinfo *p, int sig, _cygtls *tls)
{
siginfo_t si = {};
@@ -516,7 +516,7 @@ sig_send (_pinfo *p, int sig, _cygtls *tls)
If pinfo *p == NULL, send to the current process.
If sending to this process, wait for notification that a signal has
completed before returning. */
-int __reg3
+sigset_t __reg3
sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
{
int rc = 1;
@@ -748,7 +748,7 @@ out:
if (si.si_signo != __SIGPENDING)
/* nothing */;
else if (!rc)
- rc = (int) pending;
+ rc = pending;
else
rc = SIG_BAD_MASK;
sigproc_printf ("returning %p from sending signal %d", rc, si.si_signo);
diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h
index 9beb31dcf..a6f1428ce 100644
--- a/winsup/cygwin/sigproc.h
+++ b/winsup/cygwin/sigproc.h
@@ -71,8 +71,8 @@ class _pinfo;
void __stdcall proc_terminate ();
void __stdcall sigproc_init ();
bool __reg1 pid_exists (pid_t);
-int __reg3 sig_send (_pinfo *, siginfo_t&, class _cygtls * = NULL);
-int __reg3 sig_send (_pinfo *, int, class _cygtls * = NULL);
+sigset_t __reg3 sig_send (_pinfo *, siginfo_t&, class _cygtls * = NULL);
+sigset_t __reg3 sig_send (_pinfo *, int, class _cygtls * = NULL);
void __stdcall signal_fixup_after_exec ();
void __stdcall sigalloc ();
@@ -109,7 +109,7 @@ class lock_signals
public:
lock_signals ()
{
- worked = sig_send (NULL, __SIGHOLD) == 0;
+ worked = (bool) sig_send (NULL, __SIGHOLD) == 0;
}
operator int () const
{
diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc
index 43a6c88b3..e09507e07 100644
--- a/winsup/cygwin/thread.cc
+++ b/winsup/cygwin/thread.cc
@@ -3311,7 +3311,7 @@ pthread_kill (pthread_t thread, int sig)
rval = ESRCH;
else if (sig)
{
- rval = sig_send (NULL, si, thread->cygtls);
+ rval = (int) sig_send (NULL, si, thread->cygtls);
if (rval == -1)
rval = get_errno ();
}
@@ -3354,7 +3354,7 @@ pthread_sigqueue (pthread_t *thread, int sig, const union sigval value)
si.si_value = value;
si.si_pid = myself->pid;
si.si_uid = myself->uid;
- return sig_send (NULL, si, (*thread)->cygtls);
+ return (int) sig_send (NULL, si, (*thread)->cygtls);
}
/* ID */