Drop support for daemon socket path >= 108 characters
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.
This commit is contained in:
		
							parent
							
								
									056b3ecfa4
								
							
						
					
					
						commit
						c7d44bad00
					
				
					 1 changed files with 3 additions and 15 deletions
				
			
		|  | @ -61,27 +61,15 @@ ref<RemoteStore::Connection> RemoteStore::openConnection() | ||||||
| 
 | 
 | ||||||
|     string socketPath = settings.nixDaemonSocketFile; |     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; |     struct sockaddr_un addr; | ||||||
|     addr.sun_family = AF_UNIX; |     addr.sun_family = AF_UNIX; | ||||||
|     if (socketPathRel.size() >= sizeof(addr.sun_path)) |     if (socketPath.size() + 1 >= sizeof(addr.sun_path)) | ||||||
|         throw Error(format("socket path ‘%1%’ is too long") % socketPathRel); |         throw Error(format("socket path ‘%1%’ is too long") % socketPath); | ||||||
|     strcpy(addr.sun_path, socketPathRel.c_str()); |     strcpy(addr.sun_path, socketPath.c_str()); | ||||||
| 
 | 
 | ||||||
|     if (connect(conn->fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) |     if (connect(conn->fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) | ||||||
|         throw SysError(format("cannot connect to daemon at ‘%1%’") % socketPath); |         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->from.fd = conn->fd; | ||||||
|     conn->to.fd = conn->fd; |     conn->to.fd = conn->fd; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue