3 This file is part of libmspfs
4 Copyright © 2006-2008 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
15 #include <msp/core/except.h>
16 #include <msp/strings/regex.h>
17 #include <msp/strings/utils.h>
32 Helper function to determine the location of the program's executable. Caches
33 the last result to cut down filesystem access with repeated calls.
35 const Path &get_bin_dir(const Path &argv0)
37 static Path last_argv0;
40 if(!(argv0==last_argv0))
45 const char *path=getenv("PATH");
46 vector<string> dirs=split(path, ':');
47 for(vector<string>::const_iterator i=dirs.begin(); i!=dirs.end(); ++i)
48 if(exists(Path(*i)/argv0))
50 exe=realpath(Path(*i)/argv0);
66 void mkdir(const Path &path, int mode)
70 // The win32 version of this function doesn't take the mode argument. Go figure.
72 err=::mkdir(path.str().c_str());
74 err=::mkdir(path.str().c_str(), mode);
78 throw SystemError("mkdir failed", errno);
81 void mkpath(const Path &path, int mode)
84 for(Path::Iterator i=path.begin(); i!=path.end(); ++i)
88 if(p.size()==1 && p.is_absolute())
95 if(!S_ISDIR(st.st_mode))
96 throw Exception("A component exists and is not a directory");
99 else if(errno!=ENOENT)
100 throw SystemError("stat failed", errno);
106 void rmdir(const Path &path)
108 if(::rmdir(path.str().c_str())==-1)
109 throw SystemError("rmdir failed", errno);
112 void rmdirs(const Path &path)
114 list<string> files=list_files(path);
115 for(list<string>::iterator i=files.begin(); i!=files.end(); ++i)
118 struct stat st=stat(p.str().c_str());
119 if(S_ISDIR(st.st_mode))
128 list<string> list_files(const Path &path)
130 return list_filtered(path, string());
133 list<string> list_filtered(const Path &path, const string &filter)
135 Regex r_filter(filter);
138 DIR *dir=opendir(path.str().c_str());
141 while(dirent *de=readdir(dir))
143 const char *fn=de->d_name;
144 if(fn[0]=='.' && (fn[1]==0 || (fn[1]=='.' && fn[2]==0)))
146 if(r_filter.match(fn))
147 result.push_back(fn);
158 return ::getcwd(buf, sizeof(buf));
165 if(SHGetFolderPath(0, CSIDL_PERSONAL, 0, 0, home)==S_OK)
168 const char *home=getenv("HOME");
175 Path get_user_data_dir(const string &appname)
178 char datadir[MAX_PATH];
179 if(SHGetFolderPath(0, CSIDL_LOCAL_APPDATA, 0, 0, datadir)==S_OK)
180 return Path(datadir)/appname;
183 return get_home_dir()/("."+appname);
187 Path get_sys_conf_dir(const Path &argv0)
189 Path dir=get_bin_dir(argv0);
191 if(dir[-1]=="bin" || dir[-1]=="sbin")
202 Path get_sys_data_dir(const Path &argv0, const string &appname)
204 Path dir=get_bin_dir(argv0);
206 if(dir[-1]=="bin" || dir[-1]=="sbin")
207 return dir/".."/"share"/appname;
212 void chdir(const Path &path)
214 if(::chdir(path.str().c_str())==-1)
215 throw SystemError("chdir failed", errno);