Home > Enterprise >  AF_UNIX socket in Linux above Windows WSL fails to bind to /mnt file: error 95, Operation not suppor
AF_UNIX socket in Linux above Windows WSL fails to bind to /mnt file: error 95, Operation not suppor

Time:07-22

We need to connect a Windows client application to a Linux server one. The Linux side runs on top of WSL2 in Windows 10 (10.0.19044).

We want to use UNIX domain sockets, and followed guidance in https://devblogs.microsoft.com/commandline/windowswsl-interop-with-af_unix/

The server program succeeds to bind to a file in the 'local' filesystem (such as /tmp/mysock), but fails to bind to a 'Windows-sided" file in the mounted drive (such as /mnt/c/mysock), which is required so that the server can accept connections from a Windows-side AF_UNIX socket.

The errno I get is 95 : "Operation not supported" I've tried running with sudo, but same result.

Any idea on what's going on?

The server code is:

#include <sys/socket.h>
#include <sys/un.h>

#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <errno.h>

#undef NDEBUG

// filename comes as command-line argument
int main(int argc, char *argv[])
{
    struct sockaddr_un addr;
    int ret = -1;
    
    printf("Starting NVC_LINUX...\n");
    
    assert(argc == 2);
    char *filename = argv[1];
    
    int sfd = socket(AF_UNIX, SOCK_STREAM, 0);
    assert(sfd != -1);

    // Delete any file that already exists at the address. Make sure the deletion
    // succeeds. If the error is just that the file/directory doesn't exist, it's fine.
    ret = remove(filename);
    assert(ret != -1 || errno == ENOENT);

    // Zero out the address, and set family and path.
    memset(&addr, 0, sizeof(struct sockaddr_un));
    addr.sun_family = AF_UNIX;
    assert(strlen(filename) <= sizeof(addr.sun_path) - 1);
    strncpy(addr.sun_path, filename, sizeof(addr.sun_path) - 1);

    ret = bind(sfd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
    if (ret == -1) printf("errno : %d - %s\n", errno, strerror(errno));
    assert(ret != -1);

    ret = listen(sfd, 1);
    assert(ret != -1);

    printf("Waiting to accept a connection...\n");
    // NOTE: blocks until a connection request arrives.
    int cfd = accept(sfd, NULL, NULL);
    assert(cfd != -1);
    printf("Accepted socket fd = %d\n", cfd);

    char cmd;
    char res[32];
    while (1)
    {
        // get char from Win side
        ssize_t num_read = read(cfd, (void *) &cmd, sizeof(cmd));
        assert(num_read == sizeof(cmd));

        printf("  cmd=%c\n", cmd);
        
        // generate reply
        sprintf(res, "Hello from Linux, %c\n", cmd);

        // send data
        ssize_t num_written = write(cfd, (const void *) res, sizeof(res));
        assert(num_written == sizeof(res));
    }

    (void) close(cfd);
    (void) close(sfd);

    printf("done.\n");
    return 0;
}

CodePudding user response:

In quite-the-coincidence, I was searching the WSL Github issues yesterday for information on the X11 socket when I came across this (unrelated to my topic, but relevant to yours) issue regarding AF_UNIX support in WSL2, which caught my eye simply because it was closed recently as By Design.

In short, AF_UNIX isn't support under WSL2 at this time. If possible for your application, consider converting (or copying) the WSL distro to WSL1, where AF_UNIX is supported.

Alternatively, you might could use a network connection between the Windows and Linux ends.

  • Related