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.