57

Is there a command similar to mkfifo but for domain sockets?

5 Answers 5

33

There is no exact equivalent of mkfifo for socket, i.e. there is no command that just creates a "hanging" socket. This is for historical reason: server's function bind(), the one that creates a socket name/inode in the filesystem, fails if the name is already used. In other words, server cannot operate on a pre-existing socket.

So if you'd created socket earlier, it would need to be removed by the server anyway first. No benefit. As you see with Gregory's answer, you can create a socket IF you keep a server for it, such as netcat. Once a server is gone, the old socket is gone. A new server has a new socket, and all clients need to re-connect, despite the socket's name being identical.

2
  • 1
    This cannot be true... systemd, for example, creates sockets without attaching them to any services, and when someone attempts to connect to that socket, then systemd starts the service and hands over the socket so communication can happen. I ended up in this thread looking for an answer on how systemd does that. Nov 8, 2022 at 13:56
  • 4
    @SenhorLucas systemd is creating the unix sockets normally, listening for connections, and then just not closing those files when it forks to launch whatever process will receive them. child processes on unix ( including linux ) inherit open files unless you explicitly close them ( or use O_CLOEXEC to do it automatically ). so either the subprocess gets the socket as its stdin/stdout (file descriptor 0/1) or it tells the process what fds to look for with envvars. this is described here: freedesktop.org/software/systemd/man/… Jan 16, 2023 at 23:47
20

I simply use netcat and stay listening in such a case:

nc -lkU aSocket.sock

you should use netcat-openbsd. netcat-traditional does not have -U switch which is for Unix Domain socket.

2
  • 3
    -k Forces nc to stay listening for another connection after its current connection is completed. It is an error to use this option without the -l option. -U Specifies to use UNIX-domain sockets. Aug 29, 2019 at 15:01
  • 1
    Why, then, doesn't the -k option automatically turn on the -l option? Jun 9, 2021 at 1:28
17

Most recent netcat (nc) and similar programs (socat as far as I know) have domain socket options.
Else, you can have a look at ucspi-unix

2
  • 1
    On Debian: # sudo apt-get install netcat-openbsd Apr 24, 2017 at 16:43
  • 4
    ok once you install that, how do you create a "socket file" May 20, 2018 at 4:30
17

You can use python:

python -c "import socket as s; sock = s.socket(s.AF_UNIX); sock.bind('/tmp/test.sock')"

Also C, see this answer.

3
  • 4
    mksock() { SOCK="$1" python -c "import os, socket as s; s.socket(s.AF_UNIX).bind(os.environ['SOCK'])"; } for easy shell use: mksock /tmp/test.sock
    – Tino
    Jul 21, 2019 at 12:39
  • And what will be the use of this socket after the creating program exits? Oct 1, 2023 at 18:36
  • @NikitaKipriyanov, I think I needed that for some testing purposes. So I needed a socket file to see how it was handled. Oct 2, 2023 at 12:27
1

On Linux, it's very simple to create such a program:

#include <sys/stat.h>
#include <stdio.h>
int main(int C, char **V){
    int r=0; while(*++V) if (mknod(*V,S_IFSOCK|0666,0)) r=1,perror(*V);
    return r;
}

mknod on Linux can also make all the other filetypes as per the given S_IF... argument there.

On other UNIXES, I'm afraid you need to do the rather complicated dance of allocating a socket file, binding it and dropping the descriptor:

#include <errno.h>
#include <stddef.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
int main(int C, char **V){
    int r=0; while(*++V){
        int sfd = socket(AF_UNIX,SOCK_DGRAM,0);
        if (0>sfd){ perror("socket"); goto fail; }
        struct sockaddr_un a; a.sun_family = AF_UNIX;
        size_t len = strlen(*V);
        if (len+1 > sizeof(a.sun_path)){ errno=ENAMETOOLONG, perror("bind"); goto close_and_fail; }
        memcpy(a.sun_path,*V,len+1);
        socklen_t socklen = (socklen_t)(len+1+offsetof(struct sockaddr_un,sun_path));
        if (0>bind(sfd,(void*)&a,socklen)) perror("bind");
        else{ close(sfd); continue; }

        close_and_fail:
        close(sfd);
        fail: r=1;
    }
    return r;
}

As has been said, though, creating such orphaned socket files is not very useful. It definitely won't be usable as a socket address (a new wannabe server for that socketfile will need to unlink it first), but it will test (test -S file / [ -S file ] as a file of type socket, which might be usable in some scripts.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .