mknod() on macOS does not support creating sockets, so divert to call sequence socket(), bind() and chmod() respectively if S_IFSOCK was passed with mode argument.
Link: https://lore.kernel.org/qemu-devel/17933734.zYzKuhC07K@silver/ Signed-off-by: Christian Schoenebeck <qemu_...@crudebyte.com> Reviewed-by: Will Cohen <wwco...@gmail.com> Reviewed-by: Greg Kurz <gr...@kaod.org> --- hw/9pfs/9p-util-darwin.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/hw/9pfs/9p-util-darwin.c b/hw/9pfs/9p-util-darwin.c index e24d09763a..63797e60cd 100644 --- a/hw/9pfs/9p-util-darwin.c +++ b/hw/9pfs/9p-util-darwin.c @@ -74,6 +74,34 @@ int fsetxattrat_nofollow(int dirfd, const char *filename, const char *name, */ #if defined CONFIG_PTHREAD_FCHDIR_NP +static int create_socket_file_at_cwd(const char *filename, mode_t mode) { + int fd, err; + struct sockaddr_un addr = { + .sun_family = AF_UNIX + }; + + /* + * sun_path is only 104 bytes, explicit filename length check required + */ + if (sizeof(addr.sun_path) - 1 < strlen(filename) + 2) { + errno = ENAMETOOLONG; + return -1; + } + fd = socket(PF_UNIX, SOCK_DGRAM, 0); + if (fd == -1) { + return fd; + } + snprintf(addr.sun_path, sizeof(addr.sun_path), "./%s", filename); + err = bind(fd, (struct sockaddr *) &addr, sizeof(addr)); + if (err == -1) { + goto out; + } + err = chmod(addr.sun_path, mode); +out: + close_preserve_errno(fd); + return err; +} + int qemu_mknodat(int dirfd, const char *filename, mode_t mode, dev_t dev) { int preserved_errno, err; @@ -93,7 +121,11 @@ int qemu_mknodat(int dirfd, const char *filename, mode_t mode, dev_t dev) if (pthread_fchdir_np(dirfd) < 0) { return -1; } - err = mknod(filename, mode, dev); + if (S_ISSOCK(mode)) { + err = create_socket_file_at_cwd(filename, mode); + } else { + err = mknod(filename, mode, dev); + } preserved_errno = errno; /* Stop using the thread-local cwd */ pthread_fchdir_np(-1); -- 2.32.0 (Apple Git-132)