[win32] Various win32 fixes
[p5sagit/p5-mst-13.2.git] / win32 / win32sck.c
index 27ae060..5ac2ef6 100644 (file)
@@ -8,57 +8,20 @@
  *    License or the Artistic License, as specified in the README file.
  */
 
-#include <windows.h>
+#define WIN32IO_IS_STDIO
+#define WIN32SCK_IS_STDSCK
 #define WIN32_LEAN_AND_MEAN
+#ifdef __GNUC__
+#define Win32_Winsock
+#endif
+#include <windows.h>
 #include "EXTERN.h"
 #include "perl.h"
 #include <sys/socket.h>
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <assert.h>
-
-#undef htonl
-#undef htons
-#undef ntohl
-#undef ntohs
-#undef inet_addr
-#undef inet_ntoa
-#undef socket
-#undef bind
-#undef listen
-#undef accept
-#undef connect
-#undef send
-#undef sendto
-#undef recv
-#undef recvfrom
-#undef shutdown
-#undef ioctlsocket
-#undef setsockopt
-#undef getsockopt
-#undef getpeername
-#undef getsockname
-#undef gethostname
-#undef gethostbyname
-#undef gethostbyaddr
-#undef getprotobyname
-#undef getprotobynumber
-#undef getservbyname
-#undef getservbyport
-#undef select
-#undef endhostent
-#undef endnetent
-#undef endprotoent
-#undef endservent
-#undef getnetent
-#undef getnetbyname
-#undef getnetbyaddr
-#undef getprotoent
-#undef getservent
-#undef sethostent
-#undef setnetent
-#undef setprotoent
-#undef setservent
+#include <io.h>
 
 /* thanks to Beverly Brown     (beverly@datacube.com) */
 #ifdef USE_SOCKETS_AS_HANDLES
@@ -94,7 +57,16 @@ static struct servent* win32_savecopyservent(struct servent*d,
                                              struct servent*s,
                                              const char *proto);
 
+#ifdef USE_THREADS
+#ifdef USE_DECLSPEC_THREAD
 __declspec(thread) struct servent myservent;
+#else
+#define myservent (thr->i.Wservent)
+#endif
+#else
+static struct servent myservent;
+#endif
+
 static int wsock_started = 0;
 
 void
@@ -129,8 +101,9 @@ start_sockets(void)
 
 
 #ifndef USE_SOCKETS_AS_HANDLES
+#undef fdopen
 FILE *
-myfdopen(int fd, char *mode)
+my_fdopen(int fd, char *mode)
 {
     FILE *fp;
     char sockbuf[256];
@@ -288,13 +261,15 @@ win32_recvfrom(SOCKET s, char *buf, int len, int flags, struct sockaddr *from, i
 
 /* select contributed by Vincent R. Slyngstad (vrs@ibeam.intel.com) */
 int
-win32_select(int nfds, int* rd, int* wr, int* ex, const struct timeval* timeout)
+win32_select(int nfds, Perl_fd_set* rd, Perl_fd_set* wr, Perl_fd_set* ex, const struct timeval* timeout)
 {
-    long r;
-    int dummy = 0;
+    int r;
+#ifdef USE_SOCKETS_AS_HANDLES
+    Perl_fd_set dummy;
     int i, fd, bit, offset;
-    FD_SET nrd, nwr, nex,*prd,*pwr,*pex;
+    FD_SET nrd, nwr, nex, *prd, *pwr, *pex;
 
+    PERL_FD_ZERO(&dummy);
     if (!rd)
        rd = &dummy, prd = NULL;
     else
@@ -313,13 +288,11 @@ win32_select(int nfds, int* rd, int* wr, int* ex, const struct timeval* timeout)
     FD_ZERO(&nex);
     for (i = 0; i < nfds; i++) {
        fd = TO_SOCKET(i);
-       bit = 1L<<(i % (sizeof(int)*8));
-       offset = i / (sizeof(int)*8);
-       if (rd[offset] & bit)
+       if (PERL_FD_ISSET(i,rd))
            FD_SET(fd, &nrd);
-       if (wr[offset] & bit)
+       if (PERL_FD_ISSET(i,wr))
            FD_SET(fd, &nwr);
-       if (ex[offset] & bit)
+       if (PERL_FD_ISSET(i,ex))
            FD_SET(fd, &nex);
     }
 
@@ -327,21 +300,16 @@ win32_select(int nfds, int* rd, int* wr, int* ex, const struct timeval* timeout)
 
     for (i = 0; i < nfds; i++) {
        fd = TO_SOCKET(i);
-       bit = 1L<<(i % (sizeof(int)*8));
-       offset = i / (sizeof(int)*8);
-       if (rd[offset] & bit) {
-           if (!__WSAFDIsSet(fd, &nrd))
-               rd[offset] &= ~bit;
-       }
-       if (wr[offset] & bit) {
-           if (!__WSAFDIsSet(fd, &nwr))
-               wr[offset] &= ~bit;
-       }
-       if (ex[offset] & bit) {
-           if (!__WSAFDIsSet(fd, &nex))
-               ex[offset] &= ~bit;
-       }
+       if (PERL_FD_ISSET(i,rd) && !FD_ISSET(fd, &nrd))
+           PERL_FD_CLR(i,rd);
+       if (PERL_FD_ISSET(i,wr) && !FD_ISSET(fd, &nwr))
+           PERL_FD_CLR(i,wr);
+       if (PERL_FD_ISSET(i,ex) && !FD_ISSET(fd, &nex))
+           PERL_FD_CLR(i,ex);
     }
+#else
+    SOCKET_TEST_ERROR(r = select(nfds, rd, wr, ex, timeout));
+#endif
     return r;
 }
 
@@ -382,15 +350,24 @@ win32_shutdown(SOCKET s, int how)
     return r;
 }
 
+int
+win32_closesocket(SOCKET s)
+{
+    int r;
+
+    SOCKET_TEST_ERROR(r = closesocket(TO_SOCKET(s)));
+    return r;
+}
+
 SOCKET
 win32_socket(int af, int type, int protocol)
 {
     SOCKET s;
 
-    StartSockets();
 #ifndef USE_SOCKETS_AS_HANDLES
     SOCKET_TEST(s = socket(af, type, protocol), INVALID_SOCKET);
 #else
+    StartSockets();
     if((s = socket(af, type, protocol)) == INVALID_SOCKET)
        errno = WSAGetLastError();
     else
@@ -467,7 +444,8 @@ struct servent *
 win32_getservbyname(const char *name, const char *proto)
 {
     struct servent *r;
-   
+    dTHR;    
+
     SOCKET_TEST(r = getservbyname(name, proto), NULL);
     if (r) {
        r = win32_savecopyservent(&myservent, r, proto);
@@ -479,6 +457,7 @@ struct servent *
 win32_getservbyport(int port, const char *proto)
 {
     struct servent *r;
+    dTHR; 
 
     SOCKET_TEST(r = getservbyport(port, proto), NULL);
     if (r) {
@@ -487,6 +466,28 @@ win32_getservbyport(int port, const char *proto)
     return r;
 }
 
+int
+win32_ioctl(int i, unsigned int u, char *data)
+{
+    u_long argp = (u_long)data;
+    int retval;
+
+    if (!wsock_started) {
+       croak("ioctl implemented only on sockets");
+       /* NOTREACHED */
+    }
+
+    retval = ioctlsocket(TO_SOCKET(i), (long)u, &argp);
+    if (retval == SOCKET_ERROR) {
+       if (WSAGetLastError() == WSAENOTSOCK) {
+           croak("ioctl implemented only on sockets");
+           /* NOTREACHED */
+       }
+       errno = WSAGetLastError();
+    }
+    return retval;
+}
+
 char FAR *
 win32_inet_ntoa(struct in_addr in)
 {
@@ -592,17 +593,6 @@ win32_setservent(int stayopen)
     croak("setservent not implemented!\n");
 }
 
-#define WIN32IO_IS_STDIO
-#include <io.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#include "win32iop.h"
-#ifdef __cplusplus
-}
-#endif
-
 static struct servent*
 win32_savecopyservent(struct servent*d, struct servent*s, const char *proto)
 {