summaryrefslogtreecommitdiff
path: root/util.c
diff options
context:
space:
mode:
authorMike Pavone <pavone@retrodev.com>2013-10-28 21:48:46 -0700
committerMike Pavone <pavone@retrodev.com>2013-10-28 21:48:46 -0700
commit94eea1e7324e6599decb73b78d13b111dd5b2621 (patch)
tree19dd4d605eccceba3b802089c7062b42fa13926c /util.c
parentda665eb04a793552ed32ed8944dffbeb5220d7ae (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.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/util.c b/util.c
index c41547a..0b8d8cb 100644
--- a/util.c
+++ b/util.c
@@ -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;
+}