From: Katsuyuki Komatsu Date: 2000-06-26T22:34:24+09:00 Subject: [ruby-list:23522] Re: Ruby 1.4.5 小松です。 In the message of [ruby-list:23521] Re: Ruby 1.4.5 on 2000/6/26 20:19:43 Katsuyuki Komatsu wrote: | select()がWSAENOTSOCKのエラーになった場合、ソケット以外のハンドル | のみ読み込み可/書き込み可とみなす | |といったインプリメントに変える必要があります。 こんな感じです。 1.5.4も同様です。 Mon Jun 26 22:20:03 2000 Katsuyuki Komatsu * 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. diff -ru1p ruby-1.4.5.dist/win32/win32.c ruby-1.4.5/win32/win32.c --- ruby-1.4.5.dist/win32/win32.c Fri Feb 18 15:58:58 2000 +++ ruby-1.4.5/win32/win32.c Mon Jun 26 22:20:03 2000 @@ -1591,4 +1591,4 @@ my_open_osfhandle(long osfhandle, int fl -FILE * -myfdopen (int fd, const char *mode) +static int +is_socket(SOCKET fd) { @@ -1597,9 +1597,5 @@ myfdopen (int fd, const char *mode) 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) { @@ -1609,3 +1605,3 @@ myfdopen (int fd, const char *mode) if (iRet == WSAENOTSOCK || iRet == WSANOTINITIALISED) - return (_fdopen(fd, mode)); + return FALSE; } @@ -1616,4 +1612,17 @@ myfdopen (int fd, const char *mode) + 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)); + } } @@ -1759,2 +1768,32 @@ 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 @@ -1764,2 +1803,6 @@ myselect (int nfds, fd_set *rd, fd_set * long r; + fd_set file_rd; + fd_set file_wr; + int file_nfds; + if (!NtSocketsInitialized++) { @@ -1771,2 +1814,12 @@ myselect (int nfds, fd_set *rd, fd_set * } + 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) { @@ -1776,18 +1829,2 @@ myselect (int nfds, fd_set *rd, fd_set * 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; -- 小松克行 / Katsuyuki Komatsu