9 static const char rcsid[] __attribute__((used)) =
"$Id: File.cpp 1669 2016-04-09 20:07:12Z sella $";
12 #include "CommonMacro.h"
19 using namespace sella::util;
21 const std::string File::any =
"^.*";
22 const std::set<uint8_t> File::all = { DT_BLK, DT_CHR, DT_DIR, DT_FIFO, DT_LNK, DT_REG, DT_SOCK, DT_UNKNOWN };
23 const std::set<uint8_t> File::regular = { DT_LNK, DT_REG, DT_UNKNOWN };
24 const std::set<uint8_t> File::files = { DT_BLK, DT_CHR, DT_FIFO, DT_LNK, DT_REG, DT_SOCK, DT_UNKNOWN };
25 const std::set<uint8_t> File::dirs = { DT_DIR };
27 std::string File::getBaseName(
const std::string &fullpath)
throw () {
28 if (fullpath.empty()) {
32 return fullpath.substr(fullpath.rfind(
'/') + 1);
35 std::string File::getDirName(
const std::string &fullpath)
throw () {
36 if (fullpath.empty()) {
40 return fullpath.substr(0, fullpath.rfind(
'/'));
43 std::string File::getRealPath(
const std::string &fullpath)
throw (FileException) {
44 char realPath[PATH_MAX];
46 if (fullpath.empty()) {
50 if (::realpath(fullpath.c_str(), realPath) != NULL) {
51 return std::string(realPath);
54 THROW2(FileException,
"realpath()");
57 std::vector<std::string> File::getDirectory(
const std::string &path,
const std::string ®ex,
const std::set<uint8_t> &types)
throw (FileException) {
58 std::vector<std::string> results;
59 struct dirent entry, *result;
63 if ((dir = opendir(path.c_str())) == NULL) {
64 THROW(FileException,
"failed to open %s", path.c_str());
68 boost::regex re(regex);
71 if ((e = readdir_r(dir, &entry, &result)) != 0) {
74 THROW2(FileException,
"Failed to read directory %s", path.c_str());
81 if (types.count(result->d_type) > 0) {
82 if (String::regex_search(result->d_name, re)) {
83 results.push_back(result->d_name);
87 }
catch (RegexException &e) {
90 RETHROW(FileException, e);
98 std::string File::read(
const std::string &fullpath,
size_t limit, std::ios_base::openmode mode)
throw (FileException) {
99 std::ifstream file(fullpath, mode);
101 if (!file.is_open() || !file.good()) {
102 THROW(FileException,
"Failed to open file %s for reading", fullpath.c_str());
105 file.seekg(0, std::ios::end);
106 std::streamsize size = file.tellg();
107 file.seekg(0, std::ios::beg);
110 std::string buf((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
112 if (limit > 0 && buf.size() > limit) {
118 size_t len = (limit == 0 || (size_t) size < limit) ? size : limit;
119 std::string buf(len,
'\0');
121 if (!file.read((
char*) buf.data(), len)) {
122 THROW(FileException,
"Failed to read file %s", fullpath.c_str());
129 std::string File::readline(
const std::string &fullpath,
char delim, std::ios_base::openmode mode)
throw (FileException) {
130 std::ifstream file(fullpath, mode);
132 if (!file.is_open() || !file.good()) {
133 THROW(FileException,
"Failed to open file %s for reading", fullpath.c_str());
138 std::getline(file, buf, delim);
143 std::vector<std::string> File::readlines(
const std::string &fullpath,
size_t limit,
char delim, std::ios_base::openmode mode)
throw (FileException) {
144 std::ifstream file(fullpath, mode);
146 if (!file.is_open() || !file.good()) {
147 THROW(FileException,
"Failed to open file %s for reading", fullpath.c_str());
152 std::vector<std::string> lines;
154 lines.reserve((limit > 0) ? limit : 32);
157 while (std::getline(file, buf, delim)) {
158 lines.push_back(buf);
160 if (limit > 0 && ++count > limit) {
168 void File::write(
const std::string &fullpath,
const std::string &data, std::ios_base::openmode mode)
throw (FileException) {
169 std::ofstream file(fullpath, mode);
171 if (!file.is_open() || !file.good()) {
172 THROW(FileException,
"Failed to open file %s for writing", fullpath.c_str());
175 if (!file.write((
char*) data.data(), data.size())) {
176 THROW(FileException,
"Failed to write to file %s", fullpath.c_str());
180 bool File::exists(
const std::string &fullpath,
bool followSymlink)
throw () {
184 return (stat(fullpath.c_str(), &sb) == 0);
186 return (lstat(fullpath.c_str(), &sb) == 0);
190 bool File::isReadable(
const std::string &fullpath)
throw () {
191 std::ifstream file(fullpath);
193 if (!file.is_open() || !file.good()) {
200 bool File::isRegularFile(
const std::string &fullpath,
bool followSymlink)
throw (FileException) {
201 return S_ISREG(File::getMode(fullpath, followSymlink));
204 bool File::isDirectory(
const std::string &fullpath,
bool followSymlink)
throw (FileException) {
205 return S_ISDIR(File::getMode(fullpath, followSymlink));
208 bool File::isCharacterDevice(
const std::string &fullpath,
bool followSymlink)
throw (FileException) {
209 return S_ISCHR(File::getMode(fullpath, followSymlink));
212 bool File::isBlockDevice(
const std::string &fullpath,
bool followSymlink)
throw (FileException) {
213 return S_ISBLK(File::getMode(fullpath, followSymlink));
216 bool File::isFIFO(
const std::string &fullpath,
bool followSymlink)
throw (FileException) {
217 return S_ISFIFO(File::getMode(fullpath, followSymlink));
220 bool File::isSymLink(
const std::string &fullpath)
throw (FileException) {
221 return S_ISLNK(File::getMode(fullpath,
false));
224 bool File::isSocket(
const std::string &fullpath,
bool followSymlink)
throw (FileException) {
225 return S_ISSOCK(File::getMode(fullpath, followSymlink));
228 uid_t File::getUID(
const std::string &fullpath,
bool followSymlink)
throw (FileException) {
229 return File::getStat(fullpath, followSymlink).st_uid;
232 gid_t File::getGID(
const std::string &fullpath,
bool followSymlink)
throw (FileException) {
233 return File::getStat(fullpath, followSymlink).st_gid;
236 int64_t File::getSize(
const std::string &fullpath,
bool followSymlink)
throw (FileException) {
237 return (int64_t) File::getStat(fullpath, followSymlink).st_size;
240 int64_t File::getBlocks(
const std::string &fullpath,
bool followSymlink)
throw (FileException) {
241 return (int64_t) File::getStat(fullpath, followSymlink).st_blocks;
244 int64_t File::getBlockSize(
const std::string &fullpath,
bool followSymlink)
throw (FileException) {
245 return (int64_t) File::getStat(fullpath, followSymlink).st_blksize;
248 time_t File::getATime(
const std::string &fullpath,
bool followSymlink)
throw (FileException) {
249 return File::getStat(fullpath, followSymlink).st_atime;
252 time_t File::getMTime(
const std::string &fullpath,
bool followSymlink)
throw (FileException) {
253 return File::getStat(fullpath, followSymlink).st_mtime;
256 time_t File::getCTime(
const std::string &fullpath,
bool followSymlink)
throw (FileException) {
257 return File::getStat(fullpath, followSymlink).st_ctime;
260 struct stat
File::getStat(const std::string &fullpath, bool followSymlink) throw (FileException) {
264 if (stat(fullpath.c_str(), &sb) < 0) {
265 THROW2(FileException,
"stat()");
268 if (lstat(fullpath.c_str(), &sb)) {
269 THROW2(FileException,
"lstat()");
276 mode_t File::getMode(
const std::string &fullpath,
bool followSymlink)
throw (FileException) {
277 return File::getStat(fullpath, followSymlink).st_mode;
280 mode_t File::itomode(
int mode)
throw (FileException) {
289 if (mode >= 0 && mode <= 777) {
296 THROW2(FileException,
"invalid mode %d", mode);
299 if (oa > 7 || ga > 7 || ua > 7) {
300 THROW2(FileException,
"invalid mode %d", mode);
305 }
else if (ua == 6) {
306 uam = S_IRUSR | S_IWUSR;
307 }
else if (ua == 5) {
308 uam = S_IRUSR | S_IXUSR;
309 }
else if (ua == 4) {
311 }
else if (ua == 3) {
312 uam = S_IWUSR | S_IXUSR;
313 }
else if (ua == 2) {
315 }
else if (ua == 1) {
323 }
else if (ga == 6) {
324 gam = S_IRGRP | S_IWGRP;
325 }
else if (ga == 5) {
326 gam = S_IRGRP | S_IXGRP;
327 }
else if (ga == 4) {
329 }
else if (ga == 3) {
330 gam = S_IWGRP | S_IXGRP;
331 }
else if (ga == 2) {
333 }
else if (ga == 1) {
341 }
else if (oa == 6) {
342 oam = S_IROTH | S_IWOTH;
343 }
else if (oa == 5) {
344 oam = S_IROTH | S_IXOTH;
345 }
else if (oa == 4) {
347 }
else if (oa == 3) {
348 oam = S_IWOTH | S_IXOTH;
349 }
else if (oa == 2) {
351 }
else if (oa == 1) {
357 return (uam | gam | oam);