10#include <boost/config.hpp>
11#include <boost/filesystem.hpp>
20 #include <sys/types.h>
23# ifdef FC_HAS_SIMPLE_FILE_LOCK
34 std::string utf8_string;
36 variant_output = utf8_string;
45 std::wstring wide_string;
47 path_output =
path(wide_string);
51 char path::separator_char =
static_cast<char>(boost::filesystem::path(
"/").make_preferred().native()[0]);
77 *_p = fc::move( *
p._p );
95 path::operator boost::filesystem::path& () {
98 path::operator
const boost::filesystem::path& ()
const {
102 return _p->generic_string();
107 return boost::filesystem::path(*_p).make_preferred().string();
112 return _p->wstring();
117 return _p->generic_wstring();
122 return boost::filesystem::path(*_p).make_preferred().wstring();
130 const size_t maxPath = 32*1024;
131 std::vector<wchar_t> short_path;
132 short_path.resize(maxPath + 1);
134 wchar_t* buffer = short_path.data();
135 DWORD res = GetShortPathNameW(
path.c_str(), buffer, maxPath);
139 std::string filePath;
149 std::string result = _p->generic_string();
150 std::replace(result.begin(), result.end(),
'/',
'\\');
158 return _p->filename();
161 _p->replace_extension(e);
164 return _p->extension();
170 return _p->parent_path();
189 return *
r._p == *
l._p;
192 return *
r._p != *
l._p;
210 return *
r._p == *
l._p;
213 return *
r._p != *
l._p;
220 boost::filesystem::create_directories(
p);
250 boost::system::error_code ec;
252 #if BOOST_VERSION > 107300
254 throw boost::system::system_error(boost::system::errc::make_error_code(boost::system::errc::errc_t::file_exists));
256 if ( boost::filesystem::is_directory(
f ) ) {
257 boost::filesystem::copy(boost::filesystem::path(
f),
258 boost::filesystem::path(t),
259 boost::filesystem::copy_options::directories_only,
262 boost::filesystem::copy(boost::filesystem::path(
f),
263 boost::filesystem::path(t),
264 boost::filesystem::copy_options::none,
268 boost::filesystem::copy( boost::filesystem::path(
f), boost::filesystem::path(t), ec );
270 }
catch ( boost::system::system_error& e ) {
271 FC_THROW(
"Copy from ${srcfile} to ${dstfile} failed because ${reason}",
272 (
"srcfile",
f)(
"dstfile",t)(
"reason",e.what() ) );
274 FC_THROW(
"Copy from ${srcfile} to ${dstfile} failed",
278 FC_THROW(
"Copy from ${srcfile} to ${dstfile} failed because ${reason}, category: ${cat}",
279 (
"srcfile",
f)(
"dstfile",t)(
"reason", ec.message())(
"cat", ec.category().name()) );
285 boost::filesystem::resize_file(
f, t );
287 catch ( boost::system::system_error& e )
289 FC_THROW(
"Resize file '${f}' to size ${s} failed: ${reason}",
290 (
"f",
f)(
"s",t)(
"reason", e.what() ) );
294 FC_THROW(
"Resize file '${f}' to size ${s} failed: ${reason}",
306 ((perm & 0400) ? S_IRUSR : 0)
307 | ((perm & 0200) ? S_IWUSR : 0)
308 | ((perm & 0100) ? S_IXUSR : 0)
310 | ((perm & 0040) ? S_IRGRP : 0)
311 | ((perm & 0020) ? S_IWGRP : 0)
312 | ((perm & 0010) ? S_IXGRP : 0)
314 | ((perm & 0004) ? S_IROTH : 0)
315 | ((perm & 0002) ? S_IWOTH : 0)
316 | ((perm & 0001) ? S_IXOTH : 0)
319 int result =
::chmod(
p.string().c_str(), actual_perm );
321 FC_THROW(
"chmod operation failed on ${p}", (
"p",
p) );
328 boost::filesystem::rename( boost::filesystem::path(
f), boost::filesystem::path(t) );
329 }
catch ( boost::system::system_error& ) {
331 boost::filesystem::copy( boost::filesystem::path(
f), boost::filesystem::path(t) );
332 boost::filesystem::remove( boost::filesystem::path(
f));
333 }
catch ( boost::system::system_error& e ) {
334 FC_THROW(
"Rename from ${srcfile} to ${dstfile} failed because ${reason}",
335 (
"srcfile",
f)(
"dstfile",t)(
"reason",e.what() ) );
338 FC_THROW(
"Rename from ${srcfile} to ${dstfile} failed",
344 boost::filesystem::create_hard_link(
f, t );
346 FC_THROW(
"Unable to create hard link from '${from}' to '${to}'",
352 return boost::filesystem::remove(
f );
359 return boost::filesystem::canonical(
p);
370 boost::filesystem::path a_From = boost::filesystem::absolute(from);
371 boost::filesystem::path a_To = boost::filesystem::absolute(to);
372 boost::filesystem::path
ret;
373 boost::filesystem::path::const_iterator itrFrom(a_From.begin()), itrTo(a_To.begin());
375 for( boost::filesystem::path::const_iterator toEnd( a_To.end() ), fromEnd( a_From.end() ) ; itrFrom != fromEnd && itrTo != toEnd && *itrFrom == *itrTo; ++itrFrom, ++itrTo );
377 for( boost::filesystem::path::const_iterator fromEnd( a_From.end() ); itrFrom != fromEnd; ++itrFrom ) {
378 if( (*itrFrom) !=
"." )
382 for (; itrTo != a_To.end(); ++itrTo)
392 FC_THROW(
"Name collision: ${path}", (
"path",
_path->string()) );
396 std::ofstream ofs(
_path->generic_string().c_str(), std::ofstream::out | std::ofstream::binary);
411 _path = std::move(other._path);
421 FC_THROW(
"Name collision: ${path}", (
"path",
_path->string()) );
436 _path = std::move(other._path);
445 FC_THROW(
"Temporary directory has been released." );
468 _path = std::optional<fc::path>();
477 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &access_token))
478 FC_ASSERT(
false,
"Unable to open an access token for the current process");
479 wchar_t user_profile_dir[MAX_PATH];
480 DWORD user_profile_dir_len =
sizeof(user_profile_dir);
481 BOOL success = GetUserProfileDirectoryW(access_token, user_profile_dir, &user_profile_dir_len);
482 CloseHandle(access_token);
484 FC_ASSERT(
false,
"Unable to get the user profile directory");
485 return fc::path(std::wstring(user_profile_dir));
487 char* home = getenv(
"HOME" );
488 if(
nullptr == home )
490 struct passwd* pwd = getpwuid(getuid());
493 return fc::path( std::string( pwd->pw_dir ) );
495 FC_ASSERT( home !=
nullptr,
"The HOME environment variable is not set" );
497 return fc::path( std::string(home) );
506 static fc::path appdir = [](){
return home_path() /
"Library" /
"Application Support"; }();
507#elif defined( WIN32 )
509 wchar_t app_data_dir[MAX_PATH];
511 if (!SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, app_data_dir)))
512 FC_ASSERT(
false,
"Unable to get the current AppData directory");
513 return fc::path(std::wstring(app_data_dir));
523 static fc::path appCurrentPath = boost::filesystem::current_path();
524 return appCurrentPath;
528#ifdef FC_HAS_SIMPLE_FILE_LOCK
529 class simple_lock_file::impl
540 impl(
const path& lock_file_path);
547 simple_lock_file::impl::impl(
const path& lock_file_path) :
549 file_handle(INVALID_HANDLE_VALUE),
554 lock_file_path(lock_file_path)
557 simple_lock_file::impl::~impl()
562 bool simple_lock_file::impl::try_lock()
565 HANDLE fh = CreateFileA(lock_file_path.to_native_ansi_path().c_str(),
566 GENERIC_READ | GENERIC_WRITE,
568 OPEN_ALWAYS, 0, NULL);
569 if (fh == INVALID_HANDLE_VALUE)
575 int fd =
open(lock_file_path.string().c_str(), O_RDWR|O_CREAT, 0644);
578 if (flock(fd, LOCK_EX|LOCK_NB) == -1)
589 void simple_lock_file::impl::unlock()
592 CloseHandle(file_handle);
593 file_handle = INVALID_HANDLE_VALUE;
596 flock(file_handle, LOCK_UN);
604 simple_lock_file::simple_lock_file(
const path& lock_file_path) :
605 my(new impl(lock_file_path))
609 simple_lock_file::~simple_lock_file()
613 bool simple_lock_file::try_lock()
615 return my->try_lock();
618 void simple_lock_file::unlock()
directory_iterator & operator++()
fc::path operator*() const
detail::path_wrapper operator->() const
wraps boost::filesystem::path to provide platform independent path manipulation.
std::wstring generic_wstring() const
std::wstring preferred_wstring() const
fc::path parent_path() const
std::string windows_string() const
replaces '/' with '\' in the result of generic_string()
fc::path filename() const
std::wstring wstring() const
static char separator_char
path & operator=(const path &)
std::string preferred_string() const
std::string to_native_ansi_path() const
std::string string() const
fc::path extension() const
std::string generic_string() const
path & operator/=(const fc::path &)
void replace_extension(const fc::path &e)
recursive_directory_iterator()
~recursive_directory_iterator()
fc::path operator*() const
recursive_directory_iterator & operator++()
temp_directory(temp_directory &&other)
temp_directory & operator=(temp_directory &&other)
const fc::path & path() const
temp_file(temp_file &&other)
temp_file & operator=(temp_file &&other)
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object's.
Defines exception's used by fc.
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
void close(T *e, websocketpp::connection_hdl hdl)
void rename(const path &from, const path &to)
bool remove(const path &p)
bool operator<(const array< T, N > &a, const array< T, N > &b)
bool exists(const path &p)
void decodeUtf8(const std::string &input, std::wstring *storage)
void remove_all(const path &p)
bool operator!=(const array< T, N > &a, const array< T, N > &b)
bool is_regular_file(const path &p)
const fc::path & current_path()
bool operator==(const array< T, N > &a, const array< T, N > &b)
void create_directories(const path &p)
void copy(const path &from, const path &to)
void encodeUtf8(const std::wstring &input, std::string *storage)
void create_hard_link(const path &from, const path &to)
path make_relative(const path &from, const path &to)
uint64_t file_size(const path &p)
bool is_directory(const path &p)
void resize_file(const path &file, size_t s)
uint64_t directory_size(const path &p)
path absolute(const path &p)
fc::variant operator/(const fc::variant &a, const fc::variant &b)
path canonical(const path &p)
void from_variant(const fc::variant &v, sysio::chain::chain_id_type &cid)
void chmod(const path &p, int perm)
void to_variant(const sysio::chain::shared_public_key &var, fc::variant &vo)
path temp_directory_path()
unsigned __int64 uint64_t