y2err("open failed path:" << base_path << " error:" << stringerror(errno));
throw IOErrorException();
}
+
+ struct stat stat;
+ fstat(dirfd, &stat);
+ if (!S_ISDIR(stat.st_mode))
+ {
+ y2err("not a directory path:" << base_path);
+ throw IOErrorException();
+ }
}
y2err("open failed path:" << dir.fullname(name) << " (" << stringerror(errno) << ")");
throw IOErrorException();
}
+
+ struct stat stat;
+ fstat(dirfd, &stat);
+ if (!S_ISDIR(stat.st_mode))
+ {
+ y2err("not a directory path:" << dir.fullname(name));
+ throw IOErrorException();
+ }
}
}
+ static bool
+ all_entries(unsigned char type, const char* name)
+ {
+ return true;
+ }
+
+
vector<string>
SDir::entries() const
+ {
+ return entries(all_entries);
+ }
+
+
+ vector<string>
+ SDir::entries(std::function<bool(unsigned char, const char* name)> pred) const
{
int fd = dup(dirfd);
if (fd == -1)
while (readdir_r(dp, ep, &epp) == 0 && epp != NULL)
{
- if (strcmp(ep->d_name, ".") != 0 && strcmp(ep->d_name, "..") != 0)
+ if (strcmp(ep->d_name, ".") != 0 && strcmp(ep->d_name, "..") != 0 &&
+ pred(ep->d_type, ep->d_name))
ret.push_back(ep->d_name);
}
}
+ int
+ SDir::open(const string& name, int flags, mode_t mode) const
+ {
+ return ::openat(dirfd, name.c_str(), flags, mode);
+ }
+
+
int
SDir::readlink(const string& name, string& buf) const
{
}
+ int
+ SDir::mktemp(string& name) const
+ {
+ static const char letters[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789";
+
+ static uint64_t value;
+
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ value += ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec;
+
+ unsigned int attempts = 62 * 62 * 62;
+
+ string::size_type length = name.size();
+
+ for (unsigned int count = 0; count < attempts; value += 7777, ++count)
+ {
+ uint64_t v = value;
+ for (string::size_type i = length - 6; i < length; ++i)
+ {
+ name[i] = letters[v % 62];
+ v /= 62;
+ }
+
+ int fd = open(name, O_RDWR | O_CREAT | O_EXCL);
+ if (fd >= 0)
+ return fd;
+ else if (errno != EEXIST)
+ return -1;
+ }
+
+ return -1;
+ }
+
+
SFile::SFile(const SDir& dir, const string& name)
: dir(dir), name(name)
{
#include <string>
#include <vector>
+#include <algorithm>
namespace snapper
string fullname(const string& name, bool with_base_path = true) const;
vector<string> entries() const;
+ vector<string> entries(std::function<bool(unsigned char type, const char* name)> pred) const;
int stat(const string& name, struct stat* buf, int flags) const;
int open(const string& name, int flags) const;
+ int open(const string& name, int flags, mode_t mode) const;
int readlink(const string& name, string& buf) const;
int mkdir(const string& name, mode_t mode) const;
int unlink(const string& name, int flags) const;
int chown(const string& name, uid_t owner, gid_t group, int flags) const;
int rename(const string& oldname, const string& newname) const;
+ int mktemp(string& name) const;
+
private:
const string base_path;