summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2000-06-27 05:42:15 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2000-06-27 05:42:15 +0000
commitd07ebba2dce1e3d099c03d6b4bb7d20195326a65 (patch)
tree5af97072331ea683e488ae81c2b4f3ca7054a78f
parent646f83fe29d16a5c2515d44f2f108917042a07fd (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--ChangeLog15
-rw-r--r--win32/win32.c108
-rw-r--r--win32/win32.h3
3 files changed, 100 insertions, 26 deletions
diff --git a/ChangeLog b/ChangeLog
index 263337ca8a..4716d9047c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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