aboutsummaryrefslogtreecommitdiff
path: root/tests/server
diff options
context:
space:
mode:
authorMarc Hoersken <info@marc-hoersken.de>2014-04-20 22:15:36 +0200
committerMarc Hoersken <info@marc-hoersken.de>2014-04-20 22:15:36 +0200
commit8ce852a279985520ee4bcc4d1357a1612159afc5 (patch)
tree97d9e8b869e4e1d829abd04297da7f9694012e28 /tests/server
parentfe1c0176c13af6b61ee59a2bc471af5c98e4993b (diff)
sockfilt.c: properly handle disk files, pipes and character input
Diffstat (limited to 'tests/server')
-rw-r--r--tests/server/sockfilt.c93
1 files changed, 79 insertions, 14 deletions
diff --git a/tests/server/sockfilt.c b/tests/server/sockfilt.c
index 7328ca495..b7178add9 100644
--- a/tests/server/sockfilt.c
+++ b/tests/server/sockfilt.c
@@ -515,24 +515,74 @@ static void lograw(unsigned char *buffer, ssize_t len)
*/
static DWORD WINAPI select_ws_stdin_wait_thread(LPVOID lpParameter)
{
+ HANDLE handle, handles[2];
INPUT_RECORD inputrecord;
- HANDLE handle;
- DWORD length;
+ LARGE_INTEGER size, pos;
+ DWORD type, length;
+
+ handle = GetStdHandle(STD_INPUT_HANDLE);
+ handles[0] = (HANDLE) lpParameter;
+ handles[1] = handle;
+ type = GetFileType(handle);
+
+ switch(type) {
+ case FILE_TYPE_DISK:
+ while(WaitForMultipleObjectsEx(2, handles, FALSE, INFINITE, FALSE)
+ == WAIT_OBJECT_0 + 1) {
+ size.QuadPart = 0;
+ if(GetFileSizeEx(handle, &size)) {
+ pos.QuadPart = 0;
+ if(SetFilePointerEx(handle, pos, &pos, FILE_CURRENT)) {
+ if(size.QuadPart == pos.QuadPart)
+ SleepEx(100, FALSE);
+ else
+ break;
+ }
+ else
+ break;
+ }
+ else
+ break;
+ }
+ break;
- handle = (HANDLE) lpParameter;
+ case FILE_TYPE_CHAR:
+ while(WaitForMultipleObjectsEx(2, handles, FALSE, INFINITE, FALSE)
+ == WAIT_OBJECT_0 + 1) {
+ if(GetConsoleMode(handle, &length)) {
+ length = 0;
+ if(PeekConsoleInput(handle, &inputrecord, 1, &length)) {
+ if(length == 1 && inputrecord.EventType != KEY_EVENT)
+ ReadConsoleInput(handle, &inputrecord, 1, &length);
+ else
+ break;
+ }
+ else
+ break;
+ }
+ else
+ break;
+ }
+ break;
- if(GetConsoleMode(handle, &length)) {
- while(WaitForSingleObjectEx(handle, INFINITE, FALSE) == WAIT_OBJECT_0) {
- if(PeekConsoleInput(handle, &inputrecord, 1, &length)) {
- if(length == 1 && inputrecord.EventType != KEY_EVENT)
- ReadConsoleInput(handle, &inputrecord, 1, &length);
+ case FILE_TYPE_PIPE:
+ while(WaitForMultipleObjectsEx(2, handles, FALSE, INFINITE, FALSE)
+ == WAIT_OBJECT_0 + 1) {
+ if(!PeekNamedPipe(handle, NULL, 0, NULL, &length, NULL)) {
+ if(GetLastError() == ERROR_BROKEN_PIPE)
+ SleepEx(100, FALSE);
+ else
+ break;
+ }
else
break;
}
- }
+ break;
+
+ default:
+ WaitForMultipleObjectsEx(2, handles, FALSE, INFINITE, FALSE);
+ break;
}
- else
- ReadFile(handle, NULL, 0, &length, NULL);
return 0;
}
@@ -546,6 +596,7 @@ static int select_ws(int nfds, fd_set *readfds, fd_set *writefds,
curl_socket_t sock, *fdarr, *wsasocks;
long networkevents;
int error, fds;
+ HANDLE threadevent = NULL, threadhandle = NULL;
DWORD nfd = 0, wsa = 0;
int ret = 0;
@@ -613,10 +664,11 @@ static int select_ws(int nfds, fd_set *readfds, fd_set *writefds,
if(networkevents) {
fdarr[nfd] = curlx_sitosk(fds);
if(fds == fileno(stdin)) {
- handles[nfd] = CreateThread(NULL, 0,
+ threadevent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ threadhandle = CreateThread(NULL, 0,
&select_ws_stdin_wait_thread,
- GetStdHandle(STD_INPUT_HANDLE),
- 0, NULL);
+ threadevent, 0, NULL);
+ handles[nfd] = threadhandle;
}
else if(fds == fileno(stdout)) {
handles[nfd] = GetStdHandle(STD_OUTPUT_HANDLE);
@@ -655,6 +707,11 @@ static int select_ws(int nfds, fd_set *readfds, fd_set *writefds,
/* wait for one of the internal handles to trigger */
wait = WaitForMultipleObjectsEx(nfd, handles, FALSE, milliseconds, FALSE);
+ /* signal the event handle for the waiting thread */
+ if(threadevent) {
+ SetEvent(threadevent);
+ }
+
/* loop over the internal handles returned in the descriptors */
for(idx = 0; idx < nfd; idx++) {
handle = handles[idx];
@@ -721,6 +778,14 @@ static int select_ws(int nfds, fd_set *readfds, fd_set *writefds,
WSACloseEvent(wsaevents[idx]);
}
+ if(threadhandle) {
+ WaitForSingleObject(threadhandle, INFINITE);
+ CloseHandle(threadhandle);
+ }
+ if(threadevent) {
+ CloseHandle(threadevent);
+ }
+
free(wsaevents);
free(wsasocks);
free(handles);