extcap: Close pipe on windows properly

Windows implements so called CRT handlers, which will catch any
assertions happening inside so called crt routines and either
displays a debug dialog (Cancel, Retry, Ignore) or outright crashes
the application.

See
https://docs.microsoft.com/en-us/cpp/c-runtime-library/parameter-validation?view=msvc-170
for an explanation of the behaviour.

Now, in the current situation here, close will detect (correctly)
that the pipe it is supposed to be closing is already closed. This
happens (again correctly) because it had been closed by the extcap
application.

The change added, checks for a closed pipe first, and if so just
returns -1 (as it should) silently without calling the CRT routine,
therefore not crashing
This commit is contained in:
Roland Knall 2022-05-16 14:48:37 +02:00 committed by Roland Knall
parent acdda8eb6b
commit 28b917a72e
3 changed files with 25 additions and 1 deletions

View File

@ -803,7 +803,8 @@ void InterfaceToolbar::stopCapture()
if (interface_[ifname].out_fd != -1)
{
ws_close (interface_[ifname].out_fd);
ws_close_if_possible (interface_[ifname].out_fd);
interface_[ifname].out_fd = -1;
}

View File

@ -51,6 +51,7 @@
#include <glib.h>
#include <windows.h>
#include <winsock2.h>
#include <errno.h>
#include <wchar.h>
#include <tchar.h>
@ -668,6 +669,21 @@ void close_app_running_mutex() {
}
}
int ws_close_if_possible(int fd) {
fd_set rfds;
struct timeval tv = { 0, 1 };
int retval;
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
retval = select(1, &rfds, NULL, NULL, &tv);
if (retval > -1)
return _close(fd);
return -1;
}
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*

View File

@ -165,6 +165,10 @@ WS_DLL_PUBLIC void create_app_running_mutex(void);
*/
WS_DLL_PUBLIC void close_app_running_mutex(void);
/** Close a file descriptor if it is not open
*/
WS_DLL_PUBLIC int ws_close_if_possible(int fd);
#else /* _WIN32 */
/*
@ -195,6 +199,9 @@ typedef ssize_t ws_file_ssize_t;
#else
#define ws_close close
#endif
#define ws_close_if_possible ws_close
#define ws_dup dup
#ifdef HAVE_FSEEKO
#define ws_fseek64 fseeko /* AC_SYS_LARGEFILE should make off_t 64-bit */