diff options
author | Mike Pavone <pavone@retrodev.com> | 2013-10-28 21:48:46 -0700 |
---|---|---|
committer | Mike Pavone <pavone@retrodev.com> | 2013-10-28 21:48:46 -0700 |
commit | 94eea1e7324e6599decb73b78d13b111dd5b2621 (patch) | |
tree | 19dd4d605eccceba3b802089c7062b42fa13926c /util.c | |
parent | da665eb04a793552ed32ed8944dffbeb5220d7ae (diff) |
Extract function to determine executable directory from load_config so it can be used elsewhere
Diffstat (limited to 'util.c')
-rw-r--r-- | util.c | 74 |
1 files changed, 74 insertions, 0 deletions
@@ -3,6 +3,10 @@ #include <stdio.h> #include <ctype.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + char * alloc_concat(char * first, char * second) { int flen = strlen(first); @@ -63,3 +67,73 @@ char * split_keyval(char * text) *text = 0; return text+1; } + +static char * exe_str; + +void set_exe_str(char * str) +{ + exe_str = str; +} + +char * readlink_alloc(char * path) +{ + char * linktext = NULL; + ssize_t linksize = 512; + ssize_t cursize = 0; + do { + if (linksize > cursize) { + cursize = linksize; + if (linktext) { + free(linktext); + } + } + linktext = malloc(cursize); + linksize = readlink(path, linktext, cursize-1); + if (linksize == -1) { + perror("readlink"); + free(linktext); + linktext = NULL; + } + } while (linksize > cursize); + return linktext; +} + +char * get_exe_dir() +{ + static char * exe_dir; + if (!exe_dir) { + char * linktext = readlink_alloc("/proc/self/exe"); + if (!linktext) { + goto fallback; + } + char * cur; + int linksize = strlen(linktext); + for(cur = linktext + linksize - 1; cur != linktext; cur--) + { + if (*cur == '/') { + *cur = 0; + break; + } + } + if (cur == linktext) { + free(linktext); +fallback: + if (!exe_str) { + fputs("/proc/self/exe is not available and set_exe_str was not called!", stderr); + } + int pathsize = strlen(exe_str); + for(cur = exe_str + pathsize - 1; cur != exe_str; cur--) + { + if (*cur == '/') { + exe_dir = malloc(cur-exe_str+1); + memcpy(exe_dir, exe_str, cur-exe_str); + exe_dir[cur-exe_str] = 0; + break; + } + } + } else { + exe_dir = linktext; + } + } + return exe_dir; +} |