/[cvs]/ccvs/windows-NT/woe32.c
ViewVC logotype

Diff of /ccvs/windows-NT/woe32.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.12 by conradpino, Mon Sep 26 03:09:15 2005 UTC revision 1.13 by conradpino, Fri Sep 30 07:13:04 2005 UTC
# Line 23  Line 23 
23  #include "woe32.h"  #include "woe32.h"
24    
25  #include <stdio.h>  #include <stdio.h>
26  #include <conio.h>  #include <assert.h>
27    #include <errno.h>
28    
29  #include <sys/socket.h>  /* This does: #include <windows.h> */  #include <sys/socket.h>  /* This does: #include <windows.h> */
30    
# Line 55  woe32_cleanup (void) Line 56  woe32_cleanup (void)
56    
57    
58    
59    /*============================================================================*/
60    /*
61    How Microsoft does fd_set in Windows 2000 and Visual C++ 6.0:
62    
63            * Select uses arrays of SOCKETs.  These macros manipulate such
64            * arrays.  FD_SETSIZE may be defined by the user before including
65            * this file, but the default here should be >= 64.
66            *
67            * CAVEAT IMPLEMENTOR and USER: THESE MACROS AND TYPES MUST BE
68            * INCLUDED IN WINSOCK2.H EXACTLY AS SHOWN HERE.
69    
70            #ifndef FD_SETSIZE
71            #define FD_SETSIZE      64
72            #endif
73    
74            typedef struct fd_set {
75                    u_int   fd_count;
76                    SOCKET  fd_array[FD_SETSIZE];
77            } fd_set;
78    
79    Microsoft packs all handles between fd_array[0] and fd_array[fd_count-1]
80    */
81    
82    typedef struct
83    {
84            int     is_ready;
85            SOCKET  crt;
86            DWORD   type;
87            union
88            {
89                    long    osf;
90                    HANDLE  w32;
91            };
92    } woe32_handle_set;
93    
94    typedef struct
95    {
96            u_int ready_count, used_count;
97            woe32_handle_set handle[ FD_SETSIZE ];
98    } woe32_select_set;
99    
100    static int woe32_select_set_fini (woe32_select_set * w32_set, fd_set * crt_set)
101    {
102            FD_ZERO (crt_set);
103    
104            if (w32_set->ready_count)
105            {
106                    u_int index;
107                    woe32_handle_set * handle;
108    
109                    index = 0;
110                    handle = w32_set->handle;
111                    while (index < w32_set->used_count)
112                    {
113                            if (handle->is_ready)
114                            {
115                                    FD_SET (handle->crt, crt_set);
116                            }
117    
118                            ++index;
119                            ++handle;
120                    }
121            }
122    
123            return w32_set->ready_count;
124    }
125    
126    static int woe32_select_set_init (woe32_select_set * w32_set, fd_set * crt_set)
127    {
128            u_int index;
129            DWORD dwBytesAvail;
130            woe32_handle_set * handle;
131                    
132            w32_set->ready_count = w32_set->used_count = index = 0;
133            handle = w32_set->handle;
134    
135            if (crt_set) while (index < crt_set->fd_count)
136            {
137                    handle->crt = crt_set->fd_array[index];
138    
139                    handle->osf = _get_osfhandle (handle->crt);
140                    if (handle->w32 == INVALID_HANDLE_VALUE)
141                    {
142                            errno = EBADF;
143                            return -1;
144                    }
145    
146                    handle->type = GetFileType (handle->w32);
147                    switch (handle->type)
148                    {
149                    case FILE_TYPE_DISK:
150                            w32_set->ready_count += handle->is_ready = 1;
151                            break;
152    
153                    case FILE_TYPE_PIPE:
154                            if ( PeekNamedPipe (handle->w32, NULL, 0, NULL, &dwBytesAvail, NULL) )
155                            {
156                                    w32_set->ready_count += handle->is_ready = dwBytesAvail > 0;
157                            }
158                            else
159                            {
160                                    errno = EBADF;
161                                    return -1;
162                            }
163                            break;
164    
165                    case FILE_TYPE_CHAR:
166                    case FILE_TYPE_REMOTE:
167                    case FILE_TYPE_UNKNOWN:
168                    default:
169                            errno = EBADF;
170                            return -1;
171                    }
172    
173                    ++index;
174                    ++handle;
175            }
176            w32_set->used_count = index;
177    
178            while (index < FD_SETSIZE)
179            {
180                    handle->crt = -1;
181    
182                    handle->w32 = INVALID_HANDLE_VALUE;
183    
184                    handle->type = FILE_TYPE_UNKNOWN;
185    
186                    handle->is_ready = 0;
187    
188                    ++index;
189                    ++handle;
190            }
191    
192            return w32_set->ready_count;
193    }
194    
195    static int woe32_select_set_wait (woe32_select_set * w32_set)
196    {
197            char buffer[ 8 ];
198            DWORD dwBytesRead;
199    
200            /* set contains only non-ready pipes */
201            if (w32_set->used_count != 1)
202            {
203                    errno = EINVAL;
204                    return -1;
205            }
206    
207            if (! ReadFile (w32_set->handle[0].w32, buffer, 0, &dwBytesRead, NULL))
208            {
209                    errno = EBADF;
210                    return -1;
211            }
212    
213            return w32_set->handle[0].is_ready = 1;
214    }
215    
216    /* #define fd_select woe32_fd_select */
217    #undef fd_select
218    int woe32_fd_select (   int nfds,
219                                                    struct fd_set * readfds,
220                                                    struct fd_set * writefds,
221                                                    struct fd_set * errorfds,
222                                                    struct timeval * timeout)
223    {
224            int ready_fds;
225            woe32_select_set woe32_rset;
226    
227            /* we don't support these for now */
228            assert(writefds != NULL);
229            assert(errorfds != NULL);
230            assert(timeout != NULL);
231    
232            /* Windows doesn't care but POSIX says it does */
233            if (nfds < 0 || nfds > FD_SETSIZE)
234            {
235                    errno = EINVAL;
236                    return -1;
237            }
238    
239            ready_fds = woe32_select_set_init (&woe32_rset, readfds);
240            if (! ready_fds)
241            {
242                    ready_fds = woe32_select_set_wait (&woe32_rset);
243            }
244    
245            if (ready_fds >= 0)
246            {
247                    woe32_select_set_fini (&woe32_rset, readfds);
248            }
249    
250            return ready_fds;
251    }
252    /*============================================================================*/
253    
254    
255    
256  char *  char *
257  woe32_getlogin (void)  woe32_getlogin (void)
258  {  {

Legend:
Removed from v.1.12  
changed lines
  Added in v.1.13

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26