listen: Misleading error message when directory of IPC socket does not exist
- Version: v15.0.0-pre (built from source on commit 40364b18)
- Platform: Linux (hostname) 4.19.0-11-amd64 #1 SMP Debian 4.19.146-1 (2020-09-17) x86_64 GNU/Linux
- Subsystem: net
What steps will reproduce the bug?
Input:
const net = require('net')
let server = net.createServer()
server.listen('/tmp/nonexistent/ipc.sock')
Output (when run as script):
events.js:304
throw er; // Unhandled 'error' event
^
Error: listen EACCES: permission denied /tmp/nonexistent/ipc.sock
at Server.setupListenHandle [as _listen2] (net.js:1272:21)
at listenInCluster (net.js:1337:12)
at Server.listen (net.js:1434:5)
at [stdin]:3:8
at Script.runInThisContext (vm.js:132:18)
at Object.runInThisContext (vm.js:309:38)
at internal/process/execution.js:77:19
at [stdin]-wrapper:6:22
at evalScript (internal/process/execution.js:76:60)
at internal/main/eval_stdin.js:29:5
Emitted 'error' event on Server instance at:
at emitErrorNT (net.js:1316:8)
at processTicksAndRejections (internal/process/task_queues.js:80:21) {
code: 'EACCES',
errno: -13,
syscall: 'listen',
address: '/tmp/nonexistent/ipc.sock',
port: -1
}
When run directly in the node prompt, the output is different, but the difference is not relevant here.
How often does it reproduce? Is there a required condition?
Always reproducible, no conditions
What is the expected behavior?
The error message tells something like "ENOENT: no such file or directory", code
and errno
show 'ENOENT'
and 2
(or maybe -2
) respectively.
What do you see instead?
The error message claims that there was a permission denied error (EACCES), which is not the case.
Additional information
Relevant excerpt from strace
:
socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 18
bind(18, {sa_family=AF_UNIX, sun_path="/tmp/nonexistent/ipc.sock"}, 110) = -1 ENOENT (No such file or directory)
close(18)
This clearly shows that the OS actually does report ENOENT correctly, but somehow that gets mangled into EACCES.