How to re-bind local socket after it was closed?

Viewed 268

If a unix socket is bound to a path, listen()s and do some work, after which it is closed, the socket "file" remains in the filesystem. But if I try to connect() to that path, I get

Connect errno:111
Connection refused

So what is left after the "artifact"? It is still an inode on filesystem (I can see it with ls), but it is not bound, not listening, and I cannot cat it, otherwise I get

cat: /tmp/unix.str: No such device or address

So what remains from the inode? And how can I make that "artifact" once more alive, bound and listening socket (without removing it, and creating fresh new socket with that path)?

  1. What is the purpose of "dead" local socket (why is it not remove after it was closed, when there is no usage with it anymore)?

  2. how can I revive the "dead" socket? (the main question)

  3. who is responsible for error connection refused? not being bind()ed or not listen()ing?

1 Answers

You get "connection refused" when attempting to connect because nothing is listening on that local socket. It's the same as if you tried to make a connection to a TCP socket if nothing was listening on that port number.

Once the program that opened the socket is closed, it is the responsibility of that process to remove the file with unlink. The man page states:

Binding to a socket with a filename creates a socket in the filesystem that must be deleted by the caller when it is no longer needed (using unlink(2)). The usual UNIX close-behind semantics apply; the socket can be unlinked at any time and will be finally removed from the filesystem when the last reference to it is closed.

This of course could be a problem if the program crashes unexpectedly, so you could get around this by additionally using a lock file.

Another alternative is to use an abstract socket address. This is done by setting the first byte of sun_path in sockaddr_un to 0 and the remaining bytes to a null terminated string specifying the socket name. For example:

struct sockaddr_un sun;
sun.sun_family = AF_UNIX;
sun.sun_path[0] = 0;
strcpy(sun.sunpath + 1, "mysocketname");

This gives you a named socket without a corresponding socket file in the filesystem. This socket will automatically go away once the socket descriptor is closed, so another socket may then be opened with that name.

Related