initial matador ng commit
This commit is contained in:
@@ -0,0 +1,360 @@
|
||||
#include "matador/utils/os.hpp"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
#include <direct.h>
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
namespace matador::utils::os {
|
||||
|
||||
void setenv(const char *name, const char *value, override_env_value override_value)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
_putenv_s(name, value);
|
||||
#else
|
||||
::setenv(name, value, static_cast<int>(override_value));
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
std::string error_string(unsigned long error) {
|
||||
char* lpMsgBuf;
|
||||
auto bufLen = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
nullptr,
|
||||
error,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPTSTR) &lpMsgBuf,
|
||||
0,
|
||||
nullptr);
|
||||
std::string result;
|
||||
if (bufLen) {
|
||||
result.append(lpMsgBuf, lpMsgBuf+bufLen);
|
||||
LocalFree(lpMsgBuf);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string getenv(const char *name) {
|
||||
#ifdef _WIN32
|
||||
char var[1024];
|
||||
size_t len{};
|
||||
const auto error = getenv_s(&len, var, 1024, name);
|
||||
if (error > 0) {
|
||||
throw std::logic_error(error_string(error));
|
||||
};
|
||||
|
||||
return var;
|
||||
#else
|
||||
const char *path = ::getenv(name);
|
||||
return path == nullptr ? "" : path;
|
||||
#endif
|
||||
}
|
||||
|
||||
void unsetenv(const char *name)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
_putenv_s(name, nullptr);
|
||||
#else
|
||||
::unsetenv(name);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace matador::os {
|
||||
FILE* fopen(const std::string &path, const char *modes)
|
||||
{
|
||||
return fopen(path.c_str(), modes);
|
||||
}
|
||||
|
||||
FILE* fopen(const char *path, const char *modes)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return _fsopen(path, modes, _SH_DENYWR);
|
||||
#else
|
||||
return ::fopen(path, modes);
|
||||
#endif
|
||||
}
|
||||
|
||||
FILE* freopen(const std::string &path, const char *modes, FILE *stream)
|
||||
{
|
||||
return os::freopen(path.c_str(), modes, stream);
|
||||
}
|
||||
|
||||
FILE* freopen(const char *path, const char *modes, FILE *stream)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
FILE* redirected_stream;
|
||||
freopen_s(&redirected_stream, path, "w+", stream);
|
||||
return redirected_stream;
|
||||
#else
|
||||
return ::freopen(path, modes, stream);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool fclose(FILE *f)
|
||||
{
|
||||
return ::fclose(f) == 0;
|
||||
}
|
||||
|
||||
bool remove(const std::string &name)
|
||||
{
|
||||
return os::remove(name.c_str());
|
||||
}
|
||||
|
||||
bool remove(const char *name)
|
||||
{
|
||||
return ::remove(name) == 0;
|
||||
}
|
||||
|
||||
bool rename(const std::string &old_name, const std::string &new_name)
|
||||
{
|
||||
return os::rename(old_name.c_str(), new_name.c_str());
|
||||
}
|
||||
|
||||
bool rename(const char *old_name, const char *new_name)
|
||||
{
|
||||
return ::rename(old_name, new_name) == 0;
|
||||
}
|
||||
|
||||
bool access(const std::string &path, int mode)
|
||||
{
|
||||
return os::access(path.c_str(), mode);
|
||||
}
|
||||
|
||||
bool access(const char *path, int mode)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return _access(path, mode) == 0;
|
||||
#else
|
||||
return ::access(path, mode) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int dup(FILE *stream)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return _dup(_fileno(stream));
|
||||
#else
|
||||
return ::dup(fileno(stream));
|
||||
#endif
|
||||
}
|
||||
|
||||
bool mkdir(const std::string &dirname)
|
||||
{
|
||||
return os::mkdir(dirname.c_str());
|
||||
}
|
||||
|
||||
bool mkdir(const char *dirname)
|
||||
{
|
||||
if (dirname == nullptr || strlen(dirname) == 0) {
|
||||
return true;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
return ::_mkdir(dirname) == 0;
|
||||
#else
|
||||
return ::mkdir(dirname, S_IRWXU) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool chdir(const std::string &dirname)
|
||||
{
|
||||
return os::chdir(dirname.c_str());
|
||||
}
|
||||
|
||||
bool chdir(const char *dirname)
|
||||
{
|
||||
if (dirname == nullptr || strlen(dirname) == 0) {
|
||||
return true;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
return _chdir(dirname) == 0;
|
||||
#else
|
||||
return ::chdir(dirname) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool rmdir(const std::string &dirname)
|
||||
{
|
||||
return os::rmdir(dirname.c_str());
|
||||
}
|
||||
|
||||
bool rmdir(const char *dirname)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return _rmdir(dirname) == 0;
|
||||
#else
|
||||
return ::rmdir(dirname) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string get_current_dir()
|
||||
{
|
||||
char buffer[1024];
|
||||
#ifdef _WIN32
|
||||
char *dir = _getcwd(buffer, 1024);
|
||||
#else
|
||||
char *dir = ::getcwd(buffer, 1024);
|
||||
#endif
|
||||
if (dir == nullptr) {
|
||||
#ifdef _WIN32
|
||||
::strerror_s(buffer, 1024, errno);
|
||||
throw std::logic_error(buffer);
|
||||
#else
|
||||
throw std::logic_error(::strerror(errno));
|
||||
#endif
|
||||
}
|
||||
return std::string(buffer);
|
||||
}
|
||||
|
||||
bool mkpath(const std::string &path)
|
||||
{
|
||||
return os::mkpath(path.c_str());
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
char DIR_SEPARATOR = '\\';
|
||||
const char* DIR_SEPARATOR_STRING = "\\";
|
||||
#else
|
||||
char DIR_SEPARATOR = '/';
|
||||
const char* DIR_SEPARATOR_STRING = "/";
|
||||
#endif
|
||||
|
||||
bool mkpath(const char *path)
|
||||
{
|
||||
char tmp[256];
|
||||
char *p = nullptr;
|
||||
size_t len;
|
||||
|
||||
snprintf(tmp, sizeof(tmp),"%s",path);
|
||||
len = strlen(tmp);
|
||||
if (len == 0) {
|
||||
return true;
|
||||
}
|
||||
if(tmp[len - 1] == DIR_SEPARATOR) {
|
||||
tmp[len - 1] = 0;
|
||||
}
|
||||
for(p = tmp + 1; *p; p++) {
|
||||
if (*p == DIR_SEPARATOR) {
|
||||
*p = 0;
|
||||
if (!os::mkdir(tmp)) {
|
||||
return false;
|
||||
}
|
||||
*p = DIR_SEPARATOR;
|
||||
}
|
||||
}
|
||||
return os::mkdir(tmp);
|
||||
}
|
||||
|
||||
bool rmpath(const std::string &path)
|
||||
{
|
||||
return os::rmpath(path.c_str());
|
||||
}
|
||||
|
||||
bool rmpath(const char *path)
|
||||
{
|
||||
// change next to last path segment
|
||||
|
||||
std::vector<char> pathcopy(path, path+::strlen(path)+1);
|
||||
std::vector<std::string> segments;
|
||||
#ifdef _WIN32
|
||||
char *next_token = nullptr;
|
||||
char *segment = ::strtok_s(pathcopy.data(), DIR_SEPARATOR_STRING, &next_token);
|
||||
#else
|
||||
char *segment = ::strtok(pathcopy.data(), DIR_SEPARATOR_STRING);
|
||||
#endif
|
||||
|
||||
while (segment != nullptr) {
|
||||
os::chdir(segment);
|
||||
segments.emplace_back(segment);
|
||||
#ifdef _WIN32
|
||||
segment = ::strtok_s(nullptr, DIR_SEPARATOR_STRING, &next_token);
|
||||
#else
|
||||
segment = ::strtok(nullptr, DIR_SEPARATOR_STRING);
|
||||
#endif
|
||||
}
|
||||
|
||||
auto first = segments.rbegin();
|
||||
for (auto it=first; it!=segments.rend(); ++it) {
|
||||
os::chdir("..");
|
||||
os::rmdir(*it);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_readable(const std::string &path)
|
||||
{
|
||||
return is_readable(path.c_str());
|
||||
}
|
||||
|
||||
bool is_readable(const char *path)
|
||||
{
|
||||
return os::access(path, 2);
|
||||
}
|
||||
|
||||
bool is_writable(const std::string &path)
|
||||
{
|
||||
return is_writable(path.c_str());
|
||||
}
|
||||
|
||||
bool is_writable(const char *path)
|
||||
{
|
||||
return os::access(path, 4);
|
||||
}
|
||||
|
||||
bool exists(const std::string &path)
|
||||
{
|
||||
return exists(path.c_str());
|
||||
}
|
||||
|
||||
bool exists(const char *path)
|
||||
{
|
||||
return os::access(path, 0);
|
||||
}
|
||||
|
||||
size_t file_size(FILE *stream)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
int fd = _fileno(stream);
|
||||
return ::_filelength(fd);
|
||||
#else
|
||||
int fd = ::fileno(stream);
|
||||
struct stat buf{};
|
||||
::fstat(fd, &buf);
|
||||
return buf.st_size;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string build_path(const std::string &a, const std::string &b)
|
||||
{
|
||||
return a + DIR_SEPARATOR_STRING + b;
|
||||
}
|
||||
|
||||
char* strerror(int err, char* errbuf, size_t bufsize)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
::strerror_s(errbuf, bufsize, err);
|
||||
return errbuf;
|
||||
#else
|
||||
auto msg = ::strerror(err);
|
||||
auto s = strlen(msg);
|
||||
if (s < bufsize - 1) {
|
||||
return strcpy(errbuf, msg);
|
||||
} else {
|
||||
errbuf[bufsize - 1] = '\0';
|
||||
return strncpy(errbuf, msg, bufsize - 1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user