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>
This commit is contained in:
Corinna Vinschen 2019-07-12 16:32:45 +02:00
parent 0d24a86822
commit 948d40e482
5 changed files with 12 additions and 12 deletions

View File

@ -151,7 +151,7 @@ fhandler_signalfd::write (const void *, size_t)
int int
fhandler_signalfd::poll () 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) if (outset == SIG_BAD_MASK)
return -1; return -1;
if ((outset & sigset) != 0) if ((outset & sigset) != 0)

View File

@ -264,7 +264,7 @@ _pinfo::kill (siginfo_t& si)
if (si.si_signo == 0) if (si.si_signo == 0)
res = 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); sigproc_printf ("%d = sig_send, %E ", res);
res = -1; res = -1;
@ -718,7 +718,7 @@ sigqueue (pid_t pid, int sig, const union sigval value)
si.si_signo = sig; si.si_signo = sig;
si.si_code = SI_QUEUE; si.si_code = SI_QUEUE;
si.si_value = value; si.si_value = value;
return sig_send (dest, si); return (int) sig_send (dest, si);
} }
extern "C" int extern "C" int

View File

@ -422,7 +422,7 @@ _cygtls::remove_pending_sigs ()
extern "C" int extern "C" int
sigpending (sigset_t *mask) 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) if (outset == SIG_BAD_MASK)
return -1; return -1;
*mask = outset; *mask = outset;
@ -503,7 +503,7 @@ exit_thread (DWORD res)
ExitThread (res); ExitThread (res);
} }
int __reg3 sigset_t __reg3
sig_send (_pinfo *p, int sig, _cygtls *tls) sig_send (_pinfo *p, int sig, _cygtls *tls)
{ {
siginfo_t si = {}; 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 pinfo *p == NULL, send to the current process.
If sending to this process, wait for notification that a signal has If sending to this process, wait for notification that a signal has
completed before returning. */ completed before returning. */
int __reg3 sigset_t __reg3
sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls) sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
{ {
int rc = 1; int rc = 1;
@ -748,7 +748,7 @@ out:
if (si.si_signo != __SIGPENDING) if (si.si_signo != __SIGPENDING)
/* nothing */; /* nothing */;
else if (!rc) else if (!rc)
rc = (int) pending; rc = pending;
else else
rc = SIG_BAD_MASK; rc = SIG_BAD_MASK;
sigproc_printf ("returning %p from sending signal %d", rc, si.si_signo); sigproc_printf ("returning %p from sending signal %d", rc, si.si_signo);

View File

@ -71,8 +71,8 @@ class _pinfo;
void __stdcall proc_terminate (); void __stdcall proc_terminate ();
void __stdcall sigproc_init (); void __stdcall sigproc_init ();
bool __reg1 pid_exists (pid_t); bool __reg1 pid_exists (pid_t);
int __reg3 sig_send (_pinfo *, siginfo_t&, class _cygtls * = NULL); sigset_t __reg3 sig_send (_pinfo *, siginfo_t&, class _cygtls * = NULL);
int __reg3 sig_send (_pinfo *, int, class _cygtls * = NULL); sigset_t __reg3 sig_send (_pinfo *, int, class _cygtls * = NULL);
void __stdcall signal_fixup_after_exec (); void __stdcall signal_fixup_after_exec ();
void __stdcall sigalloc (); void __stdcall sigalloc ();
@ -109,7 +109,7 @@ class lock_signals
public: public:
lock_signals () lock_signals ()
{ {
worked = sig_send (NULL, __SIGHOLD) == 0; worked = (bool) sig_send (NULL, __SIGHOLD) == 0;
} }
operator int () const operator int () const
{ {

View File

@ -3311,7 +3311,7 @@ pthread_kill (pthread_t thread, int sig)
rval = ESRCH; rval = ESRCH;
else if (sig) else if (sig)
{ {
rval = sig_send (NULL, si, thread->cygtls); rval = (int) sig_send (NULL, si, thread->cygtls);
if (rval == -1) if (rval == -1)
rval = get_errno (); rval = get_errno ();
} }
@ -3354,7 +3354,7 @@ pthread_sigqueue (pthread_t *thread, int sig, const union sigval value)
si.si_value = value; si.si_value = value;
si.si_pid = myself->pid; si.si_pid = myself->pid;
si.si_uid = myself->uid; si.si_uid = myself->uid;
return sig_send (NULL, si, (*thread)->cygtls); return (int) sig_send (NULL, si, (*thread)->cygtls);
} }
/* ID */ /* ID */