add an invalid parameter handler to catch _get_osfhandle failures under visual studio

The sfds code blindly uses _get_osfhandle on values that may be file
descriptors, sockets or io handles.  Under visual studio, _get_osfhandle
will call the invalid parameter handler for items that are not file
descriptors.  Adding the handler allows us to call this in the same way
that mingw does.  We will still get an assertion, but a prior change
sends those to stdiout instead of making the user click through a
dialog.
This commit is contained in:
dkulwin 2015-11-04 18:45:37 -06:00
parent 58d15ecb9a
commit 11561cd62a
1 changed files with 95 additions and 53 deletions

View File

@ -33,6 +33,7 @@
#include <io.h>
#include "sfds.h"
extern void debug(const char *fmt,...);
extern void debug2(const char *fmt,...);
extern void debug3(const char *fmt,...);
@ -54,69 +55,110 @@ static int sfd_map_init = 0;
static int sfd_count = 0;
int sfd_start = 0;
void myInvalidParameterHandler(const wchar_t* expression,
const wchar_t* function,
const wchar_t* file,
unsigned int line,
uintptr_t pReserved)
{
return;
}
/*
* store real fd in map, detect fd type and return sfd number.
*/
int allocate_sfd(int fd_or_handle)
{
int slot = SFD_FD_INVALID;
int i;
int real_fd;
int slot = SFD_FD_INVALID;
int i;
int real_fd;
HANDLE real_handle;
DWORD handle_type;
HANDLE real_handle;
/*
* Init the map once
*/
if (!sfd_map_init)
{
sfd_map_init = 1;
for (i = 0; i < SFD_MAP_SIZE; ++i)
{
sfd_map[i].fd = SFD_FD_INVALID;
sfd_map[i].type = SFD_TYPE_NONE;
}
}
DWORD handle_type;
/*
* Find an open slot
*/
for (i = sfd_start; i < SFD_MAP_SIZE; ++i)
{
/*
* Is this slot open?
*/
if (sfd_map[i].fd == SFD_FD_INVALID)
{
slot = i;
break;
}
}
/*
* Bail if no slot found
*/
if (slot == SFD_FD_INVALID)
{
error("ERROR: Too many connections.");
return -1;
}
/*
* Init the map once
*/
/*
* Detect and save real fd and real handle
*/
real_handle = (HANDLE) _get_osfhandle(fd_or_handle);
if (!sfd_map_init)
{
sfd_map_init = 1;
for (i = 0; i < SFD_MAP_SIZE; ++i)
{
sfd_map[i].fd = SFD_FD_INVALID;
sfd_map[i].type = SFD_TYPE_NONE;
}
}
/*
* Find an open slot
*/
for (i = sfd_start; i < SFD_MAP_SIZE; ++i)
{
/*
* Is this slot open?
*/
if (sfd_map[i].fd == SFD_FD_INVALID)
{
slot = i;
break;
}
}
/*
* Bail if no slot found
*/
if (slot == SFD_FD_INVALID)
{
error("ERROR: Too many connections.");
return -1;
}
#if 0
/*
* Detect and save real fd and real handle
*/
int optVal;
int optLen = sizeof(int);
BOOL bIsSocket = TRUE;
HRESULT hr = S_OK;
int ret = getsockopt(fd_or_handle,
SOL_SOCKET,
SO_DEBUG,
(char*)&optVal,
&optLen);
if (ret == SOCKET_ERROR && WSAGetLastError() == WSAENOTSOCK)
{
bIsSocket = FALSE;
}
// if (!bIsSocket && fd_or_handle > 600)
// bIsSocket = TRUE;
if (bIsSocket == TRUE)
real_handle = (HANDLE)fd_or_handle;
else
#endif
_invalid_parameter_handler oldHandler, newHandler;
newHandler = myInvalidParameterHandler;
oldHandler = _set_invalid_parameter_handler(newHandler);
real_handle = (HANDLE)_get_osfhandle(fd_or_handle);
_set_invalid_parameter_handler(oldHandler);
if (real_handle == INVALID_HANDLE_VALUE)
{