On Fri Jun 2 01:21:42 2023 +0000, Chip Davis wrote:
Not all systems fail that way when `open(2)`ing a local-domain socket file. According to [POSIX](https://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html), the `errno` is supposed to be `EOPNOTSUPP` in that case; in this regard, the Linux behavior is nonstandard. Some implementations may actually let you `open(2)` a socket file under certain circumstances.
Interesting. FreeBSD 13.2 does indeed set `errno` to `EOPNOTSUPP`, despite [its docs](https://man.freebsd.org/cgi/man.cgi?sektion=2&query=open) stating that support for that flow has not been implemented.
[OpenBSD's docs](https://man.openbsd.org/open.2) state the same thing, but [its source](https://github.com/openbsd/src/blob/0d280c5f69f6ef21f5dca2b37e738de752505c51...) indicates it also correctly throws `EOPNOTSUPP` (though I have not actually checked an OpenBSD system). The situation is the same for NetBSD ([docs](https://man.netbsd.org/open.2), [source](https://github.com/NetBSD/src/blob/e8715cd14bb24b536fd91daabd78aeec6c862996/...), untested).
Checking `EOPNOTSUPP` in addition to `ENXIO` should suffice, as we do stat the file to make sure it is indeed a socket, and *BSD supports this use of stat.
If a system exists where `open(2)` on a socket file succeeds, then the correct flow will occur, so this case does not need specific handling unless other non-POSIX behavior would be present (say, with `unlink(2)`).
I do not have a macOS system to test on. If someone could confirm (in)correct behavior of `open(2)` on macOS, I would very much appreciate it. The following program prints the behavior of `open(2)` when called on a socket file (though I do not know if it compiles as-is on macOS).
```c #include <errno.h> #include <fcntl.h> #include <stdio.h> #include <string.h> #include <sys/socket.h> #include <sys/un.h> #include <unistd.h>
int main(void) { struct sockaddr_un const addr = { AF_UNIX, "test.sock" }; int sock = socket(AF_UNIX, SOCK_STREAM, 0); if (bind(sock, (struct sockaddr *)&addr, sizeof(addr))) { printf("Failed to bind to path "%s": %s\n", addr.sun_path, strerror(errno)); return 1; } close(sock); open(addr.sun_path, O_RDONLY); printf("open(2) on socket file: %d ("%s")\n", errno, strerror(errno)); unlink(addr.sun_path); } ```