This is the mail archive of the
cygwin-developers
mailing list for the Cygwin project.
Longstanding __USE_W32_SOCKETS hiccup.
- From: Dave Korn <dave dot korn dot cygwin at googlemail dot com>
- To: cygwin-developers at cygwin dot com
- Date: Thu, 06 Aug 2009 13:59:47 +0100
- Subject: Longstanding __USE_W32_SOCKETS hiccup.
Hi all, just wanted to check what folks here think about this before I go
about sending it upstream to newlib.
When we define __USE_W32_SOCKETS, it's supposed to keep enough posix-y stuff
out of the way to allow use of the winsock API. All of sys/types.h,
sys/unistd.h and sys/select.h check for this macro and avoid defining clashing
structures and functions if it's present.
Some of them also check for the _WINSOCK_H header guard, but that's a
last-resort, as it only works if winsock2.h has been included earlier than the
sys/*.h header, and that's often not going to be the case.
There is one exception: sys/time.h wraps the timeval struct definition only in
a check of _WINSOCK_H, and so unless you #include winsock2.h first, you get a
redefinition error regardless of __USE_W32_SOCKETS. This has been the cause of
the occasional bug report down the years; trivial test case:
> $ cat tc.c
>
> #define __USE_W32_SOCKETS
>
> #include <sys/time.h>
> #include <winsock2.h>
>
> int main (int argc, const char **argv)
> {
> return 0;
> }
>
> $ gcc-4 -g -O2 tc.c -o tc
> In file included from tc.c:5:
> /usr/lib/gcc/i686-pc-cygwin/4.3.2/../../../../i686-pc-cygwin/lib/../include/w32api/winsock2.h:109:
> error: redefinition of 'struct timeval'>
> $
The attached patch is my suggestion to fix this problem. There is one little
bit of fallout; since struct itimerval requires struct timeval, if we're using
the winsock version of timeval (as indicated by __USE_W32_SOCKETS), and we
haven't already included winsock2.h, we can't define struct itimerval. I don't
see how there could be any code relying on those definitions which wouldn't
already fail to compile because of the redefinition of struct timeval, but I
thought I should point it out.
Any comments? It looks like this struct just got omitted during the initial
implementation of __USE_W32_SOCKETS. Having this work right is needed to fix
libada in upstream GCC, where it's not always an option to "just #include
winsock first"(*). If I don't hear any issues raised, I'll send this to newlib
in fairly short order.
cheers,
DaveK
--
(*) - Although it would be technically possible to scatter "#include
<winsock.h>" directives throughout libada just in front of anywhere that might
directly or indirectly #include <sys/time.h>, it would be hideously ugly
overkill compared to just fixing our headers to make this one little thing a bit
more idempotent.
Index: newlib/libc/include/sys/time.h
===================================================================
RCS file: /cvs/src/src/newlib/libc/include/sys/time.h,v
retrieving revision 1.13
diff -p -u -r1.13 time.h
--- newlib/libc/include/sys/time.h 11 Dec 2008 22:48:38 -0000 1.13
+++ newlib/libc/include/sys/time.h 6 Aug 2009 12:26:45 -0000
@@ -12,7 +12,9 @@
extern "C" {
#endif
-#ifndef _WINSOCK_H
+#if !defined (_WINSOCK_H) && !defined (__USE_W32_SOCKETS)
+/* Don't define timeval or timezone if we already have,
+ or are going to, also include the winsock definitions. */
struct timeval {
time_t tv_sec;
suseconds_t tv_usec;
@@ -27,16 +29,24 @@ struct timezone {
#include <cygwin/sys_time.h>
#endif /* __CYGWIN__ */
-#endif /* _WINSOCK_H */
+#endif /* !defined (_WINSOCK_H) && !defined (__USE_W32_SOCKETS) */
#define ITIMER_REAL 0
#define ITIMER_VIRTUAL 1
#define ITIMER_PROF 2
+#if defined (_WINSOCK_H) || !defined (__USE_W32_SOCKETS)
+/* Can only define itimerval if we have a timeval definition,
+ either from winsock or from above. */
struct itimerval {
struct timeval it_interval;
struct timeval it_value;
};
+#else
+/* Otherwise make an incomplete declaration available for the
+ sake of the getitimer/setitimer declarations below. */
+struct itimerval;
+#endif /* defined (_WINSOCK_H) && !defined (__USE_W32_SOCKETS) */
/* BSD time macros used by RTEMS code */
#if defined (__rtems__) || defined (__CYGWIN__)