Message ID | 20230515132440.1025315-1-marcandre.lureau@redhat.com |
---|---|
State | New |
Headers | show |
Series | win32: wrap socket close() with an exception handler | expand |
On Mon, May 15, 2023 at 5:25 PM <marcandre.lureau@redhat.com> wrote: > From: Marc-André Lureau <marcandre.lureau@redhat.com> > > Since commit abe34282 ("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> > ping > --- > include/sysemu/os-win32.h | 4 ++++ > util/oslib-win32.c | 23 +++++++++++++++++------ > 2 files changed, 21 insertions(+), 6 deletions(-) > > diff --git a/include/sysemu/os-win32.h b/include/sysemu/os-win32.h > index 15c296e0eb..65f6c9ea57 100644 > --- a/include/sysemu/os-win32.h > +++ b/include/sysemu/os-win32.h > @@ -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 > diff --git a/util/oslib-win32.c b/util/oslib-win32.c > index a98638729a..fafbab80b4 100644 > --- a/util/oslib-win32.c > +++ b/util/oslib-win32.c > @@ -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) > { > @@ -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)) { > -- > 2.40.1 > > >
diff --git a/include/sysemu/os-win32.h b/include/sysemu/os-win32.h index 15c296e0eb..65f6c9ea57 100644 --- a/include/sysemu/os-win32.h +++ b/include/sysemu/os-win32.h @@ -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 diff --git a/util/oslib-win32.c b/util/oslib-win32.c index a98638729a..fafbab80b4 100644 --- a/util/oslib-win32.c +++ b/util/oslib-win32.c @@ -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) { @@ -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)) {