Mercurial > code
view misc/executable.cpp @ 593:c767f1202e8e
Ini: move to bitbucket
author | David Demelier <markand@malikania.fr> |
---|---|
date | Mon, 05 Sep 2016 22:00:23 +0200 |
parents | 668975a91fb2 |
children | f8616f9fc9d5 |
line wrap: on
line source
#include <string> #include <stdexcept> #if defined(__linux__) # include <unistd.h> # include <cerrno> # include <cstring> # include <stdexcept> #elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__) || defined(__OpenBSD__) # if defined(__NetBSD__) # include <sys/param.h> # else # include <sys/types.h> # endif # if defined(__OpenBSD__) # include <unistd.h> # endif # include <sys/sysctl.h> # include <array> # include <cerrno> # include <climits> # include <cstddef> # include <cstdlib> # include <cstring> # include <stdexcept> #elif defined(__APPLE__) # include <cerrno> # include <cstring> # include <libproc.h> # include <unistd.h> #elif defined(_WIN32) # include <Windows.h> #endif #if defined(__linux__) std::string executable() { std::string result; result.resize(2048, '\0'); auto size = readlink("/proc/self/exe", &result[0], 2048); if (size < 0) throw std::runtime_error(std::strerror(errno)); result.resize(size, '\0'); return result; } #elif defined(__FreeBSD__) || defined(__DragonFly__) std::string executable() { std::array<int, 4> mib{ CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 }; std::string result; std::size_t size = PATH_MAX + 1; result.resize(size, '\0'); if (sysctl(mib.data(), 4, &result[0], &size, nullptr, 0) < 0) throw std::runtime_error(std::strerror(errno)); result.resize(size, '\0'); return result; } #elif defined(__APPLE__) std::string executable() { std::string result; std::size_t size = PROC_PIDPATHINFO_MAXSIZE; result.resize(size, '\0'); if ((size = proc_pidpath(getpid(), &result[0], size)) == 0) throw std::runtime_error(std::strerror(errno)); result.resize(size, '\0'); return result; } #elif defined(_WIN32) std::string executable() { std::string result; std::size_t size = PATH_MAX; result.resize(size, '\0'); if (!(size = GetModuleFileNameA(nullptr, &result[0], size))) throw std::runtime_error("GetModuleFileName error"); result.resize(size, '\0'); return result; } #elif defined(__NetBSD__) std::string executable() { std::string result; #if defined(KERN_PROC_PATHNAME) std::array<int, 4> mib{ CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME }; std::size_t size = MAXPATHLEN; result.resize(size, '\0'); if (sysctl(mib.data(), 4, &result[0], &size, nullptr, 0) < 0) throw std::runtime_error(std::strerror(errno)); result.resize(size, '\0'); #else result.resize(2048, '\0'); auto size = readlink("/proc/curproc/exe", &result[0], 2048); if (size < 0) throw std::runtime_error(std::strerror(errno)); result.resize(size, '\0'); #endif return result; } #elif defined(__OpenBSD__) std::string executable() { char **paths, *path; std::string result; std::size_t len; std::array<int, 4> mib{ CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV }; if (sysctl(mib.data(), 4, nullptr, &len, nullptr, 0) == -1) throw std::runtime_error(std::strerror(errno)); if ((paths = static_cast<char **>(malloc(len))) == nullptr) throw std::runtime_error(std::strerror(errno)); sysctl(mib.data(), 4, paths, &len, nullptr, 0); if ((path = static_cast<char *>(std::malloc(PATH_MAX + 1))) == nullptr) { std::free(paths); throw std::runtime_error(std::strerror(errno)); } realpath(paths[0], path); result = path; std::free(paths); std::free(path); return result; } #else std::string executable() { // Not supported. return ""; } #endif