9 static const char rcsid[] __attribute__((used)) =
"$Id: Path.cpp 1911 2017-09-02 17:37:35Z sella $";
12 #include "CommonMacro.h"
16 #include <sys/types.h>
17 #include <sys/statvfs.h>
24 using namespace sella::util;
26 std::vector<std::string>& Path::search(std::vector<std::string> &file,
const std::string &path,
const std::string ®ex)
throw (PathException) {
28 struct dirent ** listing;
30 int length = ::scandir(path.c_str(), &(listing), NULL, ::alphasort);
32 for (
int i = 0; i < length; i++) {
33 if (String::regex_match(listing[i]->d_name, regex)) {
34 ::snprintf(buffer,
sizeof(buffer),
"%s/%s", path.c_str(), listing[i]->d_name);
36 file.push_back(buffer);
45 std::string Path::create(
const std::vector<std::string> &path, mode_t mode, uid_t uid, gid_t gid)
throw (PathException) {
48 for (
auto iter = path.begin(); iter != path.end(); ++iter) {
49 if (root.empty() ==
false) {
55 return Path::create(root, mode, uid, gid);
58 std::string Path::create(
const std::string &path, mode_t mode, uid_t uid, gid_t gid)
throw (PathException) {
60 std::string root = path;
63 while (*(root.rbegin()) ==
'/') {
64 root.erase(root.length() - 1, 1);
68 DIR * directory = ::opendir(root.c_str());
71 if (directory == NULL) {
73 for (
auto iter = root.begin(), end = root.end(); iter != end; ++iter) {
75 partial = std::string(root.begin(), iter);
77 if (partial.length() > 0) {
78 if ((directory = ::opendir(partial.c_str())) == NULL) {
79 if (::mkdir(partial.c_str(), mode) != 0) {
80 if (errno != EEXIST) {
81 THROW(PathException,
"failed to create directory '%s': %s", partial.c_str(), ::strerror_r(errno, buffer,
sizeof(buffer)));
85 if (uid != (uid_t) -1 && gid != (gid_t) 0) {
86 if (::chown(partial.c_str(), uid, gid) != 0) {
87 THROW(PathException,
"failed to set owner on directory '%s': %s", partial.c_str(), ::strerror_r(errno, buffer,
sizeof(buffer)));
91 ::closedir(directory);
97 if ((directory = ::opendir(root.c_str())) == NULL) {
98 if (::mkdir(root.c_str(), mode) != 0) {
99 if (errno != EEXIST) {
100 THROW(PathException,
"failed to create directory '%s': %s", root.c_str(), ::strerror_r(errno, buffer,
sizeof(buffer)));
104 if (uid != (uid_t) -1 && gid != (gid_t) 0) {
105 if (::chown(root.c_str(), uid, gid) != 0) {
106 THROW(PathException,
"failed to set owner on directory '%s': %s", root.c_str(), ::strerror_r(errno, buffer,
sizeof(buffer)));
110 if ((directory = ::opendir(root.c_str())) == NULL) {
111 THROW(PathException,
"failed to open directory '%s' for writing: %s", root.c_str(), ::strerror_r(errno, buffer,
sizeof(buffer)));
116 ::closedir(directory);
121 void Path::unlink(
const std::string &path)
throw (PathException) {
125 if (::stat(path.c_str(), &(stats)) != 0) {
126 THROW(PathException,
"failed to unlink directory %s: %s", path.c_str(), ::strerror_r(errno, buffer,
sizeof(buffer)));
129 if (S_ISDIR(stats.st_mode)) {
130 struct dirent ** files = NULL;
131 int count = ::scandir(path.c_str(), &(files), NULL, ::versionsort);
133 for (
int i = 0; i < count; i++) {
135 Path::unlink(std::string(path).append(
"/").append(files[i]->d_name));
136 }
catch (PathException &e) {
137 for (
int j = i; j < count; j++) {
148 if (::unlink(path.c_str()) != 0) {
149 THROW(PathException,
"failed to unlink file %s: %s", path.c_str(), ::strerror_r(errno, buffer,
sizeof(buffer)));
154 uint64_t Path::getPartitionSize(
const std::string &path)
throw (PathException) {
158 if (statvfs(path.c_str(), &vfs) == -1) {
159 THROW(PathException,
"failed to get stats for directory '%s': %s", path.c_str(), ::strerror_r(errno, buffer,
sizeof(buffer)));
162 double total = ceil((
double) (vfs.f_blocks * vfs.f_frsize));
164 return (uint64_t) total;
167 uint64_t Path::getPartitionUsed(
const std::string &path)
throw (PathException) {
171 if (statvfs(path.c_str(), &vfs) == -1) {
172 THROW(PathException,
"failed to get stats for directory '%s': %s", path.c_str(), ::strerror_r(errno, buffer,
sizeof(buffer)));
175 double total = ceil((
double) (vfs.f_blocks * vfs.f_frsize));
176 double available = ceil((
double) (vfs.f_bfree * vfs.f_frsize));
177 double used = total - available;
179 return (uint64_t) used;
182 uint64_t Path::getPartitionFree(
const std::string &path)
throw (PathException) {
186 if (statvfs(path.c_str(), &vfs) == -1) {
187 THROW(PathException,
"failed to get stats for directory '%s': %s", path.c_str(), ::strerror_r(errno, buffer,
sizeof(buffer)));
190 double available = ceil((
double) (vfs.f_bfree * vfs.f_frsize));
192 return (uint64_t) available;
195 double Path::getPartitionFull(
const std::string &path)
throw (PathException) {
199 if (statvfs(path.c_str(), &vfs) == -1) {
200 THROW(PathException,
"failed to get stats for directory '%s': %s", path.c_str(), ::strerror_r(errno, buffer,
sizeof(buffer)));
203 double total = ceil((
double) (vfs.f_blocks * vfs.f_frsize));
204 double available = ceil((
double) (vfs.f_bfree * vfs.f_frsize));
205 double used = total - available;
206 double usedPercentage = ceil((
double) (used / total) * (
double) 100);
208 return usedPercentage;