Skip to content

Commit

Permalink
GUACAMOLE-1841: Always close event handles.
Browse files Browse the repository at this point in the history
  • Loading branch information
jmuehlner committed Aug 2, 2023
1 parent 1c98b79 commit c8a2c41
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 11 deletions.
8 changes: 7 additions & 1 deletion src/guacd/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -372,8 +372,14 @@ static int guacd_add_user(guacd_proc* proc, guac_parser* parser, guac_socket* so
return 1;
}

/* Wait for the other end of the pipe to connect before attempting IO */
/* Create an event to monitor for pipe connection */
HANDLE event = CreateEvent(NULL, FALSE, FALSE, NULL);
if (event == NULL) {
guacd_log(GUAC_LOG_ERROR, "Event creation failed.");
return 1;
}

/* Wait for the other end of the pipe to connect before attempting IO */
OVERLAPPED overlapped = { 0 };
overlapped.hEvent = event;
ConnectNamedPipe(pipe_handle, &overlapped);
Expand Down
25 changes: 20 additions & 5 deletions src/libguac/handle-helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ int guac_read_from_handle(
*/
OVERLAPPED overlapped = { 0 };
overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (overlapped.hEvent == NULL)
return GetLastError();

/* Attempt to start the async read operation */
if (!ReadFile(handle, buffer, count, NULL, &overlapped)) {
Expand All @@ -50,6 +52,7 @@ int guac_read_from_handle(
* return it as the error code immediately.
*/
if (error != ERROR_IO_PENDING) {
CloseHandle(overlapped.hEvent);
return error;
}

Expand All @@ -59,10 +62,14 @@ int guac_read_from_handle(
* Wait on the result of the read. If any error occurs when waiting,
* return the error.
*/
if (!GetOverlappedResult(handle, &overlapped, num_bytes_read, TRUE))
return GetLastError();
if (!GetOverlappedResult(handle, &overlapped, num_bytes_read, TRUE)) {
DWORD error = GetLastError();
CloseHandle(overlapped.hEvent);
return error;
}

/* No errors occured, so the read was successful */
CloseHandle(overlapped.hEvent);
return 0;

}
Expand All @@ -75,6 +82,8 @@ int guac_write_to_handle(
*/
OVERLAPPED overlapped = { 0 };
overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (overlapped.hEvent == NULL)
return GetLastError();

/* Attempt to start the async write operation */
if (!WriteFile(handle, buffer, count, NULL, &overlapped)) {
Expand All @@ -85,19 +94,25 @@ int guac_write_to_handle(
* If an error other than the expected ERROR_IO_PENDING happens,
* return it as the error code immediately.
*/
if (error != ERROR_IO_PENDING)
if (error != ERROR_IO_PENDING) {
CloseHandle(overlapped.hEvent);
return error;
}

}

/*
* Wait on the result of the write. If any error occurs when waiting,
* return the error.
*/
if (!GetOverlappedResult(handle, &overlapped, num_bytes_written, TRUE))
return GetLastError();
if (!GetOverlappedResult(handle, &overlapped, num_bytes_written, TRUE)) {
DWORD error = GetLastError();
CloseHandle(overlapped.hEvent);
return error;
}

/* No errors occured, so the write was successful */
CloseHandle(overlapped.hEvent);
return 0;

}
19 changes: 14 additions & 5 deletions src/libguac/wait-handle.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,12 @@

int guac_wait_for_handle(HANDLE handle, int usec_timeout) {

/* Create an event to be used to signal comm events */
HANDLE event = CreateEvent(NULL, FALSE, FALSE, NULL);
if (event == NULL)
return GetLastError();

OVERLAPPED overlapped = { 0 };

/* Set the event to be used to signal comm events */
overlapped.hEvent = event;

/* Request to wait for new data to be available */
Expand All @@ -41,8 +43,10 @@ int guac_wait_for_handle(HANDLE handle, int usec_timeout) {
DWORD error = GetLastError();

/* ERROR_IO_PENDING is expected in overlapped mode */
if (error != ERROR_IO_PENDING)
if (error != ERROR_IO_PENDING) {
CloseHandle(event);
return error;
}

}

Expand All @@ -51,17 +55,22 @@ int guac_wait_for_handle(HANDLE handle, int usec_timeout) {
DWORD result = WaitForSingleObject(event, millis);

/* The wait attempt failed */
if (result == WAIT_FAILED)
if (result == WAIT_FAILED) {
CloseHandle(event);
return GetLastError();
}

/* The event was signalled, which should indicate data is ready */
else if (result == WAIT_OBJECT_0)
else if (result == WAIT_OBJECT_0) {
CloseHandle(event);
return 0;
}

/*
* If the event didn't trigger and the wait didn't fail, data just isn't
* ready yet.
*/
CloseHandle(event);
return -1;

}

0 comments on commit c8a2c41

Please sign in to comment.