aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tests/server/sockfilt.c142
1 files changed, 108 insertions, 34 deletions
diff --git a/tests/server/sockfilt.c b/tests/server/sockfilt.c
index 38015e22f..8acad9611 100644
--- a/tests/server/sockfilt.c
+++ b/tests/server/sockfilt.c
@@ -420,43 +420,53 @@ static int select_ws(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout)
{
long networkevents;
- DWORD milliseconds, wait, idx;
+ DWORD milliseconds, wait, idx, avail, events, inputs;
WSAEVENT wsaevent, *wsaevents;
WSANETWORKEVENTS wsanetevents;
- HANDLE *handles;
- curl_socket_t *fdarr;
+ INPUT_RECORD *inputrecords;
+ HANDLE handle, *handles;
+ curl_socket_t *fdarr, *wsasocks;
int error, fds;
DWORD nfd = 0, wsa = 0;
int ret = 0;
+ /* check if the input value is valid */
if(nfds < 0) {
SET_SOCKERRNO(EINVAL);
return -1;
}
+ /* check if we got descriptors, sleep in case we got none */
if(!nfds) {
- Sleep(1000*timeout->tv_sec + timeout->tv_usec/1000);
+ Sleep((timeout->tv_sec * 1000) + (timeout->tv_usec / 1000));
return 0;
}
/* allocate internal array for the original input handles */
fdarr = malloc(nfds * sizeof(curl_socket_t));
if(fdarr == NULL) {
- errno = ENOMEM;
+ SET_SOCKERRNO(ENOMEM);
return -1;
}
/* allocate internal array for the internal event handles */
handles = malloc(nfds * sizeof(HANDLE));
if(handles == NULL) {
- errno = ENOMEM;
+ SET_SOCKERRNO(ENOMEM);
+ return -1;
+ }
+
+ /* allocate internal array for the internal socket handles */
+ wsasocks = malloc(nfds * sizeof(curl_socket_t));
+ if(wsasocks == NULL) {
+ SET_SOCKERRNO(ENOMEM);
return -1;
}
/* allocate internal array for the internal WINSOCK2 events */
wsaevents = malloc(nfds * sizeof(WSAEVENT));
if(wsaevents == NULL) {
- errno = ENOMEM;
+ SET_SOCKERRNO(ENOMEM);
return -1;
}
@@ -466,14 +476,15 @@ static int select_ws(int nfds, fd_set *readfds, fd_set *writefds,
handles[nfd] = 0;
if(FD_ISSET(fds, readfds))
- networkevents |= FD_READ;
+ networkevents |= FD_READ|FD_ACCEPT|FD_CLOSE;
if(FD_ISSET(fds, writefds))
- networkevents |= FD_WRITE;
+ networkevents |= FD_WRITE|FD_CONNECT;
if(FD_ISSET(fds, exceptfds))
- networkevents |= FD_CLOSE;
+ networkevents |= FD_OOB;
+ /* only wait for events for which we actually care */
if(networkevents) {
fdarr[nfd] = (curl_socket_t)fds;
if(fds == fileno(stdin)) {
@@ -491,10 +502,12 @@ static int select_ws(int nfds, fd_set *readfds, fd_set *writefds,
error = WSAEventSelect(fds, wsaevent, networkevents);
if(error != SOCKET_ERROR) {
handles[nfd] = wsaevent;
- wsaevents[wsa++] = wsaevent;
+ wsasocks[wsa] = (curl_socket_t)fds;
+ wsaevents[wsa] = wsaevent;
+ wsa++;
}
else {
- handles[nfd] = (HANDLE) fds;
+ handles[nfd] = (HANDLE)fds;
WSACloseEvent(wsaevent);
}
}
@@ -516,36 +529,97 @@ static int select_ws(int nfds, fd_set *readfds, fd_set *writefds,
/* loop over the internal handles returned in the descriptors */
for(idx = 0; idx < nfd; idx++) {
- if(wait != WAIT_OBJECT_0 + idx) {
- /* remove from all descriptor sets since this handle did not trigger */
- FD_CLR(fdarr[idx], readfds);
- FD_CLR(fdarr[idx], writefds);
- FD_CLR(fdarr[idx], exceptfds);
+ fds = fdarr[idx];
+ handle = handles[idx];
+
+ /* check if the current internal handle was triggered */
+ if(wait != WAIT_FAILED && (wait - WAIT_OBJECT_0) >= idx &&
+ WaitForSingleObjectEx(handle, 0, FALSE) == WAIT_OBJECT_0) {
+ /* try to handle the event with STD* handle functions */
+ if(fds == fileno(stdin)) {
+ /* check if there is no data in the input buffer */
+ if(!stdin->_cnt) {
+ /* check if we are getting data from a PIPE */
+ if(!GetConsoleMode(handle, &avail)) {
+ /* check if there is no data from PIPE input */
+ if(!PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL))
+ avail = 0;
+ if(!avail)
+ FD_CLR(fds, readfds);
+ } /* check if there is no data from keyboard input */
+ else if (!_kbhit()) {
+ /* check if there are INPUT_RECORDs in the input buffer */
+ if(GetNumberOfConsoleInputEvents(handle, &events)) {
+ if(events > 0) {
+ /* remove INPUT_RECORDs from the input buffer */
+ inputrecords = (INPUT_RECORD*)malloc(events *
+ sizeof(INPUT_RECORD));
+ if(inputrecords) {
+ if(!ReadConsoleInput(handle, inputrecords,
+ events, &inputs))
+ inputs = 0;
+ free(inputrecords);
+ }
+
+ /* check if we got all inputs, otherwise clear buffer */
+ if(events != inputs)
+ FlushConsoleInputBuffer(handle);
+ }
+ }
+
+ /* remove from descriptor set since there is no real data */
+ FD_CLR(fds, readfds);
+ }
+ }
+
+ /* stdin is never ready for write or exceptional */
+ FD_CLR(fds, writefds);
+ FD_CLR(fds, exceptfds);
+ }
+ else if(fds == fileno(stdout) || fds == fileno(stderr)) {
+ /* stdout and stderr are never ready for read or exceptional */
+ FD_CLR(fds, readfds);
+ FD_CLR(fds, exceptfds);
+ }
+ else {
+ /* try to handle the event with the WINSOCK2 functions */
+ error = WSAEnumNetworkEvents(fds, NULL, &wsanetevents);
+ if(error != SOCKET_ERROR) {
+ /* remove from descriptor set if not ready for read/accept/close */
+ if(!(wsanetevents.lNetworkEvents & (FD_READ|FD_ACCEPT|FD_CLOSE)))
+ FD_CLR(fds, readfds);
+
+ /* remove from descriptor set if not ready for write/connect */
+ if(!(wsanetevents.lNetworkEvents & (FD_WRITE|FD_CONNECT)))
+ FD_CLR(fds, writefds);
+
+ /* remove from descriptor set if not exceptional */
+ if(!(wsanetevents.lNetworkEvents & FD_OOB))
+ FD_CLR(fds, exceptfds);
+ }
+ }
+
+ /* check if the event has not been filtered using specific tests */
+ if(FD_ISSET(fds, readfds) || FD_ISSET(fds, writefds) ||
+ FD_ISSET(fds, exceptfds)) {
+ ret++;
+ }
}
else {
- /* first try to handle the event with the WINSOCK2 functions */
- error = WSAEnumNetworkEvents(fdarr[idx], NULL, &wsanetevents);
- if(error != SOCKET_ERROR) {
- /* remove from descriptor set if not ready for read */
- if(!(wsanetevents.lNetworkEvents & FD_READ))
- FD_CLR(fdarr[idx], readfds);
-
- /* remove from descriptor set if not ready for write */
- if(!(wsanetevents.lNetworkEvents & FD_WRITE))
- FD_CLR(fdarr[idx], writefds);
-
- /* remove from descriptor set if not exceptional */
- if(!(wsanetevents.lNetworkEvents & FD_CLOSE))
- FD_CLR(fdarr[idx], exceptfds);
- }
- ret++;
+ /* remove from all descriptor sets since this handle did not trigger */
+ FD_CLR(fds, readfds);
+ FD_CLR(fds, writefds);
+ FD_CLR(fds, exceptfds);
}
}
- for(idx = 0; idx < wsa; idx++)
+ for(idx = 0; idx < wsa; idx++) {
+ WSAEventSelect(wsasocks[idx], NULL, 0);
WSACloseEvent(wsaevents[idx]);
+ }
free(wsaevents);
+ free(wsasocks);
free(handles);
free(fdarr);