9#include <framework/utilities/FileSystem.h>
11#include <framework/logging/Logger.h>
13#include <boost/algorithm/string.hpp>
30namespace fs = std::filesystem;
34 fs::path fullPath = fs::absolute(filename);
35 return fs::exists(fullPath);
40 fs::path fullPath = fs::absolute(filename);
41 fullPath.remove_filename();
42 return fs::exists(fullPath);
47 fs::path fullPath = fs::absolute(filename);
48 return (fs::exists(fullPath)) && (fs::is_regular_file(fullPath));
53 fs::path fullPath = fs::absolute(filename);
54 return (fs::exists(fullPath)) && (fs::is_directory(fullPath));
59 fs::path fullPath = fs::absolute(filename);
60 return (fs::exists(fullPath)) && (fs::is_symlink(fullPath));
65 if (!fullname) library =
"lib" + library +
".so";
67 B2DEBUG(100,
"Loading shared library " << library);
68 void* libPointer = dlopen(library.c_str(), RTLD_LAZY | RTLD_GLOBAL);
70 if (libPointer ==
nullptr) {
71 B2ERROR(
"Could not open shared library file (error in dlopen) : " << dlerror());
80 if (not
isFile(filename))
return "";
81 fs::path fullPath = fs::absolute(filename);
82 std::unique_ptr<TMD5> md5(TMD5::FileChecksum(fullPath.c_str()));
83 return md5->AsString();
89 if (not
isFile(filename))
return "";
90 fs::path fullPath = fs::absolute(filename);
91 FILE* fp = fopen(fullPath.c_str(),
"rb");
93 uLong i, sum = adler32(0, 0, 0);
95 Bytef* buf = (Bytef*) malloc(1024 * 1024 *
sizeof(Bytef));
100 while ((i = fread((
void*) buf, 1,
sizeof(buf), fp)) > 0) {
101 sum = adler32(sum, buf, i);
107 sprintf(hexdigest,
"%08lx", sum);
119 for (
auto dir : dirs) {
122 fs::path dir_path = dir;
123 if (fs::path(path).is_absolute())
127 fullpath = dir_path.string();
132 return fs::canonical(fullpath).string();
137 fullpath = fs::absolute(path).string();
142 return fs::canonical(fullpath).string();
147 B2ERROR(
"findFile(): Could not find file." <<
LogVar(
"path", path));
153 std::vector<std::string> dirs;
154 if (getenv(
"BELLE2_LOCAL_DIR")) {
155 dirs.emplace_back(getenv(
"BELLE2_LOCAL_DIR"));
157 if (getenv(
"BELLE2_RELEASE_DIR")) {
158 dirs.emplace_back(getenv(
"BELLE2_RELEASE_DIR"));
160 return findFile(path, dirs, silent);
165 std::vector<std::string> dirs;
166 std::string envVar =
"BELLE2_" + boost::to_upper_copy(dataType) +
"_DATA_DIR";
167 if (getenv(envVar.c_str())) {
168 dirs.emplace_back(getenv(envVar.c_str()));
170 std::string result =
findFile(path, dirs,
true);
171 if (result.empty() && !silent)
172 B2ERROR(
"findFile(): Could not find data file. You may want to use the 'b2install-data' tool to get the file."
173 <<
LogVar(
"path", path) <<
LogVar(
"data type", dataType));
180 const int mode = readonly ? O_RDONLY : O_RDWR;
181 m_file = open(fileName.c_str(), mode | O_CREAT, 0640);
186 if (m_file >= 0) close(m_file);
191 if (m_file < 0)
return false;
193 auto const maxtime = std::chrono::steady_clock::now() + std::chrono::seconds(timeout);
194 std::default_random_engine random;
195 std::uniform_int_distribution<int> uniform(1, 100);
203 memset(&fl,
'\0',
sizeof(fl));
204 fl.l_type = m_readOnly ? F_RDLCK : F_WRLCK;
206 fl.l_whence = SEEK_SET;
211 int lock = fcntl(m_file, F_SETLK, &fl);
214 else if (std::chrono::steady_clock::now() > maxtime)
216 if (errno != EAGAIN && errno != EACCES && errno != EINTR)
break;
217 usleep(uniform(random) * 1000);
219 if (!ignoreErrors) B2ERROR(
"Locking failed: " << strerror(errno));
225 char* temporaryFileName = strdup((std::filesystem::temp_directory_path() /
"basf2_XXXXXX").c_str());
226 int fileDescriptor = mkstemp(temporaryFileName);
227 if (fileDescriptor == -1) {
228 B2ERROR(
"Cannot create temporary file: " << strerror(errno));
229 free(temporaryFileName);
233 open(temporaryFileName, mode);
235 B2ERROR(
"Cannot open temporary file: " << strerror(errno));
237 free(temporaryFileName);
238 ::close(fileDescriptor);
244 fs::remove(m_filename);
int m_file
File descriptor of file to be locked.
Lock(const std::string &fileName, bool readonly=false)
Construct a Lock object for the given file.
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
static bool loadLibrary(std::string library, bool fullname=true)
Load a shared library.
static bool isSymLink(const std::string &filename)
Check if filename points to an existing symbolic link.
static bool fileDirExists(const std::string &filename)
Check if the dir containing the filename exists.
static bool isFile(const std::string &filename)
Check if filename points to an existing file.
static std::string findFile(const std::string &path, bool silent=false)
Search for given file or directory in local or central release directory, and return absolute path if...
static std::string calculateMD5(const std::string &filename)
Calculate the MD5 checksum of a given file.
static std::string calculateAdler32(const std::string &filename)
Calculate the Adler-32 checksum of a given file.
static bool isDir(const std::string &filename)
Check if filename points to an existing directory.
static bool fileExists(const std::string &filename)
Check if the file with given filename exists.
Class to store variables with their name which were sent to the logging service.
Abstract base class for different kinds of events.