Line data Source code
1 : #if (defined(__GNUC__) || defined(__clang__) || defined(__llvm__)) && \ 2 : (defined(__linux__) || defined(__linux) || defined(__APPLE__)) && !defined(__ANDROID__) 3 : #include <cxxabi.h> // __cxa_demangle 4 : #include <execinfo.h> // backtrace, backtrace_symbols 5 : #endif 6 : 7 : #if defined(__linux__) || defined(linux) || defined(__linux) || defined(__FreeBSD__) 8 : #include <errno.h> 9 : #include <string.h> 10 : #include <unistd.h> 11 : #elif defined(__APPLE__) || defined(__MACH__) 12 : #include <mach-o/dyld.h> 13 : #elif defined(_WIN32) || defined(_WIN64) 14 : #include <Windows.h> 15 : #endif 16 : 17 : #include <cstdio> 18 : #include <cstdlib> 19 : #include <sstream> 20 : #include <stdexcept> 21 : #include <vector> 22 : 23 : #include "Tools/Exception/exception.hpp" 24 : #include "Tools/system_functions.h" 25 : 26 : std::string 27 0 : spu::tools::run_system_command(std::string cmd) 28 : { 29 0 : std::string data; 30 : 31 0 : cmd.append(" 2>&1"); 32 : 33 : #if (defined(__GNUC__) || defined(__clang__) || defined(__llvm__)) && \ 34 : (defined(__linux__) || defined(__linux) || defined(__APPLE__)) && !defined(__ANDROID__) 35 0 : FILE* stream = popen(cmd.c_str(), "r"); 36 : #elif defined(_WIN64) || defined(_WIN32) 37 : FILE* stream = _popen(cmd.c_str(), "r"); 38 : #else 39 : FILE* stream = nullptr; 40 : #endif 41 : 42 0 : if (stream) 43 : { 44 0 : const int max_buffer = 256; 45 : char buffer[max_buffer]; 46 0 : while (!feof(stream)) 47 0 : if (fgets(buffer, max_buffer, stream) != NULL) data.append(buffer); 48 : 49 : #if (defined(__GNUC__) || defined(__clang__) || defined(__llvm__)) && \ 50 : (defined(__linux__) || defined(__linux) || defined(__APPLE__)) && !defined(__ANDROID__) 51 0 : pclose(stream); 52 : #elif defined(_WIN64) || defined(_WIN32) 53 : _pclose(stream); 54 : #endif 55 : } 56 : else 57 0 : throw std::runtime_error("run_system_command error: Couldn't open the pipe to run system command."); 58 : 59 0 : return data; 60 0 : } 61 : 62 : std::string 63 0 : spu::tools::get_binary_path() 64 : { 65 0 : std::string binary_path; 66 : 67 : #if defined(__linux__) || defined(linux) || defined(__linux) || defined(__FreeBSD__) 68 0 : constexpr size_t path_size = 8192; 69 : char path[path_size]; 70 : #ifdef __FreeBSD__ 71 : auto len = readlink("/proc/curproc/file", path, path_size); 72 : #else 73 0 : auto len = readlink("/proc/self/exe", path, path_size); 74 : #endif 75 0 : if (len == -1) 76 : { 77 0 : std::stringstream message; 78 0 : message << "'readlink' failed ('errno' = " << strerror(errno) << ")."; 79 0 : throw runtime_error(__FILE__, __LINE__, __func__, message.str()); 80 0 : } 81 0 : path[len] = '\0'; 82 0 : binary_path = path; 83 : #elif defined(__APPLE__) || defined(__MACH__) 84 : constexpr size_t path_size = 8192; 85 : char path[path_size]; 86 : uint32_t size = sizeof(path); 87 : if (_NSGetExecutablePath(path, &size) != 0) 88 : { 89 : std::stringstream message; 90 : message << "'_NSGetExecutablePath' path buffer is too small; need 'size' = " << size 91 : << "('path_size' = " << path_size << ")."; 92 : throw runtime_error(__FILE__, __LINE__, __func__, message.str()); 93 : } 94 : binary_path = path; 95 : #elif defined(_WIN32) || defined(_WIN64) 96 : constexpr size_t path_size = 8192; 97 : char path[path_size]; 98 : DWORD copied = 0; 99 : copied = GetModuleFileName(NULL, path, path_size); 100 : if (copied >= path_size) 101 : { 102 : std::stringstream message; 103 : message << "'GetModuleFileName' path buffer is too small ('path_size' = " << path_size << ")."; 104 : throw runtime_error(__FILE__, __LINE__, __func__, message.str()); 105 : } 106 : binary_path = path; 107 : #endif 108 : 109 0 : return binary_path; 110 0 : } 111 : 112 : void 113 0 : spu::tools::split_path(const std::string& path, std::string& basedir, std::string& filename) 114 : { 115 : size_t found; 116 0 : found = path.find_last_of("/\\"); 117 0 : basedir = path.substr(0, found); 118 0 : filename = path.substr(found + 1); 119 0 : }