Reputation: 188
First time working with Unix domain sockets, now I'm trying to implement the cleanup part.
It already seemed a bit ugly that the general recommendation when creating your listening socket is to first try to unlink the desired socket path and then call bind. While you probably should make sure that your process is only running once, I'm trying to prepare for the situation where for some reason it will be launched twice. For the service itself it doesn't matter too much: The first instance's socket is unlinked by the second instance, so it's unreachable, wastes some RAM, but doesn't do any harm. But how would I implement cleanup that works in this situation? Simply doing
close(sockFd);
unlink(sockPath);
would lead to the situation that if the first process exits while the second is still running, it would actually delete the second process' socket from the file system. Boom, no service.
I can only think of a few ugly hacks that wouldn't be atomic so could still mess things up, so I'm hoping there is a better paradigm to prevent ending up in this situation. Something like funlink(sockFd) would have been nice. Otherwise I'd have to resort to never cleaning up the socket, which isn't the end of the world, but feels quite messy to me.
Abstract domain sockets looked quite promising (even though it would tie me to Linux for now), but unfortunatly they don't seem to support permissions, which is a requirement in my case.
Upvotes: 1
Views: 1914
Reputation: 297
You could use a separate lock file that your application locks with flock(..., LOCK_EX)
before doing anything with the socket. As long as all application instances agree on what lock file to use you are safe, and flock()
is atomic. Cleanup is no issue with flock()
as the lock is released when the process dies.
Upvotes: 1