0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-25 23:14:13 +01:00

ircd::fs: Various reorg; cleanup.

This commit is contained in:
Jason Volk 2018-12-29 15:27:58 -08:00
parent 8f9912b766
commit 3466597981
9 changed files with 336 additions and 285 deletions

View file

@ -200,9 +200,6 @@ bool
startup_checks()
try
{
namespace fs = ircd::fs;
fs::chdir(fs::get(fs::PREFIX));
return true;
}
catch(const std::exception &e)

View file

@ -11,76 +11,27 @@
#pragma once
#define HAVE_IRCD_FS_H
/*
* Directory paths and filenames for UNIX systems.
* IRCD_PREFIX is set using ./configure --prefix, see INSTALL.
* Do not change these without corresponding changes in the build system.
*
* IRCD_PREFIX = prefix for all directories,
* DPATH = root directory of installation,
* BINPATH = directory for binary files,
* ETCPATH = directory for configuration files,
* LOGPATH = directory for logfiles,
* MODPATH = directory for modules,
* AUTOMODPATH = directory for autoloaded modules
*/
/// Tools for working with the local filesystem.
/// Local filesystem interface.
///
/// IRCd has wrapped operations for the local filesystem to maintain a
/// cross-platform implementation of asynchronous file IO in conjunction with
/// the ircd::ctx userspace context system. These operations will yield your
/// ircd::ctx when necessary to not block the event loop on the main thread
/// during IOs.
///
/// Paths are stored in the platform-specific format using plain old character
/// strings, which means you should never directly manipulate path strings to
/// maintain x-platformness; instead use the (or add more) tools provided by
/// this interface (see: path.h).
///
namespace ircd::fs
{
struct init;
enum index :int;
struct error; // custom exception; still inherits from ircd::error
constexpr size_t PATH_MAX { 2048 };
string_view get(index) noexcept;
string_view name(index) noexcept;
std::string make_path(const vector_view<const string_view> &);
std::string make_path(const vector_view<const std::string> &);
bool exists(const string_view &path);
bool is_dir(const string_view &path);
bool is_reg(const string_view &path);
size_t size(const string_view &path);
bool direct_io_support(const string_view &path);
std::vector<std::string> ls(const string_view &path);
std::vector<std::string> ls_recursive(const string_view &path);
bool rename(std::nothrow_t, const string_view &old, const string_view &new_);
void rename(const string_view &old, const string_view &new_);
bool remove(std::nothrow_t, const string_view &path);
bool remove(const string_view &path);
void chdir(const string_view &path);
bool mkdir(const string_view &path);
std::string cwd();
}
/// Index of default paths. Must be aligned with fs::syspaths (see: fs.cc)
enum ircd::fs::index
:int
{
PREFIX,
BIN,
CONF,
DATA,
DB,
LOG,
MODULES,
_NUM_
};
#include "error.h"
#include "path.h"
#include "iov.h"
#include "fd.h"
#include "aio.h"
@ -90,6 +41,25 @@ enum ircd::fs::index
#include "stdin.h"
#include "support.h"
namespace ircd::fs
{
// Observers
bool exists(const string_view &path);
bool is_dir(const string_view &path);
bool is_reg(const string_view &path);
size_t size(const string_view &path);
std::vector<std::string> ls(const string_view &path);
std::vector<std::string> ls_r(const string_view &path);
// Modifiers
bool rename(std::nothrow_t, const string_view &old, const string_view &new_);
bool rename(const string_view &old, const string_view &new_);
bool remove(std::nothrow_t, const string_view &path);
bool remove(const string_view &path);
bool mkdir(const string_view &path);
}
/// Filesystem interface init / fini held by ircd::main().
struct ircd::fs::init
{
aio::init _aio_;

57
include/ircd/fs/path.h Normal file
View file

@ -0,0 +1,57 @@
// Matrix Construct
//
// Copyright (C) Matrix Construct Developers, Authors & Contributors
// Copyright (C) 2016-2018 Jason Volk <jason@zemos.net>
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice is present in all copies. The
// full license for this software is available in the LICENSE file.
#pragma once
#define HAVE_IRCD_FS_PATH_H
namespace ircd::fs
{
enum base :uint;
struct basepath;
extern const size_t MAX_PATH_LEN;
extern const size_t MAX_PATH_DEPTH;
const basepath &get(const base &) noexcept;
string_view make_path(const base &) noexcept;
std::string make_path(const base &, const string_view &);
std::string make_path(const vector_view<const string_view> &);
std::string make_path(const vector_view<const std::string> &);
string_view cwd(const mutable_buffer &buf);
std::string cwd();
}
/// A compile-time installation base-path. We have several of these in an
/// internal array accessible with get(enum base) or make_path(enum base).
struct ircd::fs::basepath
{
string_view name;
string_view path;
};
/// Index of default paths. Must be aligned with the internal array in fs.cc.
/// Note that even though the PREFIX is accessible here, custom installations
/// may use entirely different paths for other components; most installations
/// use the package-target name as a path component.
enum ircd::fs::base
:uint
{
PREFIX, ///< Installation prefix (from ./configure --prefix)
BIN, ///< Binary directory (e.g. $prefix/bin)
CONF, ///< Configuration directory (e.g. $prefix/etc)
DATA, ///< Read-only data directory (e.g. $prefix/share)
DB, ///< Database directory (e.g. $prefix/var/db)
LOG, ///< Logfile directory (e.g. $prefix/var/log)
MODULES, ///< Modules directory (e.g. $prefix/lib/modules)
_NUM_
};

View file

@ -229,7 +229,7 @@ try
{
const auto dbdir
{
fs::get(fs::DB)
fs::make_path(fs::DB)
};
if(fs::mkdir(dbdir))
@ -290,17 +290,12 @@ catch(const std::exception &e)
std::string
ircd::db::direct_io_test_file_path()
{
const auto dbdir
static const auto &test_file_name
{
fs::get(fs::DB)
"SUPPORTS_DIRECT_IO"_sv
};
const std::string parts[]
{
dbdir, "SUPPORTS_DIRECT_IO"s
};
return fs::make_path(parts);
return fs::make_path(fs::DB, test_file_name);
}
decltype(ircd::db::compressions)
@ -3222,13 +3217,16 @@ ircd::db::database::sst::dump::dump(db::column column,
{
database::column &c(column);
const database &d(column);
std::string path
{
path_
};
std::string path{path_};
if(path.empty())
{
const string_view path_parts[]
{
fs::get(fs::DB), db::name(d), db::name(c)
fs::make_path(fs::DB), db::name(d), db::name(c)
};
path = fs::make_path(path_parts);
@ -11602,9 +11600,9 @@ ircd::db::error_to_status::error_to_status(const std::error_code &e)
std::vector<std::string>
ircd::db::available()
{
const auto prefix
const auto &prefix
{
fs::get(fs::DB)
fs::make_path(fs::DB)
};
const auto dirs
@ -11666,9 +11664,9 @@ std::string
ircd::db::path(const string_view &name,
const uint64_t &checkpoint)
{
const auto prefix
const auto &prefix
{
fs::get(fs::DB)
fs::make_path(fs::DB)
};
const string_view parts[]

View file

@ -20,17 +20,39 @@ namespace filesystem = boost::filesystem;
namespace ircd::fs
{
filesystem::path path(std::string);
filesystem::path path(const string_view &);
filesystem::path path(const vector_view<const string_view> &);
static filesystem::path path(std::string);
static filesystem::path path(const string_view &);
static filesystem::path path(const vector_view<const string_view> &);
static uint posix_flags(const std::ios::openmode &mode);
static const char *path_str(const string_view &);
static void debug_paths();
}
/// Default maximum path string length (for all filesystems & platforms).
decltype(ircd::fs::MAX_PATH_LEN)
ircd::fs::MAX_PATH_LEN
{
#ifdef PATH_MAX
PATH_MAX
#else
255
#endif
};
decltype(ircd::fs::MAX_PATH_DEPTH)
ircd::fs::MAX_PATH_DEPTH
{
32
};
//
// init
//
ircd::fs::init::init()
:_aio_{}
{
debug_paths();
}
ircd::fs::init::~init()
@ -38,83 +60,11 @@ noexcept
{
}
//
// Compile-time path index
//
namespace ircd::fs
{
struct sysent;
extern const std::array<struct sysent, num_of<index>()> syspaths;
}
struct ircd::fs::sysent
{
string_view name;
string_view path;
};
decltype(ircd::fs::syspaths)
ircd::fs::syspaths
{{
{ "installation prefix", RB_PREFIX },
{ "binary directory", RB_BIN_DIR },
{ "configuration directory", RB_CONF_DIR },
{ "data directory", RB_DATA_DIR },
{ "database directory", RB_DB_DIR },
{ "log directory", RB_LOG_DIR },
{ "module directory", RB_MODULE_DIR },
}};
ircd::string_view
ircd::fs::get(index index)
noexcept try
{
return syspaths.at(index).path;
}
catch(const std::out_of_range &e)
{
return {};
}
ircd::string_view
ircd::fs::name(index index)
noexcept try
{
return syspaths.at(index).name;
}
catch(const std::out_of_range &e)
{
return {};
}
///////////////////////////////////////////////////////////////////////////////
//
// fs.h / misc
//
std::string
ircd::fs::cwd()
try
{
return filesystem::current_path().string();
}
catch(const filesystem::filesystem_error &e)
{
throw error{e};
}
void
ircd::fs::chdir(const string_view &path)
try
{
filesystem::current_path(fs::path(path));
}
catch(const filesystem::filesystem_error &e)
{
throw error{e};
}
bool
ircd::fs::mkdir(const string_view &path)
try
@ -145,12 +95,13 @@ ircd::fs::remove(std::nothrow_t,
return filesystem::remove(fs::path(path), ec);
}
void
bool
ircd::fs::rename(const string_view &old,
const string_view &new_)
try
{
filesystem::rename(path(old), path(new_));
return true;
}
catch(const filesystem::filesystem_error &e)
{
@ -168,7 +119,7 @@ ircd::fs::rename(std::nothrow_t,
}
std::vector<std::string>
ircd::fs::ls_recursive(const string_view &path)
ircd::fs::ls_r(const string_view &path)
try
{
const filesystem::recursive_directory_iterator end;
@ -259,73 +210,6 @@ catch(const filesystem::filesystem_error &e)
throw error{e};
}
std::string
ircd::fs::make_path(const vector_view<const std::string> &list)
try
{
filesystem::path ret;
for(const auto &s : list)
ret /= path(s);
return ret.string();
}
catch(const filesystem::filesystem_error &e)
{
throw error{e};
}
std::string
ircd::fs::make_path(const vector_view<const string_view> &list)
try
{
filesystem::path ret;
for(const auto &s : list)
ret /= path(s);
return ret.string();
}
catch(const filesystem::filesystem_error &e)
{
throw error{e};
}
filesystem::path
ircd::fs::path(const vector_view<const string_view> &list)
try
{
filesystem::path ret;
for(const auto &s : list)
ret /= path(s);
return ret.string();
}
catch(const filesystem::filesystem_error &e)
{
throw error{e};
}
filesystem::path
ircd::fs::path(const string_view &s)
try
{
return path(std::string{s});
}
catch(const filesystem::filesystem_error &e)
{
throw error{e};
}
filesystem::path
ircd::fs::path(std::string s)
try
{
return filesystem::path(std::move(s));
}
catch(const filesystem::filesystem_error &e)
{
throw error{e};
}
///////////////////////////////////////////////////////////////////////////////
//
// fs/support.h
@ -1085,15 +969,6 @@ noexcept
//
// fs/fd.h
//
// TODO: x-platform
//
namespace ircd::fs
{
thread_local char path_buf[PATH_MAX];
static const char *path_str(const string_view &);
static uint posix_flags(const std::ios::openmode &mode);
}
decltype(ircd::fs::fd::opts::direct_io_enable)
ircd::fs::fd::opts::direct_io_enable
@ -1164,35 +1039,6 @@ ircd::fs::size(const fd &fd)
return end;
}
uint
ircd::fs::posix_flags(const std::ios::openmode &mode)
{
static const auto rdwr
{
std::ios::in | std::ios::out
};
uint ret{0};
if((mode & rdwr) == rdwr)
ret |= O_RDWR;
else if(mode & std::ios::out)
ret |= O_WRONLY;
else
ret |= O_RDONLY;
ret |= mode & std::ios::trunc? O_TRUNC : 0;
ret |= mode & std::ios::app? O_APPEND : 0;
ret |= ret & O_WRONLY? O_CREAT : 0;
ret |= ret & O_RDWR && ret & (O_TRUNC | O_APPEND)? O_CREAT : 0;
return ret;
}
const char *
ircd::fs::path_str(const string_view &s)
{
return data(strlcpy(path_buf, s));
}
//
// fd::opts
//
@ -1369,6 +1215,119 @@ ircd::fs::bytes(const const_iovec_view &iov)
});
}
///////////////////////////////////////////////////////////////////////////////
//
// fs/path.h
//
namespace ircd::fs
{
extern const std::array<basepath, num_of<base>()> basepaths;
}
decltype(ircd::fs::basepaths)
ircd::fs::basepaths
{{
{ "installation prefix", RB_PREFIX },
{ "binary directory", RB_BIN_DIR },
{ "configuration directory", RB_CONF_DIR },
{ "data directory", RB_DATA_DIR },
{ "database directory", RB_DB_DIR },
{ "log directory", RB_LOG_DIR },
{ "module directory", RB_MODULE_DIR },
}};
std::string
ircd::fs::cwd()
try
{
const auto &cur
{
filesystem::current_path()
};
return cur.string();
}
catch(const filesystem::filesystem_error &e)
{
throw error{e};
}
ircd::string_view
ircd::fs::cwd(const mutable_buffer &buf)
try
{
const auto &cur
{
filesystem::current_path()
};
return strlcpy(buf, cur.native());
}
catch(const filesystem::filesystem_error &e)
{
throw error{e};
}
std::string
ircd::fs::make_path(const vector_view<const std::string> &list)
try
{
filesystem::path ret;
for(const auto &s : list)
ret /= path(s);
return ret.string();
}
catch(const filesystem::filesystem_error &e)
{
throw error{e};
}
std::string
ircd::fs::make_path(const vector_view<const string_view> &list)
try
{
filesystem::path ret;
for(const auto &s : list)
ret /= path(s);
return ret.string();
}
catch(const filesystem::filesystem_error &e)
{
throw error{e};
}
std::string
ircd::fs::make_path(const base &base,
const string_view &rest)
try
{
filesystem::path ret;
ret /= make_path(base);
ret /= path(rest);
return ret.string();
}
catch(const filesystem::filesystem_error &e)
{
throw error{e};
}
ircd::string_view
ircd::fs::make_path(const base &base)
noexcept
{
return get(base).path;
}
const ircd::fs::basepath &
ircd::fs::get(const base &base)
noexcept
{
return basepaths.at(base);
}
///////////////////////////////////////////////////////////////////////////////
//
// fs/error.h
@ -1422,3 +1381,95 @@ const noexcept
{
return this->ircd::error::what();
}
///////////////////////////////////////////////////////////////////////////////
//
// Internal utils
//
void
ircd::fs::debug_paths()
{
thread_local char buf[MAX_PATH_LEN + 1];
log::debug
{
"Current working directory: `%s'", cwd(buf)
};
for_each<base>([](const base &base)
{
log::debug
{
"Working %s is `%s'",
get(base).name,
get(base).path,
};
});
}
const char *
ircd::fs::path_str(const string_view &s)
{
thread_local char buf[MAX_PATH_LEN + 1];
return data(strlcpy(buf, s));
}
uint
ircd::fs::posix_flags(const std::ios::openmode &mode)
{
static const auto rdwr
{
std::ios::in | std::ios::out
};
uint ret{0};
if((mode & rdwr) == rdwr)
ret |= O_RDWR;
else if(mode & std::ios::out)
ret |= O_WRONLY;
else
ret |= O_RDONLY;
ret |= mode & std::ios::trunc? O_TRUNC : 0;
ret |= mode & std::ios::app? O_APPEND : 0;
ret |= ret & O_WRONLY? O_CREAT : 0;
ret |= ret & O_RDWR && ret & (O_TRUNC | O_APPEND)? O_CREAT : 0;
return ret;
}
filesystem::path
ircd::fs::path(const vector_view<const string_view> &list)
try
{
filesystem::path ret;
for(const auto &s : list)
ret /= path(s);
return ret.string();
}
catch(const filesystem::filesystem_error &e)
{
throw error{e};
}
filesystem::path
ircd::fs::path(const string_view &s)
try
{
return path(std::string{s});
}
catch(const filesystem::filesystem_error &e)
{
throw error{e};
}
filesystem::path
ircd::fs::path(std::string s)
try
{
return filesystem::path(std::move(s));
}
catch(const filesystem::filesystem_error &e)
{
throw error{e};
}

View file

@ -26,7 +26,6 @@ namespace ircd::log
std::ostream &out_console{std::cout};
std::ostream &err_console{std::cerr};
static std::string dir_path();
static std::string file_path(const level &);
static void mkdir();
@ -62,9 +61,9 @@ ircd::log::fini()
void
ircd::log::mkdir()
{
const std::string dir
const auto &dir
{
dir_path()
fs::make_path(fs::LOG)
};
if(fs::exists(dir))
@ -141,28 +140,7 @@ catch(const std::exception &e)
std::string
ircd::log::file_path(const level &lev)
{
const std::string base
{
dir_path()
};
const string_view parts[]
{
base, reflect(lev)
};
return fs::make_path(parts);
}
std::string
ircd::log::dir_path()
{
const string_view parts[]
{
fs::get(fs::LOG)
};
return fs::make_path(parts);
return fs::make_path(fs::LOG, reflect(lev));
}
void

View file

@ -894,7 +894,7 @@ namespace ircd::mods
decltype(ircd::mods::modroot)
ircd::mods::modroot
{
std::string{ircd::fs::get(ircd::fs::MODULES)}
fs::make_path(fs::MODULES)
};
decltype(ircd::mods::paths)

View file

@ -3384,7 +3384,7 @@ console_cmd__db__list(opt &out, const string_view &line)
{
const auto name
{
replace(lstrip(lstrip(path, fs::get(fs::DB)), '/'), "/", ":")
replace(lstrip(lstrip(path, fs::make_path(fs::DB)), '/'), "/", ":")
};
const auto &d

View file

@ -72,7 +72,7 @@ init_files()
return;
}
for(const auto &file : fs::ls_recursive(path))
for(const auto &file : fs::ls_r(path))
{
const auto name(lstrip(file, path));
files.emplace(std::string(name), file);