-1

I created a TCP socket and tried to examine its file descriptor. I can list it without a problem:

[/proc/24846/fd]$ ls -al 11
lrwx------ 1 danb danb 64 10-Sep-19 22:58 11 -> 'socket:[38186892]'

But trying to cat or write to the file fails because the shell cannot find the file all of a sudden:

[/proc/24846/fd]$ echo 'hello' > 11
bash: no such device or address: 11
[/proc/24846/fd]$ cat 11
cat: 11: No such device or address

I don't expect those commands to do anything useful, but at least there should be consistency and the file should be found. So why is it that the shell fails to find the file when doing those particular operations?

To clarify, I'm not wondering how can I communicate with the socket via the VFS, but the reason why I cannot perform file operations on this file.

DBedrenko
  • 101
  • 1
    You can't open a Unix-domain socket the same way as an ordinary file. You have to use bind() in the server and connect() in the client. Shell I/O redirection doesn't do this. – Barmar Sep 10 '19 at 21:36
  • I don't want to open the socket or communicate with it from the shell, I'm just wondering why these error messages are shown, as the file is clearly there on the VFS. – DBedrenko Sep 10 '19 at 21:38
  • 1
    It says the device doesn't exist, it doesn't say the filename can't be found. That's because the device is not one that can be accessed using the open() system call. – Barmar Sep 10 '19 at 21:39
  • 1
    If it couldn't find the file, it would say "No such file or directory". – Barmar Sep 10 '19 at 21:40
  • 2
    That's because how the procfs(5) designers decided to do it. Since trying to open() a /proc/PID/fd/FD will try to re-open the actual file from scratch (instead of just returning a dup(2)ed fd), how could that work with a socket fd, which was not obtained with the open(2), but with the socket(2) syscall in the first place? Thence -ENXIO. –  Sep 10 '19 at 21:47

1 Answers1

2

It didn't fail to find the file. That is a different error message; compare to cat /does-not-exist (actually cat not finding it, not the shell) or echo > /path/does/not/exist (the shell not finding it):

$ echo > /path/does/not/exist
bash: /path/does/not/exist: No such file or directory

You're probably getting back ENODEV or ENXIO instead, see man 2 open. strace (on the cat case) could tell you for sure. Here I get ENXIO:

$ ls -l 3
lrwx------. 1 anthony anthony 64 Sep 10 17:39 3 -> 'socket:[11714498]'

$ strace -e open,openat -f cat 3
⋮
openat(AT_FDCWD, "3", O_RDONLY)         = -1 ENXIO (No such device or address)
⋮
derobert
  • 109,670