9 #include <framework/utilities/FileSystem.h>
11 #include <framework/logging/Logger.h>
13 #include <boost/filesystem.hpp>
14 #include <boost/algorithm/string.hpp>
29 namespace fs = boost::filesystem;
31 bool FileSystem::fileExists(
const string& filename)
33 fs::path fullPath = fs::absolute(filename);
34 return fs::exists(fullPath);
37 bool FileSystem::fileDirExists(
const string& filename)
39 fs::path fullPath = fs::absolute(filename);
40 fullPath.remove_filename();
41 return fs::exists(fullPath);
44 bool FileSystem::isFile(
const string& filename)
46 fs::path fullPath = fs::absolute(filename);
47 return (fs::exists(fullPath)) && (fs::is_regular_file(fullPath));
50 bool FileSystem::isDir(
const string& filename)
52 fs::path fullPath = fs::absolute(filename);
53 return (fs::exists(fullPath)) && (fs::is_directory(fullPath));
56 bool FileSystem::isSymLink(
const string& filename)
58 fs::path fullPath = fs::absolute(filename);
59 return (fs::exists(fullPath)) && (fs::is_symlink(fullPath));
62 bool FileSystem::loadLibrary(std::string library,
bool fullname)
64 if (!fullname) library =
"lib" + library +
".so";
66 B2DEBUG(100,
"Loading shared library " << library);
67 void* libPointer = dlopen(library.c_str() , RTLD_LAZY | RTLD_GLOBAL);
69 if (libPointer ==
nullptr) {
70 B2ERROR(
"Could not open shared library file (error in dlopen) : " << dlerror());
77 std::string FileSystem::calculateMD5(
const std::string& filename)
79 if (not isFile(filename))
return "";
80 fs::path fullPath = fs::absolute(filename);
81 std::unique_ptr<TMD5> md5(TMD5::FileChecksum(fullPath.c_str()));
82 return md5->AsString();
85 std::string FileSystem::calculateAdler32(
const std::string& filename)
88 if (not isFile(filename))
return "";
89 fs::path fullPath = fs::absolute(filename);
90 FILE* fp = fopen(fullPath.c_str(),
"rb");
92 uLong i, sum = adler32(0, 0, 0);
94 Bytef* buf = (Bytef*) malloc(1024 * 1024 *
sizeof(Bytef));
99 while ((i = fread((
void*) buf, 1,
sizeof(buf), fp)) > 0) {
100 sum = adler32(sum, buf, i);
106 sprintf(hexdigest,
"%08lx", sum);
114 std::string FileSystem::findFile(
const string& path,
const std::vector<std::string>& dirs,
bool silent)
118 for (
auto dir : dirs) {
121 fullpath = (fs::path(dir) / path).
string();
122 if (fileExists(fullpath)) {
123 if (isSymLink(fullpath) or isSymLink(dir))
126 return fs::canonical(fullpath).string();
131 fullpath = fs::absolute(path).string();
132 if (fileExists(fullpath)) {
133 if (isSymLink(fullpath))
136 return fs::canonical(fullpath).string();
141 B2ERROR(
"findFile(): Could not find file." <<
LogVar(
"path", path));
145 std::string FileSystem::findFile(
const string& path,
bool silent)
147 std::vector<std::string> dirs;
148 if (getenv(
"BELLE2_LOCAL_DIR")) {
149 dirs.emplace_back(getenv(
"BELLE2_LOCAL_DIR"));
151 if (getenv(
"BELLE2_RELEASE_DIR")) {
152 dirs.emplace_back(getenv(
"BELLE2_RELEASE_DIR"));
154 return findFile(path, dirs, silent);
157 std::string FileSystem::findFile(
const string& path,
const std::string& dataType,
bool silent)
159 std::vector<std::string> dirs;
160 std::string envVar =
"BELLE2_" + boost::to_upper_copy(dataType) +
"_DATA_DIR";
161 if (getenv(envVar.c_str())) {
162 dirs.emplace_back(getenv(envVar.c_str()));
164 std::string result = findFile(path, dirs,
true);
165 if (result.empty() && !silent)
166 B2ERROR(
"findFile(): Could not find data file. You may want to use the 'b2install-data' tool to get the file."
167 <<
LogVar(
"path", path) <<
LogVar(
"data type", dataType));
171 FileSystem::Lock::Lock(
const std::string& fileName,
bool readonly) :
174 const int mode = readonly ? O_RDONLY : O_RDWR;
175 m_file = open(fileName.c_str(), mode | O_CREAT, 0640);
180 if (m_file >= 0) close(m_file);
185 if (m_file < 0)
return false;
187 auto const maxtime = std::chrono::steady_clock::now() + std::chrono::seconds(timeout);
188 std::default_random_engine random;
189 std::uniform_int_distribution<int> uniform(1, 100);
197 memset(&fl,
'\0',
sizeof(fl));
198 fl.l_type = m_readOnly ? F_RDLCK : F_WRLCK;
200 fl.l_whence = SEEK_SET;
205 int lock = fcntl(m_file, F_SETLK, &fl);
208 else if (std::chrono::steady_clock::now() > maxtime)
210 if (errno != EAGAIN && errno != EACCES && errno != EINTR)
break;
211 usleep(uniform(random) * 1000);
213 if (!ignoreErrors) B2ERROR(
"Locking failed: " << strerror(errno));
219 fs::path filename = fs::temp_directory_path() / fs::unique_path();
223 B2ERROR(
"Cannot create temporary file: " << strerror(errno));
230 fs::remove(m_filename);
int m_file
File descriptor of file to be locked.
bool lock(int timeout=300, bool ignoreErrors=false)
Try to lock the file.
~TemporaryFile()
close file and delete on destruction
std::string m_filename
filename of the temporary file
TemporaryFile(std::ios_base::openmode mode=std::ios_base::trunc|std::ios_base::out)
construct a new temporary file
Class to store variables with their name which were sent to the logging service.
Abstract base class for different kinds of events.