[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Cvs-cvs] Changes to ccvs/windows-NT/woe32.c
From: |
Conrad T . Pino |
Subject: |
[Cvs-cvs] Changes to ccvs/windows-NT/woe32.c |
Date: |
Fri, 30 Sep 2005 03:13:05 -0400 |
Index: ccvs/windows-NT/woe32.c
diff -u ccvs/windows-NT/woe32.c:1.12 ccvs/windows-NT/woe32.c:1.13
--- ccvs/windows-NT/woe32.c:1.12 Mon Sep 26 03:09:15 2005
+++ ccvs/windows-NT/woe32.c Fri Sep 30 07:13:04 2005
@@ -23,7 +23,8 @@
#include "woe32.h"
#include <stdio.h>
-#include <conio.h>
+#include <assert.h>
+#include <errno.h>
#include <sys/socket.h> /* This does: #include <windows.h> */
@@ -52,6 +53,203 @@
sock_strerror (WSAGetLastError ()));
}
}
+
+
+
+/*============================================================================*/
+/*
+How Microsoft does fd_set in Windows 2000 and Visual C++ 6.0:
+
+ * Select uses arrays of SOCKETs. These macros manipulate such
+ * arrays. FD_SETSIZE may be defined by the user before including
+ * this file, but the default here should be >= 64.
+ *
+ * CAVEAT IMPLEMENTOR and USER: THESE MACROS AND TYPES MUST BE
+ * INCLUDED IN WINSOCK2.H EXACTLY AS SHOWN HERE.
+
+ #ifndef FD_SETSIZE
+ #define FD_SETSIZE 64
+ #endif
+
+ typedef struct fd_set {
+ u_int fd_count;
+ SOCKET fd_array[FD_SETSIZE];
+ } fd_set;
+
+Microsoft packs all handles between fd_array[0] and fd_array[fd_count-1]
+*/
+
+typedef struct
+{
+ int is_ready;
+ SOCKET crt;
+ DWORD type;
+ union
+ {
+ long osf;
+ HANDLE w32;
+ };
+} woe32_handle_set;
+
+typedef struct
+{
+ u_int ready_count, used_count;
+ woe32_handle_set handle[ FD_SETSIZE ];
+} woe32_select_set;
+
+static int woe32_select_set_fini (woe32_select_set * w32_set, fd_set * crt_set)
+{
+ FD_ZERO (crt_set);
+
+ if (w32_set->ready_count)
+ {
+ u_int index;
+ woe32_handle_set * handle;
+
+ index = 0;
+ handle = w32_set->handle;
+ while (index < w32_set->used_count)
+ {
+ if (handle->is_ready)
+ {
+ FD_SET (handle->crt, crt_set);
+ }
+
+ ++index;
+ ++handle;
+ }
+ }
+
+ return w32_set->ready_count;
+}
+
+static int woe32_select_set_init (woe32_select_set * w32_set, fd_set * crt_set)
+{
+ u_int index;
+ DWORD dwBytesAvail;
+ woe32_handle_set * handle;
+
+ w32_set->ready_count = w32_set->used_count = index = 0;
+ handle = w32_set->handle;
+
+ if (crt_set) while (index < crt_set->fd_count)
+ {
+ handle->crt = crt_set->fd_array[index];
+
+ handle->osf = _get_osfhandle (handle->crt);
+ if (handle->w32 == INVALID_HANDLE_VALUE)
+ {
+ errno = EBADF;
+ return -1;
+ }
+
+ handle->type = GetFileType (handle->w32);
+ switch (handle->type)
+ {
+ case FILE_TYPE_DISK:
+ w32_set->ready_count += handle->is_ready = 1;
+ break;
+
+ case FILE_TYPE_PIPE:
+ if ( PeekNamedPipe (handle->w32, NULL, 0, NULL,
&dwBytesAvail, NULL) )
+ {
+ w32_set->ready_count += handle->is_ready =
dwBytesAvail > 0;
+ }
+ else
+ {
+ errno = EBADF;
+ return -1;
+ }
+ break;
+
+ case FILE_TYPE_CHAR:
+ case FILE_TYPE_REMOTE:
+ case FILE_TYPE_UNKNOWN:
+ default:
+ errno = EBADF;
+ return -1;
+ }
+
+ ++index;
+ ++handle;
+ }
+ w32_set->used_count = index;
+
+ while (index < FD_SETSIZE)
+ {
+ handle->crt = -1;
+
+ handle->w32 = INVALID_HANDLE_VALUE;
+
+ handle->type = FILE_TYPE_UNKNOWN;
+
+ handle->is_ready = 0;
+
+ ++index;
+ ++handle;
+ }
+
+ return w32_set->ready_count;
+}
+
+static int woe32_select_set_wait (woe32_select_set * w32_set)
+{
+ char buffer[ 8 ];
+ DWORD dwBytesRead;
+
+ /* set contains only non-ready pipes */
+ if (w32_set->used_count != 1)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (! ReadFile (w32_set->handle[0].w32, buffer, 0, &dwBytesRead, NULL))
+ {
+ errno = EBADF;
+ return -1;
+ }
+
+ return w32_set->handle[0].is_ready = 1;
+}
+
+/* #define fd_select woe32_fd_select */
+#undef fd_select
+int woe32_fd_select ( int nfds,
+ struct fd_set * readfds,
+ struct fd_set * writefds,
+ struct fd_set * errorfds,
+ struct timeval * timeout)
+{
+ int ready_fds;
+ woe32_select_set woe32_rset;
+
+ /* we don't support these for now */
+ assert(writefds != NULL);
+ assert(errorfds != NULL);
+ assert(timeout != NULL);
+
+ /* Windows doesn't care but POSIX says it does */
+ if (nfds < 0 || nfds > FD_SETSIZE)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ ready_fds = woe32_select_set_init (&woe32_rset, readfds);
+ if (! ready_fds)
+ {
+ ready_fds = woe32_select_set_wait (&woe32_rset);
+ }
+
+ if (ready_fds >= 0)
+ {
+ woe32_select_set_fini (&woe32_rset, readfds);
+ }
+
+ return ready_fds;
+}
+/*============================================================================*/