[Rd] Problem with psignal.c for Windows builds
Radford Neal
radford at cs.toronto.edu
Fri Aug 21 21:19:24 CEST 2015
Continuing with problems that I've uncovered while getting pqR to work
on Windows...
The file src/ghuwin32/psignal.c (used only in Windows builds) fails to
use the sigset_t type in all places where it should, using "int" some
places instead.
Here is a diff of the needed corrections:
@@ -253,7 +253,7 @@ sighandler_t signal(int signal_Number, sighandler_t signal_Handler)
int sigaddset(sigset_t* sigset_Info,int signal_Number)
{
if (IS_SIGNAL(signal_Number)) {
- (*sigset_Info) |= (1 << (signal_Number - 1));
+ (*sigset_Info) |= ((sigset_t)1 << (signal_Number - 1));
return 0;
}
else {
@@ -267,7 +267,7 @@ int sigaddset(sigset_t* sigset_Info,int signal_Number)
int sigdelset(sigset_t* sigset_Info,int signal_Number)
{
if (IS_SIGNAL(signal_Number)) {
- *sigset_Info &= ~(1<< (signal_Number - 1));
+ *sigset_Info &= ~((sigset_t)1<< (signal_Number-1));
return 0;
}
else {
@@ -295,7 +295,7 @@ int sigfillset(sigset_t* sigset_Info)
int sigismember(sigset_t* sigset_Info,int signal_Number)
{
if (IS_SIGNAL(signal_Number)) {
- if ( *sigset_Info & (1 << (signal_Number-1)))
+ if ( *sigset_Info & ((sigset_t)1 << (signal_Number-1)))
return 1;
else
return 0;
@@ -380,9 +380,9 @@ int sigprocmask(int mask_Function,sigset_t* sigset_Info,
}
/* Set signal mask ========================================================= */
-int sigsetmask(int signal_MaskNew)
+sigset_t sigsetmask(sigset_t signal_MaskNew)
{
- int signal_MaskOld = downhill_Sigset_Mask;
+ sigset_t signal_MaskOld = downhill_Sigset_Mask;
if (sigprocmask(SIG_SETMASK, &signal_MaskNew, NULL) == -1)
return (int)-1;
@@ -391,7 +391,7 @@ int sigsetmask(int signal_MaskNew)
}
/* Add signals to mask ===================================================== */
-int sigblock(int signal_MaskNew)
+sigset_t sigblock(sigset_t signal_MaskNew)
{
/* Block a specific group of signals */
return sigsetmask(downhill_Sigset_Mask|signal_MaskNew);
Now, you may wonder how it's been working with these errors. The
file src/gnuwin32/fixed/h/psignal.h has the following code:
/* mingw-w64's sys/types.h also defines this and we want this defn */
#ifndef _SIGSET_T_
#define _SIGSET_T_
typedef int sigset_t;
#endif /* Not _SIGSET_T_ */
The comment is unclear as to whether the mingw definition is or is not
the one that is desired (what does "this" refer to?). Anyway, the
mingw sys/types.h file contains the following code:
#ifndef _SIGSET_T_
#define _SIGSET_T_
#ifdef _WIN64
__MINGW_EXTENSION
typedef unsigned long long _sigset_t;
#else
typedef unsigned long _sigset_t;
#endif
#ifdef _POSIX
typedef _sigset_t sigset_t;
#endif
#endif /* Not _SIGSET_T_ */
So if the R psignal.h file is included before sys/types, sigset_t will
be defined as "int", not as "unsigned long" or "unsigned long long".
And in fact it seems that R (though not pqR) always includes psignal.h
before sys/types.h (if the latter is included as well). There's even
this code snippet in src/unix/Rscript.c:
#ifdef WIN32
#include <psignal.h>
/* on some systems needs to be included before <sys/types.h> */
#endif
And indeed, with Rtools, you do have to include psignal.h first, since
the mingw sys/types.h defines _SIGSET_T_, preventing psignal.h from
defining sigset_t but does not define sigset_t itself (rather only
_sigset_t), since _POSIX isn't defined.
So current R Core releases (accidentally?) avoid the problem by not
actually using mingw's sigset_t type, but instead always using int.
But it's possible that there is some reason to want to use the type
defined in sys/types.h.
Radford Neal
More information about the R-devel
mailing list