comparison modules/executable/executable.cpp @ 616:47f003c55e1e

Executable: dedicate new module directory, closes #684
author David Demelier <markand@malikania.fr>
date Mon, 21 Aug 2017 11:40:55 +0200
parents misc/executable.cpp@beef249c796c
children 266f32919d0a
comparison
equal deleted inserted replaced
615:e8661a550a12 616:47f003c55e1e
1 /*
2 * executable.cpp -- get executable path
3 *
4 * Copyright (c) 2016 David Demelier <markand@malikania.fr>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include <string>
20 #include <stdexcept>
21
22 #if defined(__linux__)
23 # include <unistd.h>
24
25 # include <cerrno>
26 # include <climits>
27 # include <cstring>
28 #elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__) || defined(__OpenBSD__)
29 # if defined(__NetBSD__)
30 # include <sys/param.h>
31 # include <unistd.h>
32 # else
33 # include <sys/types.h>
34 # endif
35
36 # if defined(__OpenBSD__)
37 # include <unistd.h>
38 # endif
39
40 # include <sys/sysctl.h>
41
42 # include <cerrno>
43 # include <climits>
44 # include <cstddef>
45 # include <cstdlib>
46 # include <cstring>
47 #elif defined(__APPLE__)
48 # include <cerrno>
49 # include <cstring>
50 # include <libproc.h>
51 # include <unistd.h>
52 #elif defined(_WIN32)
53 # include <Windows.h>
54 #endif
55
56 std::string executable_path()
57 {
58 std::string result;
59
60 #if defined(__linux__)
61 char path[PATH_MAX + 1] = {0};
62
63 if (readlink("/proc/self/exe", path, sizeof (path) - 1) < 0)
64 throw std::runtime_error(std::strerror(errno));
65
66 result = path;
67 #elif defined(__FreeBSD__) || defined(__DragonFly__)
68 int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
69 char path[PATH_MAX + 1] = {0};
70 size_t size = PATH_MAX;
71
72 if (sysctl(mib, 4, path, &size, nullptr, 0) < 0)
73 throw std::runtime_error(std::strerror(errno));
74
75 result = path;
76 #elif defined(__APPLE__)
77 char path[PROC_PIDPATHINFO_MAXSIZE + 1] = {0};
78
79 if ((proc_pidpath(getpid(), path, sizeof (path) - 1) == 0)
80 throw std::runtime_error(std::strerror(errno));
81
82 result = path;
83 #elif defined(_WIN32)
84 char path[PATH_MAX + 1] = {0};
85
86 if (GetModuleFileNameA(nullptr, path, sizeof (path) - 1) == 0)
87 throw std::runtime_error("GetModuleFileName error");
88
89 result = path;
90 #elif defined(__NetBSD__)
91 char path[4096 + 1] = {0};
92
93 # if defined(KERN_PROC_PATHNAME)
94 int mib[] = { CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME };
95 int size = sizeof (path) - 1;
96
97 if (sysctl(mib, 4, path, &size, nullptr, 0) < 0)
98 throw std::runtime_error(std::strerror(errno));
99 # else
100 if (readlink("/proc/curproc/exe", path, sizeof (path) - 1) < 0)
101 throw std::runtime_error(std::strerror(errno));
102 # endif
103
104 result = path;
105 #elif defined(__OpenBSD__)
106 char **paths, path[PATH_MAX + 1] = {0};
107 int mib[] = { CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV };
108 size_t length = 0;
109
110 if (sysctl(mib, 4, 0, &length, 0, 0) < 0)
111 throw std::runtime_error(std::strerror(errno));
112 if (!(paths = static_cast<char**>(std::malloc(length))))
113 throw std::runtime_error(std::strerror(errno));
114 if (sysctl(mib, 4, paths, &length, 0, 0) < 0) {
115 std::free(paths);
116 throw std::runtime_error(std::strerror(errno));
117 }
118
119 realpath(paths[0], path);
120 result = path;
121
122 std::free(paths);
123 #endif
124
125 return result;
126 }