1 #include <msp/core/application.h>
2 #include <msp/core/environ.h>
3 #include <msp/core/except.h>
4 #include <msp/strings/utils.h>
27 /** Helper function to determine the location of the program's executable.
28 Caches the last result to cut down filesystem access with repeated calls. */
29 const Path &get_bin_dir(const string &argv0)
31 static string last_argv0;
34 if(!(argv0==last_argv0))
37 if(argv0.find(DIRSEP)==string::npos)
39 string path = getenv("PATH");
42 for(const string &d: split(path, ITEMSEP))
43 if(exists(Path(d)/argv0))
45 exe = realpath(Path(d)/argv0);
52 exe = realpath(argv0);
55 bin_dir = dirname(exe);
64 not_a_directory::not_a_directory(const Path &p):
65 runtime_error(p.str())
69 void mkpath(const Path &path, int mode)
72 for(const string &c: path)
76 if(p.size()==1 && p.is_absolute())
79 if(FS::Stat st = stat(p))
81 if(!st.is_directory())
82 throw not_a_directory(p);
90 void rmpath(const Path &path)
92 for(const string &f: list_files(path))
104 vector<string> list_files(const Path &path)
106 return list_filtered(path, string());
109 Path get_sys_conf_dir()
111 const char *argv0 = Application::get_argv0();
113 throw invalid_state("no startup command");
115 Path dir = get_bin_dir(argv0);
117 if(dir[-1]=="bin" || dir[-1]=="sbin")
128 Path get_sys_data_dir()
130 const char *argv0 = Application::get_argv0();
132 throw invalid_state("no startup command");
134 Path dir = get_bin_dir(argv0);
136 if(dir[-1]=="bin" || dir[-1]=="sbin")
137 return dir/".."/"share"/Application::get_name();
138 else if(dir[-1]=="MacOS")
139 return dir/".."/"Resources";
144 Path get_sys_lib_dir()
146 const char *argv0 = Application::get_argv0();
148 throw invalid_state("no startup command");
150 Path dir = get_bin_dir(argv0);
152 if(dir[-1]=="bin" || dir[-1]=="sbin")
153 return dir/".."/"lib"/Application::get_name();
158 Path path_lookup(const string &name, const vector<Path> &paths)
160 for(const Path &p: paths)
164 return realpath(full);
170 Path path_lookup(const string &name)
172 string path = getenv("PATH");
173 vector<string> dirs = split(path, ITEMSEP);
174 return path_lookup(name, vector<Path>(dirs.begin(), dirs.end()));