4 #include <msp/core/application.h>
5 #include <msp/core/systemerror.h>
6 #include <msp/strings/regex.h>
7 #include <msp/strings/utils.h>
30 /** Helper function to determine the location of the program's executable.
31 Caches the last result to cut down filesystem access with repeated calls. */
32 const Path &get_bin_dir(const string &argv0)
34 static string last_argv0;
37 if(!(argv0==last_argv0))
40 if(argv0.find(DIRSEP)==string::npos)
41 if(const char *path = getenv("PATH"))
43 for(const string &d: split(path, ITEMSEP))
44 if(exists(Path(d)/argv0))
46 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 vector<string> list_filtered(const Path &path, const string &filter)
111 Regex r_filter(filter);
113 vector<string> result;
114 DIR *dir = opendir(path.str().c_str());
116 throw system_error("opendir");
118 while(dirent *de = readdir(dir))
120 const char *fn = de->d_name;
121 if(fn[0]=='.' && (fn[1]==0 || (fn[1]=='.' && fn[2]==0)))
123 if(r_filter.match(fn))
124 result.push_back(fn);
131 Path get_sys_conf_dir()
133 const char *argv0 = Application::get_argv0();
135 throw logic_error("no startup command");
137 Path dir = get_bin_dir(argv0);
139 if(dir[-1]=="bin" || dir[-1]=="sbin")
150 Path get_sys_data_dir()
152 const char *argv0 = Application::get_argv0();
154 throw logic_error("no startup command");
156 Path dir = get_bin_dir(argv0);
158 if(dir[-1]=="bin" || dir[-1]=="sbin")
159 return dir/".."/"share"/Application::get_name();
160 else if(dir[-1]=="MacOS")
161 return dir/".."/"Resources";
166 Path get_sys_lib_dir()
168 const char *argv0 = Application::get_argv0();
170 throw logic_error("no startup command");
172 Path dir = get_bin_dir(argv0);
174 if(dir[-1]=="bin" || dir[-1]=="sbin")
175 return dir/".."/"lib"/Application::get_name();
180 Path path_lookup(const string &name, const vector<Path> &paths)
182 for(const Path &p: paths)
186 return realpath(full);
192 Path path_lookup(const string &name)
194 const char *path = getenv("PATH");
195 vector<string> dirs = split(path, ITEMSEP);
196 return path_lookup(name, vector<Path>(dirs.begin(), dirs.end()));