1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS WinSock 2 API 4 * FILE: dll/win32/ws2_32/src/select.c 5 * PURPOSE: Socket Select Support 6 * PROGRAMMER: Alex Ionescu (alex@relsoft.net) 7 */ 8 9 /* INCLUDES ******************************************************************/ 10 11 #include <ws2_32.h> 12 13 #define NDEBUG 14 #include <debug.h> 15 16 /* FUNCTIONS *****************************************************************/ 17 18 /* 19 * @implemented 20 */ 21 INT 22 WSPAPI 23 __WSAFDIsSet(SOCKET s, 24 LPFD_SET set) 25 { 26 INT i = set->fd_count; 27 INT Return = FALSE; 28 29 /* Loop until a match is found */ 30 while (i--) if (set->fd_array[i] == s) Return = TRUE; 31 32 /* Return */ 33 return Return; 34 } 35 36 /* 37 * @implemented 38 */ 39 INT 40 WSAAPI 41 select(IN INT s, 42 IN OUT LPFD_SET readfds, 43 IN OUT LPFD_SET writefds, 44 IN OUT LPFD_SET exceptfds, 45 IN CONST struct timeval *timeout) 46 { 47 PWSSOCKET Socket; 48 INT Status; 49 INT ErrorCode; 50 SOCKET Handle; 51 LPWSPSELECT WSPSelect; 52 53 DPRINT("select: %lx %p %p %p %p\n", s, readfds, writefds, exceptfds, timeout); 54 55 /* Check for WSAStartup */ 56 ErrorCode = WsQuickProlog(); 57 58 if (ErrorCode != ERROR_SUCCESS) 59 { 60 SetLastError(ErrorCode); 61 return SOCKET_ERROR; 62 } 63 64 /* Use the first Socket from the first valid set */ 65 if (readfds && readfds->fd_count) 66 { 67 Handle = readfds->fd_array[0]; 68 } 69 else if (writefds && writefds->fd_count) 70 { 71 Handle = writefds->fd_array[0]; 72 } 73 else if (exceptfds && exceptfds->fd_count) 74 { 75 Handle = exceptfds->fd_array[0]; 76 } 77 else 78 { 79 /* Invalid handles */ 80 SetLastError(WSAEINVAL); 81 return SOCKET_ERROR; 82 } 83 84 /* Get the Socket Context */ 85 Socket = WsSockGetSocket(Handle); 86 87 if (!Socket) 88 { 89 /* No Socket Context Found */ 90 SetLastError(WSAENOTSOCK); 91 return SOCKET_ERROR; 92 } 93 94 /* Get the select procedure */ 95 WSPSelect = Socket->Provider->Service.lpWSPSelect; 96 97 /* Make the call */ 98 Status = WSPSelect(s, readfds, writefds, exceptfds, (struct timeval *)timeout, 99 &ErrorCode); 100 101 /* Deference the Socket Context */ 102 WsSockDereference(Socket); 103 104 /* Return Provider Value */ 105 if (Status != SOCKET_ERROR) 106 return Status; 107 108 /* If everything seemed fine, then the WSP call failed itself */ 109 if (ErrorCode == NO_ERROR) 110 ErrorCode = WSASYSCALLFAILURE; 111 112 /* Return with an error */ 113 SetLastError(ErrorCode); 114 return SOCKET_ERROR; 115 } 116 117 /* 118 * @unimplemented 119 */ 120 INT 121 WSPAPI 122 WPUFDIsSet(IN SOCKET s, 123 IN LPFD_SET set) 124 { 125 UNIMPLEMENTED; 126 return (SOCKET)0; 127 } 128 129 /* 130 * @implemented 131 */ 132 INT 133 WSAAPI 134 WSAAsyncSelect(IN SOCKET s, 135 IN HWND hWnd, 136 IN UINT wMsg, 137 IN LONG lEvent) 138 { 139 PWSSOCKET Socket; 140 INT Status; 141 INT ErrorCode; 142 DPRINT("WSAAsyncSelect: %lx, %lx, %lx, %lx\n", s, hWnd, wMsg, lEvent); 143 144 /* Check for WSAStartup */ 145 if ((ErrorCode = WsQuickProlog()) == ERROR_SUCCESS) 146 { 147 /* Get the Socket Context */ 148 if ((Socket = WsSockGetSocket(s))) 149 { 150 /* Make the call */ 151 Status = Socket->Provider->Service.lpWSPAsyncSelect(s, 152 hWnd, 153 wMsg, 154 lEvent, 155 &ErrorCode); 156 /* Deference the Socket Context */ 157 WsSockDereference(Socket); 158 159 /* Return Provider Value */ 160 if (Status == ERROR_SUCCESS) return Status; 161 162 /* If everything seemed fine, then the WSP call failed itself */ 163 if (ErrorCode == NO_ERROR) ErrorCode = WSASYSCALLFAILURE; 164 } 165 else 166 { 167 /* No Socket Context Found */ 168 ErrorCode = WSAENOTSOCK; 169 } 170 } 171 172 /* Return with an Error */ 173 SetLastError(ErrorCode); 174 return SOCKET_ERROR; 175 } 176 177 /* 178 * @implemented 179 */ 180 INT 181 WSAAPI 182 WSAEventSelect(IN SOCKET s, 183 IN WSAEVENT hEventObject, 184 IN LONG lNetworkEvents) 185 { 186 PWSSOCKET Socket; 187 INT Status; 188 INT ErrorCode; 189 190 /* Check for WSAStartup */ 191 if ((ErrorCode = WsQuickProlog()) == ERROR_SUCCESS) 192 { 193 /* Get the Socket Context */ 194 if ((Socket = WsSockGetSocket(s))) 195 { 196 /* Make the call */ 197 Status = Socket->Provider->Service.lpWSPEventSelect(s, 198 hEventObject, 199 lNetworkEvents, 200 &ErrorCode); 201 /* Deference the Socket Context */ 202 WsSockDereference(Socket); 203 204 /* Return Provider Value */ 205 if (Status == ERROR_SUCCESS) return Status; 206 } 207 else 208 { 209 /* No Socket Context Found */ 210 ErrorCode = WSAENOTSOCK; 211 } 212 } 213 214 /* Return with an Error */ 215 SetLastError(ErrorCode); 216 return SOCKET_ERROR; 217 } 218