8 #include <msp/core/except.h>
9 #include <msp/strings/regex.h>
10 #include <msp/strings/utils.h>
25 Helper function to determine the location of the program's executable. Caches
26 the last result to cut down filesystem access with repeated calls.
28 const Path &get_bin_dir(const string &argv0)
30 static string last_argv0;
33 if(!(argv0==last_argv0))
36 if(argv0.find('/')==string::npos)
38 const char *path = getenv("PATH");
39 vector<string> dirs = split(path, ':');
40 for(vector<string>::const_iterator i=dirs.begin(); i!=dirs.end(); ++i)
41 if(exists(Path(*i)/argv0))
43 exe = realpath(Path(*i)/argv0);
48 exe = realpath(argv0);
51 bin_dir = dirname(exe);
59 void mkdir(const Path &path, int mode)
63 // The win32 version of this function doesn't take the mode argument. Go figure.
65 err = ::mkdir(path.str().c_str());
67 err = ::mkdir(path.str().c_str(), mode);
71 throw SystemError("mkdir failed", errno);
74 void mkpath(const Path &path, int mode)
77 for(Path::Iterator i=path.begin(); i!=path.end(); ++i)
81 if(p.size()==1 && p.is_absolute())
85 int err = stat(p, st);
88 if(!S_ISDIR(st.st_mode))
89 throw Exception("A component exists and is not a directory");
92 else if(errno!=ENOENT)
93 throw SystemError("stat failed", errno);
99 void rmdir(const Path &path)
101 if(::rmdir(path.str().c_str())==-1)
102 throw SystemError("rmdir failed", errno);
105 void rmdirs(const Path &path)
107 list<string> files = list_files(path);
108 for(list<string>::iterator i=files.begin(); i!=files.end(); ++i)
111 struct stat st = stat(p.str().c_str());
112 if(S_ISDIR(st.st_mode))
121 list<string> list_files(const Path &path)
123 return list_filtered(path, string());
126 list<string> list_filtered(const Path &path, const string &filter)
128 Regex r_filter(filter);
131 DIR *dir = opendir(path.str().c_str());
134 while(dirent *de = readdir(dir))
136 const char *fn = de->d_name;
137 if(fn[0]=='.' && (fn[1]==0 || (fn[1]=='.' && fn[2]==0)))
139 if(r_filter.match(fn))
140 result.push_back(fn);
151 return ::getcwd(buf, sizeof(buf));
158 if(SHGetFolderPath(0, CSIDL_PERSONAL, 0, 0, home)==S_OK)
161 const char *home = getenv("HOME");
168 Path get_user_data_dir(const string &appname)
171 char datadir[MAX_PATH];
172 if(SHGetFolderPath(0, CSIDL_LOCAL_APPDATA, 0, 0, datadir)==S_OK)
173 return Path(datadir)/appname;
176 return get_home_dir()/("."+appname);
180 Path get_sys_conf_dir(const string &argv0)
182 Path dir = get_bin_dir(argv0);
184 if(dir[-1]=="bin" || dir[-1]=="sbin")
195 Path get_sys_data_dir(const string &argv0, const string &appname)
197 Path dir = get_bin_dir(argv0);
199 if(dir[-1]=="bin" || dir[-1]=="sbin")
200 return dir/".."/"share"/appname;
205 Path get_sys_lib_dir(const string &argv0, const string &appname)
207 Path dir = get_bin_dir(argv0);
209 if(dir[-1]=="bin" || dir[-1]=="sbin")
210 return dir/".."/"lib"/appname;
215 void chdir(const Path &path)
217 if(::chdir(path.str().c_str())==-1)
218 throw SystemError("chdir failed", errno);