On some platforms (like FreeBSD, Darwin, GNU/Hurd, ...), `getsockname` returns an empty string for sockets in the UNIX domain.
On FreeBSD and Darwin, the `kqueue` event loop implementation will call `fcntl` with `F_KINFO`/`F_GETPATH` to get the path of the file before calling the final system interfaces. On other platforms that do not use kqueue (for example, GNU/Hurd uses posix-poll), the path cannot be got in these way and `uv__stat` will be called with an empty string resulting in an error. However, we do have stored the path info in `pipe_fname` of `uv_pipe_t`, so we can try to use this if `getsockname` returns an empty string. --- src/unix/pipe.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/unix/pipe.c b/src/unix/pipe.c index 6bfe6cf2..1884b3ac 100644 --- a/src/unix/pipe.c +++ b/src/unix/pipe.c @@ -450,6 +450,7 @@ int uv_pipe_chmod(uv_pipe_t* handle, int mode) { unsigned desired_mode; struct stat pipe_stat; char name_buffer[1 + UV__PATH_MAX]; + const char* name = name_buffer; size_t name_len; int r; @@ -467,8 +468,11 @@ int uv_pipe_chmod(uv_pipe_t* handle, int mode) { if (r != 0) return r; + if (name_len == 0 && handle->pipe_fname != NULL) + name = handle->pipe_fname; + /* stat must be used as fstat has a bug on Darwin */ - if (uv__stat(name_buffer, &pipe_stat) == -1) + if (uv__stat(name, &pipe_stat) == -1) return UV__ERR(errno); desired_mode = 0; @@ -483,7 +487,7 @@ int uv_pipe_chmod(uv_pipe_t* handle, int mode) { pipe_stat.st_mode |= desired_mode; - r = chmod(name_buffer, pipe_stat.st_mode); + r = chmod(name, pipe_stat.st_mode); return r != -1 ? 0 : UV__ERR(errno); } -- Yuqian Yang <crup...@crupest.life>