master
c 104 lines 2.37 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "libnetdata/libnetdata.h"
4
5 #if defined(OS_LINUX)
6 #include <unistd.h>
7
8 static char *os_get_process_path_internal(void) {
9 char path[PATH_MAX + 1] = "";
10 ssize_t len = readlink("/proc/self/exe", path, PATH_MAX);
11
12 if (len < 0) {
13 // Error occurred; errno is set
14 return NULL;
15 }
16
17 path[len] = '\0'; // readlink doesn't null terminate
18 return strdupz(path);
19 }
20 #endif
21
22 #if defined(OS_FREEBSD)
23 #include <sys/sysctl.h>
24
25 static char *os_get_process_path_internal(void) {
26 char path[PATH_MAX + 1] = "";
27 int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
28 size_t len = sizeof(path);
29
30 if (sysctl(mib, 4, path, &len, NULL, 0) == -1) {
31 // Error occurred; errno is set
32 return NULL;
33 }
34
35 return strdupz(path);
36 }
37 #endif
38
39 #if defined(OS_MACOS)
40 #include <mach-o/dyld.h>
41
42 static char *os_get_process_path_internal(void) {
43 char path[PATH_MAX + 1] = "";
44 uint32_t size = sizeof(path);
45
46 if (_NSGetExecutablePath(path, &size) != 0) {
47 // Buffer too small
48 return NULL;
49 }
50
51 // Resolve any symlinks to get the real path
52 char real_path[PATH_MAX + 1] = "";
53 if (!realpath(path, real_path)) {
54 // Error occurred; errno is set
55 return NULL;
56 }
57
58 return strdupz(real_path);
59 }
60 #endif
61
62 #if defined(OS_WINDOWS)
63 #include <windows.h>
64
65 static char *os_get_process_path_internal(void) {
66 wchar_t wpath[32768] = L""; // Maximum path length in Windows
67 DWORD length = GetModuleFileNameW(NULL, wpath, sizeof(wpath)/sizeof(wpath[0]));
68
69 if (length == 0) {
70 // GetModuleFileName failed
71 return NULL;
72 }
73
74 // Convert wide string to UTF-8
75 int utf8_len = WideCharToMultiByte(CP_UTF8, 0, wpath, -1, NULL, 0, NULL, NULL);
76 if (utf8_len == 0) {
77 // Conversion error
78 return NULL;
79 }
80
81 char *path = mallocz(utf8_len);
82 if (WideCharToMultiByte(CP_UTF8, 0, wpath, -1, path, utf8_len, NULL, NULL) == 0) {
83 // Conversion error
84 freez(path);
85 return NULL;
86 }
87
88 return path;
89 }
90 #endif
91
92 char *os_get_process_path(void) {
93 char b[FILENAME_MAX + 1];
94 size_t b_size = sizeof(b) - 1;
95 int ret = uv_exepath(b, &b_size);
96 if(ret == 0)
97 b[b_size] = '\0';
98
99 if (ret != 0 || access(b, R_OK) != 0)
100 return os_get_process_path_internal();
101
102 b[b_size] = '\0';
103 return strdupz(b);
104 }