X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=win32%2Fwin32sck.c;h=5c2b73f95a6a535e80e69cf34df0415d0332c949;hb=26b3385cfa7a4193b7fdcd1e1e62a8894e9d9198;hp=a0fad00386aa3fa41c82369df2f58938b6b02742;hpb=3a25acb49073f2e27090ba463a25de8bf4748c3f;p=p5sagit%2Fp5-mst-13.2.git diff --git a/win32/win32sck.c b/win32/win32sck.c index a0fad00..5c2b73f 100644 --- a/win32/win32sck.c +++ b/win32/win32sck.c @@ -8,58 +8,27 @@ * License or the Artistic License, as specified in the README file. */ -#include +#define WIN32IO_IS_STDIO +#define WIN32SCK_IS_STDSCK #define WIN32_LEAN_AND_MEAN +#ifdef __GNUC__ +#define Win32_Winsock +#endif +#include #include "EXTERN.h" #include "perl.h" + +#if defined(PERL_OBJECT) +#define NO_XSLOCKS +extern CPerlObj* pPerl; +#include "XSUB.h" +#endif + #include #include #include #include - -#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 closesocket -#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 /* thanks to Beverly Brown (beverly@datacube.com) */ #ifdef USE_SOCKETS_AS_HANDLES @@ -95,7 +64,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 @@ -130,8 +108,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]; @@ -289,13 +268,24 @@ 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; + /* winsock seems incapable of dealing with all three null fd_sets, + * so do the (millisecond) sleep as a special case + */ + if (!(rd || wr || ex)) { + Sleep(timeout->tv_sec * 1000 + + timeout->tv_usec / 1000); /* do the best we can */ + return 0; + } + StartSockets(); + PERL_FD_ZERO(&dummy); if (!rd) rd = &dummy, prd = NULL; else @@ -314,13 +304,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); } @@ -328,21 +316,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; } @@ -477,7 +460,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); @@ -489,6 +473,7 @@ struct servent * win32_getservbyport(int port, const char *proto) { struct servent *r; + dTHR; SOCKET_TEST(r = getservbyport(port, proto), NULL); if (r) { @@ -497,6 +482,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) { @@ -602,17 +609,6 @@ win32_setservent(int stayopen) croak("setservent not implemented!\n"); } -#define WIN32IO_IS_STDIO -#include - -#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) { @@ -624,7 +620,7 @@ win32_savecopyservent(struct servent*d, struct servent*s, const char *proto) d->s_proto = s->s_proto; else #endif - if (proto && strlen(proto)) + if (proto && strlen(proto)) d->s_proto = (char *)proto; else d->s_proto = "tcp";