22

I have a server application that creates a UNIX Domain Socket in a specific path with a name and bind()s to it.

I need to delete the socket only when I close/stop the application intentionally, from within the the application code; otherwise it needs to be open. How do I do this?

Thanks!

Edit: Consider that I start and run my application from inside a terminal.

Will
  • 24,082
  • 14
  • 97
  • 108
Pheonix7
  • 2,131
  • 5
  • 21
  • 38

6 Answers6

30

You're making this harder than it needs to be. Put the unlink() right before the bind(). That's how everybody else does it. (Example: BSD syslogd, one of the classic unix-domain-socket-based services)

Ersel Er
  • 731
  • 6
  • 22
  • thank you. i thought i had to go after the bind. thanks for specifying it had to go before. – Pheonix7 Jan 19 '16 at 16:37
  • 4
    You could still do an unlink on exit to prevent the stale socket from showing up in directory listings when the server isn't running. But that's purely cosmetic. –  Jan 19 '16 at 16:53
5

If you have multiple exit points from your application and you don't want to modify each of them to call cleanup routine, then you may use "dirty" approach.

When socket is just created, register cleanup routine with atexit(3). Routine (which is simply a call to unlink(2)) will be called when application is terminated normally. But it won't be called if application is terminated with signal. So, if you want to cleanup after receiving SIGINT and similar signals, you also need to setup signal handlers properly.

gudok
  • 4,029
  • 2
  • 20
  • 30
3

You can check if socket if active by looking at /proc/net/unix. Then delete, ether in a cron, or before you start/restart your application.

echo "active sockets in /path/"
cat /proc/net/unix | grep -Eo '/path/.*'

echo "all sockets in path including stale sockets"
ls -1F /path/ | egrep '=$' | sed 's/=$//'

echo "example command to remove stale sockets"
comm -1 -3 <(cat /proc/net/unix | grep -Eo '/path/.*' | sort)  <(ls -1F /path/ | egrep '=$' | sed 's/=$//' | sort) | xargs -n1 echo rm
Jeff Peters
  • 106
  • 3
1

Just execute

unlink("Path/to/Socket");

before you exit your program.

1

If you are using Linux, you can use an abstract namespace socket: Set the first byte in the sockaddr_un.sun_path to \0, and with bytes still in this array. An abstract socket is not placed on the filesystem, which has mild side effects.

References

  1. https://gavv.net/articles/unix-socket-reuse/
  2. man 7 unix

Abstract sockets

Socket permissions have no meaning for abstract sockets: the process umask(2) has no effect when binding an abstract socket, and changing the ownership and permissions of the object (via fchown(2) and fchmod(2)) has no effect on the accessibility of the socket.

Abstract sockets automatically disappear when all open references to the socket are closed.

The abstract socket namespace is a nonportable Linux extension.

bgStack15
  • 180
  • 3
  • 11
0

You can remove the socket file with a simple:

unlink(path);

Wherever you program exit your program, check if it exists, and remove it.

Will
  • 24,082
  • 14
  • 97
  • 108
  • but i exit my application from the terminal, so where would i put the unlink in the code? – Pheonix7 Jan 19 '16 at 10:00
  • It doesn't matter where you exit your application from, unless you're saying that you're hitting `Control-C` or something. In that case, you need to create a signal handler that takes care of the socket before exiting. – David Hoelzer Jan 19 '16 at 10:07