4 #include <msp/core/systemerror.h>
5 #include <msp/strings/regex.h>
6 #include <msp/strings/utils.h>
29 /** Helper function to determine the location of the program's executable.
30 Caches the last result to cut down filesystem access with repeated calls. */
31 const Path &get_bin_dir(const string &argv0)
33 static string last_argv0;
36 if(!(argv0==last_argv0))
39 if(argv0.find('/')==string::npos)
41 const char *path = getenv("PATH");
42 vector<string> dirs = split(path, ITEMSEP);
43 for(vector<string>::const_iterator i=dirs.begin(); i!=dirs.end(); ++i)
44 if(exists(Path(*i)/argv0))
46 exe = realpath(Path(*i)/argv0);
51 exe = realpath(argv0);
54 bin_dir = dirname(exe);
63 not_a_directory::not_a_directory(const Path &p):
64 runtime_error(p.str())
68 void mkpath(const Path &path, int mode)
71 for(Path::Iterator i=path.begin(); i!=path.end(); ++i)
75 if(p.size()==1 && p.is_absolute())
78 if(FS::Stat st = stat(p))
80 if(!st.is_directory())
81 throw not_a_directory(p);
89 void rmpath(const Path &path)
91 list<string> files = list_files(path);
92 for(list<string>::iterator i=files.begin(); i!=files.end(); ++i)
104 list<string> list_files(const Path &path)
106 return list_filtered(path, string());
109 list<string> list_filtered(const Path &path, const string &filter)
111 Regex r_filter(filter);
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);
134 return ::getcwd(buf, sizeof(buf));
137 Path get_sys_conf_dir(const string &argv0)
139 Path dir = get_bin_dir(argv0);
141 if(dir[-1]=="bin" || dir[-1]=="sbin")
152 Path get_sys_data_dir(const string &argv0, const string &appname)
154 Path dir = get_bin_dir(argv0);
156 if(dir[-1]=="bin" || dir[-1]=="sbin")
157 return dir/".."/"share"/appname;
158 else if(dir[-1]=="MacOS")
159 return dir/".."/"Resources";
164 Path get_sys_lib_dir(const string &argv0, const string &appname)
166 Path dir = get_bin_dir(argv0);
168 if(dir[-1]=="bin" || dir[-1]=="sbin")
169 return dir/".."/"lib"/appname;
174 void chdir(const Path &path)
176 if(::chdir(path.str().c_str())==-1)
177 throw system_error("chdir");