diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2000-06-27 05:42:15 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2000-06-27 05:42:15 +0000 |
commit | d07ebba2dce1e3d099c03d6b4bb7d20195326a65 (patch) | |
tree | 5af97072331ea683e488ae81c2b4f3ca7054a78f | |
parent | 646f83fe29d16a5c2515d44f2f108917042a07fd (diff) |
win32 fix
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_4@787 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 15 | ||||
-rw-r--r-- | win32/win32.c | 108 | ||||
-rw-r--r-- | win32/win32.h | 3 |
3 files changed, 100 insertions, 26 deletions
@@ -1,3 +1,18 @@ +Tue Jun 27 12:05:10 2000 Katsuyuki Komatsu <komatsu@sarion.co.jp> + + * win32.c (myfdclr): new function. + + * win32.h: add FD_CLR. + +Mon Jun 26 22:20:03 2000 Katsuyuki Komatsu <komatsu@sarion.co.jp> + + * win32/win32.c (is_socket, extract_file_fd): New function. + + * win32/win32.c (myfdopen): use is_socket(). + + * win32/win32.c (myselect): return non socket files immediately + if file and socket handles are mixed. + Sun Jun 25 00:55:03 2000 Katsuyuki Komatsu <komatsu@sarion.co.jp> * ext/socket/socket.c (sock_s_getnameinfo): `res' would not diff --git a/win32/win32.c b/win32/win32.c index a1e6d25ff3..e7b0c19de3 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -1589,33 +1589,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)); + } } @@ -1738,6 +1747,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 @@ -1757,11 +1785,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(); } @@ -1769,28 +1831,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 cbcf4e8117..412f8f9278 100644 --- a/win32/win32.h +++ b/win32/win32.h @@ -281,6 +281,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 |