1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-07 13:11:28 +00:00

Use correct API for clearing events after WSAEventSelect

This commit is contained in:
dmiller
2024-12-06 18:41:55 +00:00
parent 3d1030be38
commit 3a1763e1f6

View File

@@ -418,16 +418,18 @@ static DWORD WINAPI subprocess_thread_func(void *data)
char *crlf = NULL, *wbuf; char *crlf = NULL, *wbuf;
char buffer[BUFSIZ]; char buffer[BUFSIZ];
int pending; int pending;
WSANETWORKEVENTS triggered;
i = WaitForMultipleObjects(3, events, FALSE, INFINITE); i = WaitForMultipleObjects(3, events, FALSE, INFINITE);
switch(i) { switch(i) {
case WAIT_OBJECT_0: case WAIT_OBJECT_0:
/* Read from socket, write to process. */ /* Read from socket, write to process. */
/* Reset events on the socket. SSL_read in particular does not /* Reset events on the socket. */
* clear the event. */ n = WSAEnumNetworkEvents(info->fdn.fd, events[0], &triggered);
ResetEvent(events[0]); ncat_assert(n == 0);
WSAEventSelect(info->fdn.fd, events[0], 0); /* Regardless of what event triggered, try to read. This simplifies
* error handling. */
block_socket(info->fdn.fd); block_socket(info->fdn.fd);
do { do {
n = ncat_recv(&info->fdn, buffer, sizeof(buffer), &pending); n = ncat_recv(&info->fdn, buffer, sizeof(buffer), &pending);
@@ -451,9 +453,10 @@ static DWORD WINAPI subprocess_thread_func(void *data)
goto loop_end; goto loop_end;
} }
} while (pending); } while (pending);
/* Restore the select event (and non-block the socket again.) */ unblock_socket(info->fdn.fd);
WSAEventSelect(info->fdn.fd, events[0], FD_READ | FD_CLOSE); // If ReadFile finished, go on
/* Fall through to check other objects */ if (!HasOverlappedIoCompleted(&overlap))
break;
case WAIT_OBJECT_0 + 1: case WAIT_OBJECT_0 + 1:
/* Read from process, write to socket. */ /* Read from process, write to socket. */
if (GetOverlappedResult(info->child_out_r, &overlap, &n_r, FALSE)) { if (GetOverlappedResult(info->child_out_r, &overlap, &n_r, FALSE)) {
@@ -464,12 +467,6 @@ static DWORD WINAPI subprocess_thread_func(void *data)
wbuf = crlf; wbuf = crlf;
n_r = n; n_r = n;
} }
/* The above call to WSAEventSelect puts the socket in
non-blocking mode, but we want this send to block, not
potentially return WSAEWOULDBLOCK. We call block_socket, but
first we must clear out the select event. */
WSAEventSelect(info->fdn.fd, events[0], 0);
block_socket(info->fdn.fd);
n = ncat_send(&info->fdn, wbuf, n_r); n = ncat_send(&info->fdn, wbuf, n_r);
if (crlf != NULL) if (crlf != NULL)
free(crlf); free(crlf);
@@ -477,8 +474,6 @@ static DWORD WINAPI subprocess_thread_func(void *data)
{ {
goto loop_end; goto loop_end;
} }
/* Restore the select event (and non-block the socket again.) */
WSAEventSelect(info->fdn.fd, events[0], FD_READ | FD_CLOSE);
/* Queue another asychronous read. */ /* Queue another asychronous read. */
ReadFile(info->child_out_r, pipe_buffer, sizeof(pipe_buffer), NULL, &overlap); ReadFile(info->child_out_r, pipe_buffer, sizeof(pipe_buffer), NULL, &overlap);
} else { } else {