Page MenuHomec4science

filesystem.cpp
No OneTemporary

File Metadata

Created
Mon, May 13, 02:15

filesystem.cpp

/* =============================================================================
Copyright (c) 2014 - 2016
F. Georget <fabieng@princeton.edu> Princeton University
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
============================================================================= */
#include "filesystem.hpp"
#include <string.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/stat.h>
#include <stdexcept>
#include <limits.h>
#include <stdlib.h>
#include "specmicp_common/config.h"
#include "log.hpp"
static std::string test_name;
namespace specmicp {
namespace utils {
bool is_directory(const std::string& path)
{
struct stat info;
if (stat(path.c_str(), &info) == -1) {
return false;
}
if (S_ISDIR(info.st_mode)) {
return true;
}
return false;
}
bool is_file(const std::string& path)
{
struct stat info;
if (stat(path.c_str(), &info) == -1) {
return false;
}
if (S_ISREG(info.st_mode)) {
return true;
}
return false;
}
std::string get_current_directory()
{
char buf[PATH_MAX];
char* test = getcwd(buf, PATH_MAX);
if (test == NULL) {
ERROR << "Unable to obtain current working directory";
throw std::runtime_error("Something is wrong,"
"unable to obtain the current directory.");
}
return std::string(buf);
}
std::string complete_path(
const std::string& dir,
const std::string& file
)
{
std::string complete = dir;
if (dir.back() != '/') {
complete += '/';
}
complete += file;
return complete;
}
std::string relative_to_absolute(
const std::string& rel_path,
std::string& error
)
{
std::string abs_path = "";
char buf[PATH_MAX];
// call posix function
char* res = realpath(rel_path.c_str(), buf);
if (res == NULL) {
// parse error
if (errno == ENOENT) {
error = "No such file '" + rel_path +"'.";
} else if (errno == EACCES) {
error = "Read permission denied while searching for '"
+ rel_path +"'.";
} else if (errno == EIO) {
error = "I/O error while searching for '"
+ rel_path +"'.";
} else {
error = "Error while accessing '" + rel_path + "'.";
}
} else {
// no error, copy buffer
abs_path = buf;
}
return abs_path;
}
int name_filter(const struct dirent64* entry)
{
auto res = strncmp(entry->d_name, test_name.c_str(), 256);
if (res == 0) {
return 1;
}
return 0;
}
std::string find_path(
std::string filename,
const std::vector<std::string> &directories
)
{
// check if filename is a path
const auto has_sep = filename.find('/');
if (has_sep != std::string::npos) {
// already a path => we convert it to absolute
std::string error = "";
auto filepath = relative_to_absolute(filename, error);
if (filepath == "") {
ERROR << error;
return ""; // empty string is signal for error
}
return filepath;
}
// if not a path we try to find it
std::string complete_path_str = "";
test_name = filename.c_str();
for (auto dir: directories)
{
bool found = false;
struct dirent64** entry_list;
auto count = scandir64(dir.c_str(), &entry_list, name_filter, alphasort64);
if (count < 0) {
ERROR << "Problem while scanning directory : " << dir << ".";
throw std::runtime_error("Problem while scanning directory "
+ dir + ".");
}
if (count == 0) {
continue;
}
if (count > 1) {
WARNING << "More that one match for file '" << filename
<< "in : " << dir << ".";
}
for (auto ind=0; ind<count; ++ind) {
struct dirent64* entry;
entry = entry_list[0];
if (not found) {
complete_path_str = complete_path(dir, entry->d_name);
}
free(entry); // need to free everything
}
free(entry_list);
if (found) break;
}
return complete_path_str;
}
bool has_env(
const std::string& env_var
)
{
#ifdef SPECMICP_HAVE_SECURE_GETENV
char* env = secure_getenv(env_var.c_str());
#else
char* env = getenv(env_var.c_str());
#endif
if (env == NULL) {
return false;
}
return true;
}
std::string get_env(
const std::string& env_var
)
{
#ifdef SPECMICP_HAVE_SECURE_GETENV
char* env = secure_getenv(env_var.c_str());
#else
char* env = getenv(env_var.c_str());
#endif
if (env == NULL) {
return "";
}
else return env;
}
} // end namespace utils
} // end namespace specmicp

Event Timeline