11 * This function returns the absolute path to the executable it is running in.
13 * The implementation follows http://stackoverflow.com/a/933996/712014
15 * Returned value must be freed by the caller.
17 char *get_exe_path(const char *argv0) {
18 size_t destpath_size = 1024;
19 size_t tmp_size = 1024;
20 char *destpath = smalloc(destpath_size);
21 char *tmp = smalloc(tmp_size);
23 #if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
24 /* Linux and Debian/kFreeBSD provide /proc/self/exe */
25 #if defined(__linux__) || defined(__FreeBSD_kernel__)
26 const char *exepath = "/proc/self/exe";
27 #elif defined(__FreeBSD__)
28 const char *exepath = "/proc/curproc/file";
32 while ((linksize = readlink(exepath, destpath, destpath_size)) == (ssize_t)destpath_size) {
33 destpath_size = destpath_size * 2;
34 destpath = srealloc(destpath, destpath_size);
37 /* readlink() does not NULL-terminate strings, so we have to. */
38 destpath[linksize] = '\0';
44 /* argv[0] is most likely a full path if it starts with a slash. */
45 if (argv0[0] == '/') {
48 return sstrdup(argv0);
51 /* if argv[0] contains a /, prepend the working directory */
52 if (strchr(argv0, '/') != NULL) {
54 while ((retgcwd = getcwd(tmp, tmp_size)) == NULL && errno == ERANGE) {
55 tmp_size = tmp_size * 2;
56 tmp = srealloc(tmp, tmp_size);
58 if (retgcwd != NULL) {
60 sasprintf(&destpath, "%s/%s", tmp, argv0);
66 /* Fall back to searching $PATH (or _CS_PATH in absence of $PATH). */
67 char *path = getenv("PATH");
69 /* _CS_PATH is typically something like "/bin:/usr/bin" */
70 while (confstr(_CS_PATH, tmp, tmp_size) > tmp_size) {
71 tmp_size = tmp_size * 2;
72 tmp = srealloc(tmp, tmp_size);
74 sasprintf(&path, ":%s", tmp);
78 const char *component;
81 if ((component = strtok(str, ":")) == NULL)
85 sasprintf(&destpath, "%s/%s", component, argv0);
86 /* Of course this is not 100% equivalent to actually exec()ing the
88 if (access(destpath, X_OK) == 0) {
98 /* Last resort: maybe it’s in /usr/bin? */
99 return sstrdup("/usr/bin/i3-nagbar");