Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
win32: wrap socket close() with an exception handler
Since commit abe3428 ("win32: avoid mixing SOCKET and file descriptor
space"), we set HANDLE_FLAG_PROTECT_FROM_CLOSE on the socket FD, to
prevent closing the HANDLE with CloseHandle. This raises an exception
which under gdb is fatal, and qemu exits.

Let's catch the expected error instead.

Note: this appears to work, but the mingw64 macro is not well documented
or tested, and it's not obvious how it is meant to be used.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20230515132440.1025315-1-marcandre.lureau@redhat.com>
  • Loading branch information
elmarco committed May 28, 2023
1 parent 0b31e48 commit d89f30b
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 6 deletions.
4 changes: 4 additions & 0 deletions include/sysemu/os-win32.h
Expand Up @@ -259,6 +259,10 @@ ssize_t qemu_recv_wrap(int sockfd, void *buf, size_t len, int flags);
ssize_t qemu_recvfrom_wrap(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *addr, socklen_t *addrlen);

EXCEPTION_DISPOSITION
win32_close_exception_handler(struct _EXCEPTION_RECORD*, void*,
struct _CONTEXT*, void*);

#ifdef __cplusplus
}
#endif
Expand Down
23 changes: 17 additions & 6 deletions util/oslib-win32.c
Expand Up @@ -479,6 +479,13 @@ int qemu_bind_wrap(int sockfd, const struct sockaddr *addr,
return ret;
}

EXCEPTION_DISPOSITION
win32_close_exception_handler(struct _EXCEPTION_RECORD*,
void*, struct _CONTEXT*, void*)
{
return EXCEPTION_EXECUTE_HANDLER;
}

#undef close
int qemu_close_socket_osfhandle(int fd)
{
Expand All @@ -504,12 +511,16 @@ int qemu_close_socket_osfhandle(int fd)
return -1;
}

/*
* close() returns EBADF since we PROTECT_FROM_CLOSE the underlying handle,
* but the FD is actually freed
*/
if (close(fd) < 0 && errno != EBADF) {
return -1;
__try1(win32_close_exception_handler) {
/*
* close() returns EBADF since we PROTECT_FROM_CLOSE the underlying
* handle, but the FD is actually freed
*/
if (close(fd) < 0 && errno != EBADF) {
return -1;
}
}
__except1 {
}

if (!SetHandleInformation((HANDLE)s, flags, flags)) {
Expand Down

0 comments on commit d89f30b

Please sign in to comment.