about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libstore/remote-store.cc18
-rw-r--r--src/nix-worker/nix-worker.cc14
2 files changed, 26 insertions, 6 deletions
diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc
index 88a2fca8aedd..14412b8c8b60 100644
--- a/src/libstore/remote-store.cc
+++ b/src/libstore/remote-store.cc
@@ -137,14 +137,26 @@ void RemoteStore::connectToDaemon()
 
     string socketPath = nixStateDir + DEFAULT_SOCKET_PATH;
 
+    /* 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");
+    chdir(dirOf(socketPath).c_str()); 
+    Path socketPathRel = "./" + baseNameOf(socketPath);
+    
     struct sockaddr_un addr;
     addr.sun_family = AF_UNIX;
-    if (socketPath.size() >= sizeof(addr.sun_path))
-        throw Error(format("socket path `%1%' is too long") % socketPath);
-    strcpy(addr.sun_path, socketPath.c_str());
+    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 (connect(fdSocket, (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");
 }
 
 
diff --git a/src/nix-worker/nix-worker.cc b/src/nix-worker/nix-worker.cc
index 4aab03fcd685..d9b75270f843 100644
--- a/src/nix-worker/nix-worker.cc
+++ b/src/nix-worker/nix-worker.cc
@@ -542,11 +542,17 @@ static void daemonLoop()
 
     createDirs(dirOf(socketPath));
 
+    /* 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. */
+    chdir(dirOf(socketPath).c_str());
+    Path socketPathRel = "./" + baseNameOf(socketPath);
+    
     struct sockaddr_un addr;
     addr.sun_family = AF_UNIX;
-    if (socketPath.size() >= sizeof(addr.sun_path))
-        throw Error(format("socket path `%1%' is too long") % socketPath);
-    strcpy(addr.sun_path, socketPath.c_str());
+    if (socketPathRel.size() >= sizeof(addr.sun_path))
+        throw Error(format("socket path `%1%' is too long") % socketPathRel);
+    strcpy(addr.sun_path, socketPathRel.c_str());
 
     unlink(socketPath.c_str());
 
@@ -559,6 +565,8 @@ static void daemonLoop()
     if (res == -1)
         throw SysError(format("cannot bind to socket `%1%'") % socketPath);
 
+    chdir("/"); /* back to the root */
+
     if (listen(fdSocket, 5) == -1)
         throw SysError(format("cannot listen on socket `%1%'") % socketPath);