Using Unix domain sockets from Python
Using Unix domain sockets from Python's socket module is pretty easy, but underdocumented. Since I've done it (and I may want to do it again sometime):
- you need to create the socket with an explicit family of
AF_UNIX. I usually go whole-hog and explicitly specify
- the address argument to
.connect()is the path of the Unix socket file. For
.bind(), the file can't already exist, which means that it has to be in a directory that you have write permissions on and you probably want to try to remove it if it's there already.
Note that the address argument is restricted to be fairly short, well below the maximum Unix path or filename limits.
- nothing removes the socket file when the socket closes down, hence
the probable need to remove it before you try to
.bind(). (Yes, on an orderly shutdown you can remove it. And when your daemon doesn't shut down in an orderly way?)
- on Linux, but not necessarily elsewhere, people who want to talk to
your daemon need write permission on the socket file. Since
.bind()creates the file, you are going to need to use either
os.chmod()if you want other UIDs to be able to talk to it; the latter is the simpler option.
(This implies that to portably restrict access to your daemon, you need to put the socket file in a mode 0700 directory that you own. And to portably open access to everyone, you need to both put the socket file in an open directory and make it mode 0666 or so.)
- Unix domain sockets have no peername. Don't bother trying.
Moral: Unix domain socket portability is hard. On the other hand, you do get UID-based access restrictions for free.
Using Unix domain sockets from C is similar but more annoying. You use
struct sockaddr_un, setting the
then memcpy()'ing the path of the socket file into
sun_path. (Be a
good program and check for buffer overflows first.)