From c7d44bad000d5f431c05f6c27718d26d2b93bb0f Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 23 Mar 2016 17:16:16 +0100 Subject: [PATCH] Drop support for daemon socket path >= 108 characters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Doing a chdir() is a bad idea in multi-threaded programs, leading to failures such as error: cannot connect to daemon at ‘/nix/var/nix/daemon-socket/socket’: No such file or directory Since Linux doesn't have a connectat() syscall like FreeBSD, there is no way we can support this in a race-free way. --- src/libstore/remote-store.cc | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index 82b7cfd7c..6d6448ba7 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -61,27 +61,15 @@ ref RemoteStore::openConnection() string socketPath = settings.nixDaemonSocketFile; - /* Urgh, sockaddr_un allows path names of only 108 characters. So - chdir to the socket directory so that we can pass a relative - path name. !!! this is probably a bad idea in multi-threaded - applications... */ - AutoCloseFD fdPrevDir = open(".", O_RDONLY); - if (fdPrevDir == -1) throw SysError("couldn't open current directory"); - if (chdir(dirOf(socketPath).c_str()) == -1) throw SysError(format("couldn't change to directory of ‘%1%’") % socketPath); - Path socketPathRel = "./" + baseNameOf(socketPath); - struct sockaddr_un addr; addr.sun_family = AF_UNIX; - if (socketPathRel.size() >= sizeof(addr.sun_path)) - throw Error(format("socket path ‘%1%’ is too long") % socketPathRel); - strcpy(addr.sun_path, socketPathRel.c_str()); + if (socketPath.size() + 1 >= sizeof(addr.sun_path)) + throw Error(format("socket path ‘%1%’ is too long") % socketPath); + strcpy(addr.sun_path, socketPath.c_str()); if (connect(conn->fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) throw SysError(format("cannot connect to daemon at ‘%1%’") % socketPath); - if (fchdir(fdPrevDir) == -1) - throw SysError("couldn't change back to previous directory"); - conn->from.fd = conn->fd; conn->to.fd = conn->fd;