Unix Socket – Who’s Got the Other End of This Socketpair

lsofopen filesprocesssocket

I want to determine which process has the other end of a UNIX socket.

Specifically, I'm asking about one that was created with socketpair(), though the problem is the same for any UNIX socket.

I have a program parent which creates a socketpair(AF_UNIX, SOCK_STREAM, 0, fds), and fork()s. The parent process closes fds[1] and keeps fds[0] to communicate. The child does the opposite, close(fds[0]); s=fds[1]. Then the child exec()s another program, child1. The two can communicate back and forth via this socketpair.

Now, let's say I know who parent is, but I want to figure out who child1 is. How do I do this?

There are several tools at my disposal, but none can tell me which process is on the other end of the socket. I have tried:

  • lsof -c progname
  • lsof -c parent -c child1
  • ls -l /proc/$(pidof server)/fd
  • cat /proc/net/unix

Basically, I can see the two sockets, and everything about them, but cannot tell that they are connected. I am trying to determine which FD in the parent is communicating with which child process.

Best Answer

Since kernel 3.3, it is possible using ss or lsof-4.89 or above — see Stéphane Chazelas's answer.

In older versions, according to the author of lsof, it was impossible to find this out: the Linux kernel does not expose this information. Source: 2003 thread on comp.unix.admin.

The number shown in /proc/$pid/fd/$fd is the socket's inode number in the virtual socket filesystem. When you create a pipe or socket pair, each end successively receives an inode number. The numbers are attributed sequentially, so there is a high probability that the numbers differ by 1, but this is not guaranteed (either because the first socket was N and N+1 was already in use due to wrapping, or because some other thread was scheduled between the two inode allocations and that thread created some inodes too).

I checked the definition of socketpair in kernel 2.6.39, and the two ends of the socket are not correlated except by the type-specific socketpair method. For unix sockets, that's unix_socketpair in net/unix/af_unix.c.