portable icon indicating copy to clipboard operation
portable copied to clipboard

posix_win.c: is_socket(int fd) fails at any socket whose value also exists as a file descriptor

Open datadiode opened this issue 1 year ago • 0 comments

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;
}

datadiode avatar Jul 09 '24 08:07 datadiode