Line data Source code
1 : /**
2 : * POSIX path implementation.
3 : * Uses $HOME / $XDG_CACHE_HOME / $XDG_CONFIG_HOME / $XDG_DATA_HOME,
4 : * falling back to getpwuid(getuid()) for the home directory.
5 : */
6 : #include "../path.h"
7 : #include <stdlib.h>
8 : #include <stdio.h>
9 : #include <string.h>
10 : #include <pwd.h>
11 : #include <unistd.h>
12 : #include <sys/types.h>
13 : #ifdef __APPLE__
14 : #include <mach-o/dyld.h>
15 : #endif
16 :
17 : static char g_home[4096];
18 : static char g_cache[8192];
19 : static char g_config[8192];
20 : static char g_data[8192];
21 :
22 3404 : const char *platform_home_dir(void) {
23 3404 : const char *h = getenv("HOME");
24 3404 : if (!h || !*h) {
25 0 : struct passwd *pw = getpwuid(getuid());
26 0 : if (pw) h = pw->pw_dir;
27 : }
28 3404 : if (!h) return NULL;
29 3404 : snprintf(g_home, sizeof(g_home), "%s", h);
30 3404 : return g_home;
31 : }
32 :
33 795 : const char *platform_cache_dir(void) {
34 795 : const char *xdg = getenv("XDG_CACHE_HOME");
35 795 : if (xdg && *xdg) {
36 118 : snprintf(g_cache, sizeof(g_cache), "%s", xdg);
37 118 : return g_cache;
38 : }
39 677 : const char *home = platform_home_dir();
40 677 : if (!home) return NULL;
41 677 : snprintf(g_cache, sizeof(g_cache), "%s/.cache", home);
42 677 : return g_cache;
43 : }
44 :
45 1353 : const char *platform_config_dir(void) {
46 1353 : const char *xdg = getenv("XDG_CONFIG_HOME");
47 1353 : if (xdg && *xdg) {
48 208 : snprintf(g_config, sizeof(g_config), "%s", xdg);
49 208 : return g_config;
50 : }
51 1145 : const char *home = platform_home_dir();
52 1145 : if (!home) return NULL;
53 1145 : snprintf(g_config, sizeof(g_config), "%s/.config", home);
54 1145 : return g_config;
55 : }
56 :
57 1757 : const char *platform_data_dir(void) {
58 1757 : const char *xdg = getenv("XDG_DATA_HOME");
59 1757 : if (xdg && *xdg) {
60 180 : snprintf(g_data, sizeof(g_data), "%s", xdg);
61 180 : return g_data;
62 : }
63 1577 : const char *home = platform_home_dir();
64 1577 : if (!home) return NULL;
65 1577 : snprintf(g_data, sizeof(g_data), "%s/.local/share", home);
66 1577 : return g_data;
67 : }
68 :
69 1 : int platform_executable_path(char *buf, size_t size) {
70 1 : if (!buf || size == 0) return -1;
71 : #ifdef __linux__
72 1 : ssize_t n = readlink("/proc/self/exe", buf, size - 1);
73 1 : if (n > 0) { buf[n] = '\0'; return 0; }
74 0 : return -1;
75 : #elif defined(__APPLE__)
76 : uint32_t len = (uint32_t)size;
77 : if (_NSGetExecutablePath(buf, &len) == 0) return 0;
78 : return -1;
79 : #else
80 : /* Generic POSIX fallback: try /proc/curproc/file (FreeBSD) */
81 : ssize_t n = readlink("/proc/curproc/file", buf, size - 1);
82 : if (n > 0) { buf[n] = '\0'; return 0; }
83 : return -1;
84 : #endif
85 : }
|