From d6c1e42a26520730897e53df5665765abf66c002 Mon Sep 17 00:00:00 2001 From: Andrey Astafyev Date: Mon, 25 Nov 2019 15:08:34 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A1=D1=82=D0=B0=D0=BD=D0=B4=D0=B0=D1=80?= =?UTF-8?q?=D1=82=D0=BD=D1=8B=D0=B5=20=D0=BF=D1=83=D1=82=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/filesystem/01_minimal/CMakeLists.txt | 2 - examples/filesystem/01_minimal/minimal.cpp | 5 + src/myx/filesystem/CMakeLists.txt | 4 +- src/myx/filesystem/current_executable.cpp | 43 +++ src/myx/filesystem/current_executable.hpp | 30 ++ src/myx/filesystem/paths.cpp | 70 ++-- src/myx/filesystem/paths.hpp | 14 +- src/myx/filesystem/whereami.cpp | 305 ------------------ src/myx/filesystem/whereami.hpp | 121 ------- 9 files changed, 126 insertions(+), 468 deletions(-) create mode 100644 src/myx/filesystem/current_executable.cpp create mode 100644 src/myx/filesystem/current_executable.hpp delete mode 100644 src/myx/filesystem/whereami.cpp delete mode 100644 src/myx/filesystem/whereami.hpp diff --git a/examples/filesystem/01_minimal/CMakeLists.txt b/examples/filesystem/01_minimal/CMakeLists.txt index 2fd45e9..785b520 100644 --- a/examples/filesystem/01_minimal/CMakeLists.txt +++ b/examples/filesystem/01_minimal/CMakeLists.txt @@ -33,8 +33,6 @@ target_include_directories(${current_target} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIR target_compile_options(${current_target} PUBLIC "${Qt5Core_EXECUTABLE_COMPILE_FLAGS}") target_link_libraries(${current_target} myx-filesystem) -target_link_libraries(${current_target} whereamipp) -target_link_libraries(${current_target} whereami) target_link_libraries(${current_target} Qt5::Core) # Имя выходного файла для цели diff --git a/examples/filesystem/01_minimal/minimal.cpp b/examples/filesystem/01_minimal/minimal.cpp index ccbd999..deb06ef 100644 --- a/examples/filesystem/01_minimal/minimal.cpp +++ b/examples/filesystem/01_minimal/minimal.cpp @@ -1,5 +1,9 @@ +#include + #include +#include + namespace MF = myx::filesystem; @@ -7,6 +11,7 @@ int main( int argc, char** argv ) { (void)argc; (void)argv; + QCoreApplication::setApplicationName( PROJECT_NAME ); MF::Paths paths; paths.updatePaths(); diff --git a/src/myx/filesystem/CMakeLists.txt b/src/myx/filesystem/CMakeLists.txt index 3439d0e..eaad8c2 100644 --- a/src/myx/filesystem/CMakeLists.txt +++ b/src/myx/filesystem/CMakeLists.txt @@ -3,14 +3,14 @@ set(current_target filesystem) # Список файлов исходных текстов set(current_target_sources + ${CMAKE_CURRENT_SOURCE_DIR}/current_executable.cpp ${CMAKE_CURRENT_SOURCE_DIR}/paths.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/whereami.cpp ) # Список заголовочных файлов (используется для установки) set(current_target_headers + ${CMAKE_CURRENT_SOURCE_DIR}/current_executable.hpp ${CMAKE_CURRENT_SOURCE_DIR}/paths.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/whereami.hpp ) add_common_library(TARGET ${current_target} diff --git a/src/myx/filesystem/current_executable.cpp b/src/myx/filesystem/current_executable.cpp new file mode 100644 index 0000000..9a2bb8f --- /dev/null +++ b/src/myx/filesystem/current_executable.cpp @@ -0,0 +1,43 @@ +#include "current_executable.hpp" + +#include + +#include +#include +#include + +namespace myx { + +namespace filesystem { + +CurrentExecutable::CurrentExecutable() : + m_procFilePath( "/proc/self/exe" ) +{ + auto canonicalFilePath = m_procFilePath.canonicalFilePath(); + auto canonicalPath = m_procFilePath.canonicalPath(); + m_fileName = canonicalFilePath.remove( canonicalPath ).remove( '/' ); + m_canonicalFilePath = canonicalFilePath; + m_canonicalPath = canonicalPath; +} + + +QFileInfo CurrentExecutable::canonicalFilePath() const +{ + return( m_canonicalFilePath ); +} + + +QDir CurrentExecutable::canonicalPath() const +{ + return( m_canonicalPath ); +} + + +QString CurrentExecutable::fileName() const +{ + return( m_fileName ); +} + +} // namespace filesystem + +} // namespace myx diff --git a/src/myx/filesystem/current_executable.hpp b/src/myx/filesystem/current_executable.hpp new file mode 100644 index 0000000..5c86a90 --- /dev/null +++ b/src/myx/filesystem/current_executable.hpp @@ -0,0 +1,30 @@ +#ifndef MYX_FILESYSTEM_CURRENT_EXECUTABLE_HPP_ +#define MYX_FILESYSTEM_CURRENT_EXECUTABLE_HPP_ + +#include +#include +#include + +namespace myx { + +namespace filesystem { + +class CurrentExecutable +{ + QFileInfo m_procFilePath; + QFileInfo m_canonicalFilePath; + QDir m_canonicalPath; + QString m_fileName; + +public: + CurrentExecutable(); + QFileInfo canonicalFilePath() const; + QDir canonicalPath() const; + QString fileName() const; +}; + +} // namespace filesystem + +} // namespace myx + +#endif // MYX_FILESYSTEM_CURRENT_EXECUTABLE_HPP_ diff --git a/src/myx/filesystem/paths.cpp b/src/myx/filesystem/paths.cpp index 869b1c5..01b1a36 100644 --- a/src/myx/filesystem/paths.cpp +++ b/src/myx/filesystem/paths.cpp @@ -1,7 +1,7 @@ #include "paths.hpp" #include -#include +#include #include #include @@ -13,13 +13,7 @@ namespace filesystem { QString Paths::executableFileName() const { - return( m_executableFileName ); -} - - -void Paths::setExecutableFileName( const QString& executableFileName ) -{ - m_executableFileName = executableFileName; + return( m_currentExecutable.fileName() ); } @@ -37,13 +31,7 @@ void Paths::setConfigFileName( const QString& configFileName ) QFileInfo Paths::executableFilePath() const { - return( m_executableFilePath ); -} - - -void Paths::setExecutableFilePath( const QFileInfo& executableFilePath ) -{ - m_executableFilePath = executableFilePath; + return( m_currentExecutable.canonicalFilePath() ); } @@ -59,20 +47,36 @@ void Paths::setConfigFilePath( const QFileInfo& configFilePath ) } -Paths::Paths() +QDir Paths::logDirectory() const +{ + return( m_logDirectory ); +} + + +void Paths::setLogDirectory( const QString& logDirectory ) +{ + m_logDirectory = logDirectory; +} + + +Paths::Paths( const QString& configFileExtension ) : + m_configFileExtension( configFileExtension ) + { m_prefixDirectory = "/opt/" + QCoreApplication::organizationName().toLower() + "/" + QCoreApplication::applicationName().toLower(); - m_binaryDirectory = m_prefixDirectory.absolutePath() + "/bin"; - m_configDirectory = m_prefixDirectory.absolutePath() + "/etc"; - m_cacheDirectory = m_prefixDirectory.absolutePath() + "/var"; - m_tempDirectory = QString::fromLocal8Bit( qgetenv( qPrintable( "TMPDIR" ) ) ); - m_dataDirectory = m_prefixDirectory.absolutePath() + "/share"; - m_homeDirectory = QString::fromLocal8Bit( qgetenv( qPrintable( "HOME" ) ) ); - m_executableFileName = QCoreApplication::applicationName().toLower(); - m_configFileName = m_executableFileName + ".conf"; - m_executableFilePath = m_binaryDirectory.absolutePath() + "/" + m_executableFileName; - m_configFilePath = m_binaryDirectory.absolutePath() + "/" + m_configFileName; + auto pd = m_prefixDirectory.absolutePath(); + m_binaryDirectory = pd + "/bin"; + m_configDirectory = pd + "/etc"; + m_cacheDirectory = pd + "/var"; + m_logDirectory = pd + "/var/log"; + m_tempDirectory = QString::fromLocal8Bit( qgetenv( qPrintable( "TMPDIR" ) ) ); + m_dataDirectory = pd + "/share"; + m_homeDirectory = QString::fromLocal8Bit( qgetenv( qPrintable( "HOME" ) ) ); + m_configFileName = QCoreApplication::applicationName().toLower() + + "." + m_configFileExtension; + m_configFilePath = m_binaryDirectory.absolutePath() + + "/" + m_configFileName; if ( m_tempDirectory.absolutePath().isEmpty() || ( m_tempDirectory.path() == "." ) ) @@ -156,20 +160,18 @@ void Paths::setDataDirectory( const QString& dataDirectory ) bool Paths::updatePaths() { - whereami::whereami_path_t executablePath = whereami::getExecutablePath(); - - m_executableFileName = QString::fromStdString( executablePath.basename() ); - m_binaryDirectory = QString::fromStdString( executablePath.dirname() ); - m_executableFilePath = QFile( m_binaryDirectory.absolutePath() + "/" + m_executableFileName ); + m_binaryDirectory = m_currentExecutable.canonicalPath(); if ( m_binaryDirectory.absolutePath().endsWith( "/bin" ) ) { m_prefixDirectory = m_binaryDirectory.absolutePath().remove( QRegExp( "/bin$" ) ); m_configDirectory = m_prefixDirectory.absolutePath() + "/etc"; m_cacheDirectory = m_prefixDirectory.absolutePath() + "/var"; + m_logDirectory = m_prefixDirectory.absolutePath() + "/var/log"; m_dataDirectory = m_prefixDirectory.absolutePath() + "/share"; - m_configFilePath = QFile( m_configDirectory.absolutePath() + "/" + - QCoreApplication::applicationName() + ".conf" ); + m_configFilePath = QFile( m_configDirectory.absolutePath() + + "/" + QCoreApplication::applicationName() + + "." + m_configFileExtension ); } if ( m_prefixDirectory.absolutePath().startsWith( "/opt" ) || @@ -201,6 +203,7 @@ bool Paths::updatePaths() m_cacheDirectory = cacheDirectory + "/" + QCoreApplication::organizationName().toLower() + "/" + QCoreApplication::applicationName().toLower(); + m_logDirectory = m_cacheDirectory.absolutePath() + "/log"; } return( true ); @@ -214,6 +217,7 @@ bool Paths::makeDefaultDirectories() if ( !m_dataDirectory.mkpath( m_dataDirectory.absolutePath() ) ) { status = false; } if ( !m_configDirectory.mkpath( m_configDirectory.absolutePath() ) ) { status = false; } if ( !m_cacheDirectory.mkpath( m_cacheDirectory.absolutePath() ) ) { status = false; } + if ( !m_logDirectory.mkpath( m_logDirectory.absolutePath() ) ) { status = false; } return( status ); } diff --git a/src/myx/filesystem/paths.hpp b/src/myx/filesystem/paths.hpp index 96b7ad5..a03f0d0 100644 --- a/src/myx/filesystem/paths.hpp +++ b/src/myx/filesystem/paths.hpp @@ -1,6 +1,8 @@ #ifndef MYX_FILESYSTEM_PATHS_HPP_ #define MYX_FILESYSTEM_PATHS_HPP_ +#include + #include #include #include @@ -17,14 +19,16 @@ class Paths QDir m_cacheDirectory; QDir m_tempDirectory; QDir m_dataDirectory; + QDir m_logDirectory; QDir m_homeDirectory; - QString m_executableFileName; + QString m_configFileExtension; QString m_configFileName; - QFileInfo m_executableFilePath; QFileInfo m_configFilePath; + CurrentExecutable m_currentExecutable; + public: - Paths(); + Paths( const QString& configFileExtension = "conf" ); QDir prefixDirectory() const; void setPrefixDirectory( const QString& prefixDirectory ); QDir binaryDirectory() const; @@ -37,12 +41,12 @@ public: void setTempDirectory( const QString& tempDirectory ); QDir dataDirectory() const; void setDataDirectory( const QString& dataDirectory ); + QDir logDirectory() const; + void setLogDirectory( const QString& logDirectory ); QString executableFileName() const; - void setExecutableFileName( const QString& executableFileName ); QString configFileName() const; void setConfigFileName( const QString& configFileName ); QFileInfo executableFilePath() const; - void setExecutableFilePath( const QFileInfo& executableFilePath ); QFileInfo configFilePath() const; void setConfigFilePath( const QFileInfo& configFilePath ); diff --git a/src/myx/filesystem/whereami.cpp b/src/myx/filesystem/whereami.cpp deleted file mode 100644 index c7d5b08..0000000 --- a/src/myx/filesystem/whereami.cpp +++ /dev/null @@ -1,305 +0,0 @@ -#include - -namespace whereami { - -namespace { - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#ifndef WAI_NOINLINE -#if defined( _MSC_VER ) -#define WAI_NOINLINE __declspec( noinline ) -#elif defined( __GNUC__ ) -#define WAI_NOINLINE __attribute__( ( noinline ) ) -#else -#error unsupported compiler -#endif -#endif - -#if defined( _MSC_VER ) -#define WAI_RETURN_ADDRESS() _ReturnAddress() -#elif defined( __GNUC__ ) -#define WAI_RETURN_ADDRESS() __builtin_extract_return_addr( __builtin_return_address( 0 ) ) -#else -#error unsupported compiler -#endif - - -#include -#include -#include -#if defined( __linux__ ) -#include -#else -#include -#endif -#ifndef __STDC_FORMAT_MACROS -#define __STDC_FORMAT_MACROS -#endif -#include - -#if !defined( WAI_PROC_SELF_EXE ) -#define WAI_PROC_SELF_EXE "/proc/self/exe" -#endif - - -int getExecutablePath( char* out, int capacity, int* dirname_length ) -{ - char buffer[PATH_MAX]; - char* resolved = nullptr; - int length = -1; - - for (;; ) - { - resolved = realpath( WAI_PROC_SELF_EXE, buffer ); - if ( !resolved ) - { - break; - } - - length = static_cast< int >( strlen( resolved ) ); - if ( length <= capacity ) - { - memcpy( out, resolved, static_cast< size_t >( length ) ); - - if ( dirname_length ) - { - for ( int i = length - 1; i >= 0; --i ) - { - if ( out[i] == '/' ) - { - *dirname_length = i; - break; - } - } - } - } - - break; - } - - return( length ); -} // getExecutablePath - - -#if !defined( WAI_PROC_SELF_MAPS_RETRY ) -#define WAI_PROC_SELF_MAPS_RETRY 5 -#endif - -#if !defined( WAI_PROC_SELF_MAPS ) -#if defined( __sun ) -#define WAI_PROC_SELF_MAPS "/proc/self/map" -#else -#define WAI_PROC_SELF_MAPS "/proc/self/maps" -#endif -#endif - -#if defined( __ANDROID__ ) || defined( ANDROID ) -#include -#include -#include -#endif - - -WAI_NOINLINE -int getModulePath( char* out, int capacity, int* dirname_length ) -{ - int length = -1; - FILE* maps = nullptr; - - for ( int r = 0; r < WAI_PROC_SELF_MAPS_RETRY; ++r ) - { - maps = fopen( WAI_PROC_SELF_MAPS, "r" ); - if ( !maps ) - { - break; - } - - for (;; ) - { - char buffer[PATH_MAX < 1024 ? 1024 : PATH_MAX]; - uint64_t low, high; - char perms[5]; - uint64_t offset; - uint32_t major, minor; - char path[PATH_MAX]; - uint32_t inode; - - if ( !fgets( buffer, sizeof( buffer ), maps ) ) - { - break; - } - - if ( sscanf( buffer, "%" PRIx64 "-%" PRIx64 " %s %" PRIx64 " %x:%x %u %s\n", &low, &high, perms, &offset, &major, &minor, &inode, path ) == 8 ) - { - uint64_t addr = reinterpret_cast< uintptr_t >( WAI_RETURN_ADDRESS() ); - if ( ( low <= addr ) && ( addr <= high ) ) - { - char* resolved = nullptr; - - resolved = realpath( path, buffer ); - if ( resolved == nullptr ) - { - break; - } - - length = static_cast< int >( strlen( resolved ) ); - if ( length <= capacity ) - { - memcpy( out, resolved, static_cast< size_t >( length ) ); - - if ( dirname_length ) - { - for ( int i = length - 1; i >= 0; --i ) - { - if ( out[i] == '/' ) - { - *dirname_length = i; - break; - } - } - } - } - - break; - } - } - } - - fclose( maps ); - maps = nullptr; - - if ( length != -1 ) - { - break; - } - } - - if ( maps != nullptr ) - { - fclose( maps ); - } - - return( length ); -} // getModulePath - - -#ifdef __cplusplus - -} // namespace -#endif - -} // namespace - - -whereami_string_t whereami_path_t::dirname() const -{ - return( m_path.substr( 0, static_cast< size_t >( m_dirnameLength ) ) ); -} - - -whereami_string_t whereami_path_t::basename() const -{ - return( m_path.substr( static_cast< size_t >( m_dirnameLength + 1 ) ) ); -} - - -#if defined( WHEREAMI_CXX11 ) -whereami_path_t::operator whereami_string_t() && -{ - return( std::move( m_path ) ); -} - -whereami_path_t::operator whereami_string_t() const & -{ - return( m_path ); -} - - -#else -whereami_path_t::operator const whereami_string_t&() const -{ - return( m_path ); -} - - -#endif // if defined( WHEREAMI_CXX11 ) - -#if defined( WHEREAMI_CXX11 ) -whereami_path_t::whereami_path_t( whereami_string_t&& path, int dirname_length ) noexcept : - m_path ( std::move( path ) ), - m_dirnameLength( dirname_length ) -{ -} - - -#else -whereami_path_t::whereami_path_t( whereami_string_t& path, int dirname_length ) : - m_path ( path ), - m_dirnameLength( dirname_length ) -{ -} - - -#endif - -#if !defined( WHEREAMI_DISABLE_OSTREAM ) -std::ostream& operator<<( std::ostream& os, const whereami_path_t& path ) -{ - return( os << path.m_path ); -} - - -#endif - - -whereami_path_t getExecutablePath() -{ - whereami_string_t path; - int dirname_length = -1; - - int length = getExecutablePath( nullptr, 0, nullptr ); - - if ( length != -1 ) - { - path.resize( static_cast< size_t >( length ) ); - getExecutablePath( &path[0], length, &dirname_length ); - } - - #if defined( WHEREAMI_CXX11 ) - return( whereami_path_t( std::move( path ), dirname_length ) ); - - #else - return( whereami_path_t( path, dirname_length ) ); - - #endif -} - - -whereami_path_t getModulePath() -{ - whereami_string_t path; - int dirname_length = -1; - - int length = getModulePath( nullptr, 0, nullptr ); - - if ( length != -1 ) - { - path.resize( static_cast< size_t >( length ) ); - getModulePath( &path[0], length, &dirname_length ); - } - - #if defined( WHEREAMI_CXX11 ) - return( whereami_path_t( std::move( path ), dirname_length ) ); - - #else - return( whereami_path_t( path, dirname_length ) ); - - #endif -} - -} // namespace whereami diff --git a/src/myx/filesystem/whereami.hpp b/src/myx/filesystem/whereami.hpp deleted file mode 100644 index 0fdca45..0000000 --- a/src/myx/filesystem/whereami.hpp +++ /dev/null @@ -1,121 +0,0 @@ -#ifndef WHEREAMIPP_HPP_ -#define WHEREAMIPP_HPP_ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Returns the path to the current executable. - * - * Usage: - * - first call `int length = wai_getExecutablePath(NULL, 0, NULL);` to - * retrieve the length of the path - * - allocate the destination buffer with `path = (char*)malloc(length + 1);` - * - call `wai_getExecutablePath(path, length, NULL)` again to retrieve the - * path - * - add a terminal NUL character with `path[length] = '\0';` - * - * @param out destination buffer, optional - * @param capacity destination buffer capacity - * @param dirname_length optional recipient for the length of the dirname part - * of the path. - * - * @return the length of the executable path on success (without a terminal NUL - * character), otherwise `-1` - */ -int getExecutablePath( char* out, int capacity, int* dirname_length ); - -/** - * Returns the path to the current module. - * - * Usage: - * - first call `int length = wai_getModulePath(NULL, 0, NULL);` to retrieve - * the length of the path - * - allocate the destination buffer with `path = (char*)malloc(length + 1);` - * - call `wai_getModulePath(path, length, NULL)` again to retrieve the path - * - add a terminal NUL character with `path[length] = '\0';` - * - * @param out destination buffer, optional - * @param capacity destination buffer capacity - * @param dirname_length optional recipient for the length of the dirname part - * of the path. - * - * @return the length of the module path on success (without a terminal NUL - * character), otherwise `-1` - */ - -int getModulePath( char* out, int capacity, int* dirname_length ); - -#ifdef __cplusplus -} -#endif - - -#if !defined( WHEREAMI_STRING_T ) -#include -typedef std::string whereami_string_t; -#else -typedef WHEREAMI_STRING_T whereami_string_t; -#endif -#if !defined( WHEREAMI_DISABLE_OSTREAM ) -#include -#endif - -#if ( defined ( __cplusplus ) && ( __cplusplus > 199711L ) ) || ( defined( _MSC_FULL_VER ) && ( _MSC_FULL_VER >= 150020706 ) ) - #define WHEREAMI_CXX11 -#endif - -#if defined( __GNUC__ ) -#if ( ( __GNUC__ * 100 + __GNUC_MINOR__ ) < 408 ) - #undef WHEREAMI_CXX11 -#endif -#endif - - -namespace whereami { - -class whereami_path_t -{ -public: - #if defined( WHEREAMI_CXX11 ) - operator whereami_string_t() &&; - operator whereami_string_t() const &; - #else - operator const whereami_string_t&() const; - #endif - whereami_string_t dirname() const; - whereami_string_t basename() const; - -private: - whereami_path_t(); - - #if defined( WHEREAMI_CXX11 ) - whereami_path_t( whereami_string_t&& path, int dirname_length ) noexcept; - #else - whereami_path_t( whereami_string_t& m_path, int m_dirnameLength ); - #endif - - friend whereami_path_t getExecutablePath(); - friend whereami_path_t getModulePath(); - #if !defined( WHEREAMI_DISABLE_OSTREAM ) - friend std::ostream& operator<<( std::ostream& os, const whereami_path_t& m_path ); - #endif - - whereami_string_t m_path; - int m_dirnameLength; -}; // class whereami_path_t - -/** - * Returns the path to the current executable. - */ -whereami_path_t getExecutablePath(); - -/** - * Returns the path to the current module. - */ -whereami_path_t getModulePath(); - -} // namespace whereami - -#endif // #ifndef WHEREAMIPP_H