I don't know if a socket file in use should count as an open file, but in the case of unix domain sockets, lsof
will only list as NAME
(and is only able to find by) the exact name a socket was bound to, whether that's a relative or absolute path, and with any path artifacts left unchanged:
$ cd /tmp
$ nc -dUl ./././///sock &
[3] 6324
$ ls sock /tmp/sock ./sock
./sock /tmp/sock sock
$ lsof sock /tmp/sock ./sock
[nothing]
$ lsof ./././///sock
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nc 6324 XXX 3u unix 0xffff9f9faab76000 0t0 175260 ./././///sock type=STREAM
Notice that in the case of a non-abstract unix domain socket, the path the socket was bound or connected to matters only until the kernel has resolved it; it's the [device,inode] tuple which is the real address the socket is bound or connected to:
$ cd /tmp
$ nc -dUl ./././///sock &
[1] 7293
$ mv sock SOCK
$ lsof -aUp $!
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nc 7293 xxx 3u unix 0xffff908d70bb5800 0t0 1137631 ./././///sock type=STREAM
$ lsof ./././///sock
lsof: status error on ./././///sock: No such file or directory
[stupid junk snipped]
$ lsof SOCK
[nothing]
$ nc -U ./././///sock
nc: unix connect failed: No such file or directory
$ nc -U SOCK
[connected ok]
lsof
is also not able to find datagram sockets "connected" (ie. with their default send address set) to another socket, is making impossible to distinguish abstract sockets with a @
in their name from those with a NUL byte in their name, etc.
Just in case someone's wondering, all the needed info is available via the sock_diag
interface (UDIAG_SHOW_VFS
, UDIAG_SHOW_PEER
look at the linux/unix_udiag.h
header); it's just that lsof
is too dumb to make use of it.
Note: the examples are using the nc
from the netcat-openbsd
package from Debian, which supports Unix sockets.