Mercurial > code
view modules/executable/executable.cpp @ 617:266f32919d0a
Misc: update copyright headers, closes #686
author | David Demelier <markand@malikania.fr> |
---|---|
date | Mon, 21 Aug 2017 11:49:11 +0200 |
parents | 47f003c55e1e |
children | da9c2e128cae |
line wrap: on
line source
/* * executable.cpp -- get executable path * * Copyright (c) 2016-2017 David Demelier <markand@malikania.fr> * * 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 appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include <string> #include <stdexcept> #if defined(__linux__) # include <unistd.h> # include <cerrno> # include <climits> # include <cstring> #elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__) || defined(__OpenBSD__) # if defined(__NetBSD__) # include <sys/param.h> # include <unistd.h> # else # include <sys/types.h> # endif # if defined(__OpenBSD__) # include <unistd.h> # endif # include <sys/sysctl.h> # include <cerrno> # include <climits> # include <cstddef> # include <cstdlib> # include <cstring> #elif defined(__APPLE__) # include <cerrno> # include <cstring> # include <libproc.h> # include <unistd.h> #elif defined(_WIN32) # include <Windows.h> #endif std::string executable_path() { std::string result; #if defined(__linux__) char path[PATH_MAX + 1] = {0}; if (readlink("/proc/self/exe", path, sizeof (path) - 1) < 0) throw std::runtime_error(std::strerror(errno)); result = path; #elif defined(__FreeBSD__) || defined(__DragonFly__) int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 }; char path[PATH_MAX + 1] = {0}; size_t size = PATH_MAX; if (sysctl(mib, 4, path, &size, nullptr, 0) < 0) throw std::runtime_error(std::strerror(errno)); result = path; #elif defined(__APPLE__) char path[PROC_PIDPATHINFO_MAXSIZE + 1] = {0}; if ((proc_pidpath(getpid(), path, sizeof (path) - 1) == 0) throw std::runtime_error(std::strerror(errno)); result = path; #elif defined(_WIN32) char path[PATH_MAX + 1] = {0}; if (GetModuleFileNameA(nullptr, path, sizeof (path) - 1) == 0) throw std::runtime_error("GetModuleFileName error"); result = path; #elif defined(__NetBSD__) char path[4096 + 1] = {0}; # if defined(KERN_PROC_PATHNAME) int mib[] = { CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME }; int size = sizeof (path) - 1; if (sysctl(mib, 4, path, &size, nullptr, 0) < 0) throw std::runtime_error(std::strerror(errno)); # else if (readlink("/proc/curproc/exe", path, sizeof (path) - 1) < 0) throw std::runtime_error(std::strerror(errno)); # endif result = path; #elif defined(__OpenBSD__) char **paths, path[PATH_MAX + 1] = {0}; int mib[] = { CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV }; size_t length = 0; if (sysctl(mib, 4, 0, &length, 0, 0) < 0) throw std::runtime_error(std::strerror(errno)); if (!(paths = static_cast<char**>(std::malloc(length)))) throw std::runtime_error(std::strerror(errno)); if (sysctl(mib, 4, paths, &length, 0, 0) < 0) { std::free(paths); throw std::runtime_error(std::strerror(errno)); } realpath(paths[0], path); result = path; std::free(paths); #endif return result; }