Mercurial > repos > blastem
diff util.c @ 496:6fc71114d145
Extract function to determine executable directory from load_config so it can be used elsewhere
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Mon, 28 Oct 2013 21:48:46 -0700 |
parents | 39cad98d2789 |
children | 32da1e0d5e55 |
line wrap: on
line diff
--- a/util.c Mon Oct 28 19:37:30 2013 -0700 +++ b/util.c Mon Oct 28 21:48:46 2013 -0700 @@ -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 @@ *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; +}