portable
portable copied to clipboard
posix_win.c: is_socket(int fd) fails at any socket whose value also exists as a file descriptor
In such situation, v3.8.1+ assumes that fd is not a socket but a file descriptor, while earlier versions always assumed fd to be a socket in first place.
In other words, v3.8.0 and earlier gave a socket precedence over a file descriptor with the same value, while v3.8.1 and later give a file descriptor precedence over a socket with the same value.
The discussion at #266 already outlines possible fixes.
Code snippet to likely produce a socket vs. file descriptor conflict:
#include <io.h>
#include <stdio.h>
#include <WinSock2.h>
int main(int argc, const char *argv[])
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
int sd = (int)socket(AF_INET, SOCK_STREAM, 0);
// Use up file descriptors until fopen() fails
int fd = -1;
while (FILE* f = fopen(argv[0], "rb"))
fd = _fileno(f);
intptr_t sh = _get_osfhandle(sd);
intptr_t fh = _get_osfhandle(fd);
printf("The operating-system file handle associated with fd is %p\n", fh);
printf("The operating-system file handle associated with sd is %p\n", sh);
return 0;
}
Employing _dup2() to achieve the same:
#include <io.h>
#include <stdio.h>
#include <WinSock2.h>
int main(int argc, const char *argv[])
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
int sd = (int)socket(AF_INET, SOCK_STREAM, 0);
// Duplicate stdout descriptor to produce a collision with the socket
_dup2(1, sd);
intptr_t sh = _get_osfhandle(sd);
printf("The operating-system file handle associated with sd is %p\n", sh);
return 0;
}