Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I want to determine what process has the other end of a unix socket, that was created with socketpair().

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.

lsof

lsof -c progname lists the open files for all processes named progname. When I execute lsof -c parent -c child1 I see the following (unrelated entries removed):

jonathon@jrr-suse113:/proc/net> lsof -c server -c child
COMMAND   PID     USER   FD   TYPE     DEVICE SIZE/OFF   NODE NAME
server  12923 jonathon    0u   CHR      136,3      0t0      6 /dev/pts/3
server  12923 jonathon    1u   CHR      136,3      0t0      6 /dev/pts/3
server  12923 jonathon    2u   CHR      136,3      0t0      6 /dev/pts/3
server  12923 jonathon    3u  unix 0xf67b8440      0t0  32721 socket
child   12924 jonathon    0u   CHR      136,3      0t0      6 /dev/pts/3
child   12924 jonathon    1u   CHR      136,3      0t0      6 /dev/pts/3
child   12924 jonathon    2u   CHR      136,3      0t0      6 /dev/pts/3
child   12924 jonathon    3u  unix 0xf42ff4c0      0t0  32722 socket

So I see the file descriptors for stdin/out/err, as well as my socket (which has been dup2'd to #3 for the child as well). Additionally, we see the socket device numbers in hex, and node (inode). Yet there is nothing that tells me these two are connected (which they definitely are.)

/proc/xxx/fd

This simply shows me the open file descriptors and what they point to. No surprises here.

jonathon@jrr-suse113:/> ls -l /proc/`pidof server`/fd
total 0
lrwx------ 1 jonathon users 64 2011-07-08 17:58 0 -> /dev/pts/3
lrwx------ 1 jonathon users 64 2011-07-08 17:58 1 -> /dev/pts/3
lrwx------ 1 jonathon users 64 2011-07-08 17:58 2 -> /dev/pts/3
lrwx------ 1 jonathon users 64 2011-07-08 17:58 3 -> socket:[32721]

/proc/net/unix

This also doesn't show me anything that lsof doesn't (probably because these are where it gets its information.)

Num       RefCount Protocol Flags    Type St Inode Path
f42ff4c0: 00000003 00000000 00000000 0001 03 32722
f67b8440: 00000003 00000000 00000000 0001 03 32721

So basically, I can see the two sockets, and everything about them, but cannot tell that they are connected. Before you ask why I want to see this, consider the case where there are 40 different children processes running. I am trying to then determine which FD in the parent is communicating with which child process.

share|improve this question
add comment

2 Answers

up vote 13 down vote accepted

According to the author of lsof, it's 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).

share|improve this answer
1  
Thanks @Gillles. I do recall reading something about that a while back, but was unable to find it again. I may just have to go writing a patch for /proc/net/unix. –  Jonathon Reinhart Jul 9 '11 at 22:09
    
And yes, I'd made that observation with the increasing inode numbers, and currently that's what I'm working with. However, as you noted, it is not guaranteed. The process I'm looking at has at least 40 open unix sockets, and I saw one instance where the N+1 did not hold true. Bummer. –  Jonathon Reinhart Jul 9 '11 at 22:11
1  
@JonathonReinhart I checked the definition of socketpair, 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. It would be nice to have this information for pipes, too. –  Gilles Jul 9 '11 at 22:35
add comment

Erkki Seppala actually has a tool that retrieves this information from the Linux kernel with gdb.. It's available here.

share|improve this answer
1  
Very useful information! Even if the tool didn't work out of the box for me (it caused a kernel Oops), the idea helped me to identify the other end. I described my solution on Stack Overflow. –  MvG Aug 15 '12 at 20:33
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.