static int dl_pathbyaddr(void *addr, char *path, int sz) { struct shl_descriptor inf; int i, len; if (addr == NULL) { union { int (*f) (void *, char *, int); void *p; } t = { dl_pathbyaddr }; addr = t.p; } for (i = -1; shl_get_r(i, &inf) == 0; i++) { if (((size_t)addr >= inf.tstart && (size_t)addr < inf.tend) || ((size_t)addr >= inf.dstart && (size_t)addr < inf.dend)) { len = (int)strlen(inf.filename); if (sz <= 0) return len + 1; if (len >= sz) len = sz - 1; memcpy(path, inf.filename, len); path[len++] = 0; return len; } } return -1; }
int get_exec_path(char *exec_path, int len) { int ret; #ifdef LINUX ret = readlink("/proc/self/exe", exec_path, len); if (ret < 0) { fprintf(stderr, "readlink() failed. %d %s\n", errno, strerror(errno)); return -1; } exec_path[len - 1] = '\0'; return 0; #elif SUNOS const char *cmdp; char cwd[BUFSIZ], *cwdp; char *homep = getenv("HOME"); cmdp = getexecname(); if (cmdp != NULL) { if (homep != NULL) { if (strstr(cmdp, homep) == NULL) { cwdp = getcwd(cwd, sizeof(cwd)); if (cwdp == NULL) { fprintf(stderr, "getcwd() failed. %d %s\n", errno, strerror(errno)); return -1; } cwd[sizeof(cwd) - 1] = '\0'; snprintf(exec_path, len, "%s/%s", cwd, cmdp); } else { strncpy(exec_path, cmdp, len); exec_path[len - 1] = '\0'; } } else { fprintf(stderr, "warning: couldn't get $HOME\n"); snprintf(exec_path, len, "./%s\n", cmdp); } } else { fprintf(stderr, "getexecname() failed. %d %s\n", errno, strerror(errno)); return -1; } return 0; #elif HP_UX struct shl_descriptor desc; ret = shl_get_r(0, &desc); if (ret < 0) { fprintf(stderr, "shl_get_r() failed. %d %s\n", errno, strerror(errno)); return -1; } strncpy(exec_path, desc.filename, len); exec_path[len - 1] = '\0'; return 0; #else return -1; #endif }