diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2000-06-28 08:31:35 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2000-06-28 08:31:35 +0000 |
commit | 224e59c6f82c98da0d507cfae3b39c97b6769d51 (patch) | |
tree | 1e844ef7bb01533ce06310b79a92cd0c75a53ba1 /win32 | |
parent | 1261c7e05550a72f3bb33eae75660142c6ea2a4e (diff) |
matz
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@791 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'win32')
-rw-r--r-- | win32/ruby.def | 1 | ||||
-rw-r--r-- | win32/win32.c | 108 | ||||
-rw-r--r-- | win32/win32.h | 4 |
3 files changed, 87 insertions, 26 deletions
diff --git a/win32/ruby.def b/win32/ruby.def index 704e98b7b5..b6a2d31a30 100644 --- a/win32/ruby.def +++ b/win32/ruby.def @@ -125,6 +125,7 @@ EXPORTS myfdclose myaccept mybind + myfdclr myconnect myfdset myfdisset diff --git a/win32/win32.c b/win32/win32.c index 5590ea5a5d..5780bff261 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -1631,33 +1631,42 @@ my_open_osfhandle(long osfhandle, int flags) return fh; /* return handle */ } -FILE * -myfdopen (int fd, const char *mode) +static int +is_socket(SOCKET fd) { char sockbuf[80]; int optlen; int retval; - int fh; - extern int errno; - - //fprintf(stderr, "myfdopen()\n"); - optlen = sizeof(sockbuf); - retval = getsockopt((SOCKET)fd, SOL_SOCKET, SO_TYPE, sockbuf, &optlen); + optlen = sizeof(sockbuf); + retval = getsockopt(fd, SOL_SOCKET, SO_TYPE, sockbuf, &optlen); if (retval == SOCKET_ERROR) { int iRet; iRet = WSAGetLastError(); if (iRet == WSAENOTSOCK || iRet == WSANOTINITIALISED) - return (_fdopen(fd, mode)); + return FALSE; } // // If we get here, then fd is actually a socket. // + return TRUE; +} + +FILE * +myfdopen (int fd, const char *mode) +{ + if (is_socket((SOCKET)fd)) { + int fh; + fh = my_open_osfhandle((SOCKET)fd, O_RDWR|O_BINARY); - return _fdopen(fh, mode); // return file pointer + return _fdopen(fh, mode); // return file pointer + } + else { + return (_fdopen(fd, mode)); + } } @@ -1784,6 +1793,25 @@ myfdset(int fd, fd_set *set) } } +#undef FD_CLR + +void +myfdclr(int fd, fd_set *set) +{ + unsigned int i; + SOCKET s = TO_SOCKET(fd); + + for (i = 0; i < set->fd_count; i++) { + if (set->fd_array[i] == s) { + while (i < set->fd_count - 1) { + set->fd_array[i] = set->fd_array[i + 1]; + i++; + } + set->fd_count--; + break; + } + } +} #undef FD_ISSET @@ -1803,11 +1831,45 @@ myfdisset(int fd, fd_set *set) static int NtSocketsInitialized = 0; +static int +extract_file_fd(fd_set *set, fd_set *fileset) +{ + int idx; + + fileset->fd_count = 0; + if (!set) + return 0; + for (idx = 0; idx < set->fd_count; idx++) { + SOCKET fd = set->fd_array[idx]; + + if (!is_socket(fd)) { + int i; + + for (i = 0; i < fileset->fd_count; i++) { + if (fileset->fd_array[i] == fd) { + break; + } + } + if (i == fileset->fd_count) { + if (fileset->fd_count < FD_SETSIZE) { + fileset->fd_array[i] = fd; + fileset->fd_count++; + } + } + } + } + return fileset->fd_count; +} + long myselect (int nfds, fd_set *rd, fd_set *wr, fd_set *ex, struct timeval *timeout) { long r; + fd_set file_rd; + fd_set file_wr; + int file_nfds; + if (!NtSocketsInitialized++) { StartSockets(); } @@ -1815,28 +1877,22 @@ myselect (int nfds, fd_set *rd, fd_set *wr, fd_set *ex, Sleep(timeout->tv_sec * 1000 + timeout->tv_usec / 1000); return 0; } + file_nfds = extract_file_fd(rd, &file_rd); + file_nfds += extract_file_fd(wr, &file_wr); + if (file_nfds) + { + // assume normal files are always readable/writable + // fake read/write fd_set and return value + if (rd) *rd = file_rd; + if (wr) *wr = file_wr; + return file_nfds; + } if ((r = select (nfds, rd, wr, ex, timeout)) == SOCKET_ERROR) { errno = WSAGetLastError(); switch (errno) { case WSAEINTR: errno = EINTR; break; - case WSAENOTSOCK: - // assume normal files are always readable/writable - // fake read/write fd_set and return value - r = 0; - if (rd) r += rd->fd_count; - if (wr) r += wr->fd_count; - if (ex && ex->fd_count > 0) { - // exceptional condition never happen for normal files - if (r > 0) - ex->fd_count = 0; - else { - errno = EBADF; - r = SOCKET_ERROR; - } - } - break; } } return r; diff --git a/win32/win32.h b/win32/win32.h index 0bfe711a79..add6f14250 100644 --- a/win32/win32.h +++ b/win32/win32.h @@ -183,6 +183,7 @@ extern SOCKET myaccept(SOCKET, struct sockaddr *, int *); extern int mybind(SOCKET, struct sockaddr *, int); extern int myconnect(SOCKET, struct sockaddr *, int); extern void myfdset(int, fd_set*); +extern void myfdclr(int, fd_set*); extern int myfdisset(int, fd_set*); extern long myselect(int, fd_set *, fd_set *, fd_set *, struct timeval *); extern int mygetpeername(SOCKET, struct sockaddr *, int *); @@ -288,6 +289,9 @@ extern char *mystrerror(int); #undef FD_SET #define FD_SET myfdset +#undef FD_CLR +#define FD_CLR myfdclr + #undef FD_ISSET #define FD_ISSET myfdisset |