11 #include <framework/utilities/FileSystem.h>
13 #include <framework/logging/Logger.h>
15 #include <boost/filesystem.hpp>
16 #include <boost/algorithm/string.hpp>
31 namespace fs = boost::filesystem;
33 bool FileSystem::fileExists(
const string& filename)
35 fs::path fullPath = fs::absolute(filename);
36 return fs::exists(fullPath);
39 bool FileSystem::fileDirExists(
const string& filename)
41 fs::path fullPath = fs::absolute(filename);
42 fullPath.remove_filename();
43 return fs::exists(fullPath);
46 bool FileSystem::isFile(
const string& filename)
48 fs::path fullPath = fs::absolute(filename);
49 return (fs::exists(fullPath)) && (fs::is_regular_file(fullPath));
52 bool FileSystem::isDir(
const string& filename)
54 fs::path fullPath = fs::absolute(filename);
55 return (fs::exists(fullPath)) && (fs::is_directory(fullPath));
58 bool FileSystem::isSymLink(
const string& filename)
60 fs::path fullPath = fs::absolute(filename);
61 return (fs::exists(fullPath)) && (fs::is_symlink(fullPath));
64 bool FileSystem::loadLibrary(std::string library,
bool fullname)
66 if (!fullname) library =
"lib" + library +
".so";
68 B2DEBUG(100,
"Loading shared library " << library);
69 void* libPointer = dlopen(library.c_str() , RTLD_LAZY | RTLD_GLOBAL);
71 if (libPointer ==
nullptr) {
72 B2ERROR(
"Could not open shared library file (error in dlopen) : " << dlerror());
79 std::string FileSystem::calculateMD5(
const std::string& filename)
81 if (not isFile(filename))
return "";
82 fs::path fullPath = fs::absolute(filename);
83 std::unique_ptr<TMD5> md5(TMD5::FileChecksum(fullPath.c_str()));
84 return md5->AsString();
87 std::string FileSystem::calculateAdler32(
const std::string& filename)
90 if (not isFile(filename))
return "";
91 fs::path fullPath = fs::absolute(filename);
92 FILE* fp = fopen(fullPath.c_str(),
"rb");
94 uLong i, sum = adler32(0, 0, 0);
96 Bytef* buf = (Bytef*) malloc(1024 * 1024 *
sizeof(Bytef));
101 while ((i = fread((
void*) buf, 1,
sizeof(buf), fp)) > 0) {
102 sum = adler32(sum, buf, i);
108 sprintf(hexdigest,
"%08lx", sum);
116 std::string FileSystem::findFile(
const string& path,
const std::vector<std::string>& dirs,
bool silent)
120 for (
auto dir : dirs) {
123 fullpath = (fs::path(dir) / path).
string();
124 if (fileExists(fullpath)) {
125 if (isSymLink(fullpath) or isSymLink(dir))
128 return fs::canonical(fullpath).string();
133 fullpath = fs::absolute(path).string();
134 if (fileExists(fullpath)) {
135 if (isSymLink(fullpath))
138 return fs::canonical(fullpath).string();
143 B2ERROR(
"findFile(): Could not find file." <<
LogVar(
"path", path));
147 std::string FileSystem::findFile(
const string& path,
bool silent)
149 std::vector<std::string> dirs;
150 if (getenv(
"BELLE2_LOCAL_DIR")) {
151 dirs.emplace_back(getenv(
"BELLE2_LOCAL_DIR"));
153 if (getenv(
"BELLE2_RELEASE_DIR")) {
154 dirs.emplace_back(getenv(
"BELLE2_RELEASE_DIR"));
156 return findFile(path, dirs, silent);
159 std::string FileSystem::findFile(
const string& path,
const std::string& dataType,
bool silent)
161 std::vector<std::string> dirs;
162 std::string envVar =
"BELLE2_" + boost::to_upper_copy(dataType) +
"_DATA_DIR";
163 if (getenv(envVar.c_str())) {
164 dirs.emplace_back(getenv(envVar.c_str()));
166 std::string dirName = boost::to_lower_copy(dataType) +
"-data";
167 if (getenv(
"VO_BELL2_SW_DIR")) {
168 dirs.push_back((fs::path(getenv(
"VO_BELL2_SW_DIR")) / dirName).
string());
170 dirs.push_back(dirName);
171 std::string result = findFile(path, dirs,
true);
172 if (result.empty() && !silent)
173 B2ERROR(
"findFile(): Could not find data file. You may want to use the 'b2install-data' tool to get the file."
174 <<
LogVar(
"path", path) <<
LogVar(
"data type", dataType));
178 FileSystem::Lock::Lock(
const std::string& fileName,
bool readonly) :
181 const int mode = readonly ? O_RDONLY : O_RDWR;
182 m_file = open(fileName.c_str(), mode | O_CREAT, 0640);
187 if (m_file >= 0) close(m_file);
192 if (m_file < 0)
return false;
194 auto const maxtime = std::chrono::steady_clock::now() + std::chrono::seconds(timeout);
195 std::default_random_engine random;
196 std::uniform_int_distribution<int> uniform(1, 100);
204 memset(&fl,
'\0',
sizeof(fl));
205 fl.l_type = m_readOnly ? F_RDLCK : F_WRLCK;
207 fl.l_whence = SEEK_SET;
212 int lock = fcntl(m_file, F_SETLK, &fl);
215 else if (std::chrono::steady_clock::now() > maxtime)
217 if (errno != EAGAIN && errno != EACCES && errno != EINTR)
break;
218 usleep(uniform(random) * 1000);
220 if (!ignoreErrors) B2ERROR(
"Locking failed: " << strerror(errno));
226 fs::path filename = fs::temp_directory_path() / fs::unique_path();
230 B2ERROR(
"Cannot create temporary file: " << strerror(errno));
237 fs::remove(m_filename);