Figure out the user's home directory if $HOME is not set
This commit is contained in:
		
							parent
							
								
									eba840c8a1
								
							
						
					
					
						commit
						465cb68244
					
				
					 8 changed files with 84 additions and 36 deletions
				
			
		|  | @ -16,8 +16,6 @@ | |||
|     <dict> | ||||
|       <key>NIX_SSL_CERT_FILE</key> | ||||
|       <string>/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt</string> | ||||
|       <key>XDG_CACHE_HOME</key> | ||||
|       <string>/root/.cache</string> | ||||
|     </dict> | ||||
|   </dict> | ||||
| </plist> | ||||
|  |  | |||
|  | @ -7,5 +7,3 @@ ConditionPathIsReadWrite=@localstatedir@/nix/daemon-socket | |||
| [Service] | ||||
| ExecStart=@@bindir@/nix-daemon nix-daemon --daemon | ||||
| KillMode=process | ||||
| Environment=XDG_CACHE_HOME=/root/.cache | ||||
| Environment=XDG_CONFIG_HOME=/root/.config | ||||
|  |  | |||
|  | @ -376,7 +376,7 @@ expr_simple | |||
|       $$ = stripIndentation(CUR_POS, data->symbols, *$2); | ||||
|   } | ||||
|   | PATH { $$ = new ExprPath(absPath($1, data->basePath)); } | ||||
|   | HPATH { $$ = new ExprPath(getEnv("HOME", "") + string{$1 + 1}); } | ||||
|   | HPATH { $$ = new ExprPath(getHome() + string{$1 + 1}); } | ||||
|   | SPATH { | ||||
|       string path($1 + 1, strlen($1) - 2); | ||||
|       $$ = new ExprApp(CUR_POS, | ||||
|  |  | |||
							
								
								
									
										48
									
								
								src/libutil/lazy.hh
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/libutil/lazy.hh
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,48 @@ | |||
| #include <exception> | ||||
| #include <functional> | ||||
| #include <mutex> | ||||
| 
 | ||||
| namespace nix { | ||||
| 
 | ||||
| /* A helper class for lazily-initialized variables.
 | ||||
| 
 | ||||
|      Lazy<T> var([]() { return value; }); | ||||
| 
 | ||||
|    declares a variable of type T that is initialized to 'value' (in a | ||||
|    thread-safe way) on first use, that is, when var() is first | ||||
|    called. If the initialiser code throws an exception, then all | ||||
|    subsequent calls to var() will rethrow that exception. */ | ||||
| template<typename T> | ||||
| class Lazy | ||||
| { | ||||
| 
 | ||||
|     typedef std::function<T()> Init; | ||||
| 
 | ||||
|     Init init; | ||||
| 
 | ||||
|     std::once_flag done; | ||||
| 
 | ||||
|     T value; | ||||
| 
 | ||||
|     std::exception_ptr ex; | ||||
| 
 | ||||
| public: | ||||
| 
 | ||||
|     Lazy(Init init) : init(init) | ||||
|     { } | ||||
| 
 | ||||
|     const T & operator () () | ||||
|     { | ||||
|         std::call_once(done, [&]() { | ||||
|             try { | ||||
|                 value = init(); | ||||
|             } catch (...) { | ||||
|                 ex = std::current_exception(); | ||||
|             } | ||||
|         }); | ||||
|         if (ex) std::rethrow_exception(ex); | ||||
|         return value; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| } | ||||
|  | @ -1,3 +1,4 @@ | |||
| #include "lazy.hh" | ||||
| #include "util.hh" | ||||
| #include "affinity.hh" | ||||
| #include "sync.hh" | ||||
|  | @ -13,10 +14,12 @@ | |||
| #include <thread> | ||||
| #include <future> | ||||
| 
 | ||||
| #include <sys/wait.h> | ||||
| #include <unistd.h> | ||||
| #include <fcntl.h> | ||||
| #include <limits.h> | ||||
| #include <pwd.h> | ||||
| #include <sys/types.h> | ||||
| #include <sys/wait.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| #ifdef __APPLE__ | ||||
| #include <sys/syscall.h> | ||||
|  | @ -417,14 +420,28 @@ Path createTempDir(const Path & tmpRoot, const Path & prefix, | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| static Lazy<Path> getHome2([]() { | ||||
|     Path homeDir = getEnv("HOME"); | ||||
|     if (homeDir.empty()) { | ||||
|         char buf[16384]; | ||||
|         struct passwd pwbuf; | ||||
|         struct passwd * pw; | ||||
|         if (getpwuid_r(getuid(), &pwbuf, buf, sizeof(buf), &pw) != 0 | ||||
|             || !pw || !pw->pw_dir || !pw->pw_dir[0]) | ||||
|             throw Error("cannot determine user's home directory"); | ||||
|         homeDir = pw->pw_dir; | ||||
|     } | ||||
|     return homeDir; | ||||
| }); | ||||
| 
 | ||||
| Path getHome() { return getHome2(); } | ||||
| 
 | ||||
| 
 | ||||
| Path getCacheDir() | ||||
| { | ||||
|     Path cacheDir = getEnv("XDG_CACHE_HOME"); | ||||
|     if (cacheDir.empty()) { | ||||
|         Path homeDir = getEnv("HOME"); | ||||
|         if (homeDir.empty()) throw Error("$XDG_CACHE_HOME and $HOME are not set"); | ||||
|         cacheDir = homeDir + "/.cache"; | ||||
|     } | ||||
|     if (cacheDir.empty()) | ||||
|         cacheDir = getHome() + "/.cache"; | ||||
|     return cacheDir; | ||||
| } | ||||
| 
 | ||||
|  | @ -432,11 +449,8 @@ Path getCacheDir() | |||
| Path getConfigDir() | ||||
| { | ||||
|     Path configDir = getEnv("XDG_CONFIG_HOME"); | ||||
|     if (configDir.empty()) { | ||||
|         Path homeDir = getEnv("HOME"); | ||||
|         if (homeDir.empty()) throw Error("$XDG_CONFIG_HOME and $HOME are not set"); | ||||
|         configDir = homeDir + "/.config"; | ||||
|     } | ||||
|     if (configDir.empty()) | ||||
|         configDir = getHome() + "/.config"; | ||||
|     return configDir; | ||||
| } | ||||
| 
 | ||||
|  | @ -444,11 +458,8 @@ Path getConfigDir() | |||
| Path getDataDir() | ||||
| { | ||||
|     Path dataDir = getEnv("XDG_DATA_HOME"); | ||||
|     if (dataDir.empty()) { | ||||
|         Path homeDir = getEnv("HOME"); | ||||
|         if (homeDir.empty()) throw Error("$XDG_DATA_HOME and $HOME are not set"); | ||||
|         dataDir = homeDir + "/.local/share"; | ||||
|     } | ||||
|     if (dataDir.empty()) | ||||
|         dataDir = getHome() + "/.local/share"; | ||||
|     return dataDir; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -110,6 +110,9 @@ void deletePath(const Path & path, unsigned long long & bytesFreed); | |||
| Path createTempDir(const Path & tmpRoot = "", const Path & prefix = "nix", | ||||
|     bool includePid = true, bool useGlobalCounter = true, mode_t mode = 0755); | ||||
| 
 | ||||
| /* Return $HOME or the user's home directory from /etc/passwd. */ | ||||
| Path getHome(); | ||||
| 
 | ||||
| /* Return $XDG_CACHE_HOME or $HOME/.cache. */ | ||||
| Path getCacheDir(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -169,9 +169,7 @@ int main(int argc, char ** argv) | |||
|         setenv("NIX_DOWNLOAD_CACHE", channelCache.c_str(), 1); | ||||
| 
 | ||||
|         // Figure out the name of the `.nix-channels' file to use
 | ||||
|         auto home = getEnv("HOME"); | ||||
|         if (home.empty()) | ||||
|             throw Error("$HOME not set"); | ||||
|         auto home = getHome(); | ||||
|         channelsList = home + "/.nix-channels"; | ||||
|         nixDefExpr = home + "/.nix-defexpr"; | ||||
| 
 | ||||
|  |  | |||
|  | @ -192,17 +192,9 @@ static void loadDerivations(EvalState & state, Path nixExprPath, | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| static Path getHomeDir() | ||||
| { | ||||
|     Path homeDir(getEnv("HOME", "")); | ||||
|     if (homeDir == "") throw Error("HOME environment variable not set"); | ||||
|     return homeDir; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static Path getDefNixExprPath() | ||||
| { | ||||
|     return getHomeDir() + "/.nix-defexpr"; | ||||
|     return getHome() + "/.nix-defexpr"; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -1188,7 +1180,7 @@ static void opSwitchProfile(Globals & globals, Strings opFlags, Strings opArgs) | |||
|         throw UsageError(format("exactly one argument expected")); | ||||
| 
 | ||||
|     Path profile = absPath(opArgs.front()); | ||||
|     Path profileLink = getHomeDir() + "/.nix-profile"; | ||||
|     Path profileLink = getHome() + "/.nix-profile"; | ||||
| 
 | ||||
|     switchLink(profileLink, profile); | ||||
| } | ||||
|  | @ -1413,7 +1405,7 @@ int main(int argc, char * * argv) | |||
|             globals.profile = getEnv("NIX_PROFILE", ""); | ||||
| 
 | ||||
|         if (globals.profile == "") { | ||||
|             Path profileLink = getHomeDir() + "/.nix-profile"; | ||||
|             Path profileLink = getHome() + "/.nix-profile"; | ||||
|             globals.profile = pathExists(profileLink) | ||||
|                 ? absPath(readLink(profileLink), dirOf(profileLink)) | ||||
|                 : canonPath(settings.nixStateDir + "/profiles/default"); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue