Last active
October 24, 2017 06:20
-
-
Save lenary/f819aba7a36127568666b68b5ec5de63 to your computer and use it in GitHub Desktop.
Simple Utility to find the path to a dynamic library on your system (by name)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <dlfcn.h> | |
#include <stdio.h> | |
#include <stdbool.h> | |
#include <string.h> | |
#ifdef __APPLE__ | |
#include <mach-o/dyld.h> | |
#else // Linux | |
#include <link.h> | |
#endif | |
// So much of this is borrowed from Julia, here: | |
// https://github.com/JuliaLang/julia/blob/0027ed143e90d0f965694de7ea8c692d75ffa1a5/src/sys.c#L565-L626 | |
const char *dlpath(void *handle) { | |
const char *path = NULL; | |
#ifdef __APPLE__ | |
for (int32_t i = _dyld_image_count(); i >= 0 ; i--) { | |
bool found = FALSE; | |
const char *probe_path = _dyld_get_image_name(i); | |
void *probe_handle = dlopen(probe_path, RTLD_NOW | RTLD_LOCAL | RTLD_NOLOAD); | |
if (handle == probe_handle) { | |
found = TRUE; | |
path = probe_path; | |
} | |
dlclose(probe_handle); | |
if (found) | |
break; | |
} | |
#else // Linux | |
struct link_map *map; | |
dlinfo(handle, RTLD_DI_LINKMAP, &map); | |
if (map) | |
path = map->l_name; | |
#endif | |
return path; | |
} | |
int main(int argc, const char ** argv) | |
{ | |
if (argc != 2 || argc != 3) { | |
fprintf(stderr, "Usage: %s [ <libfirst.dylib> ] <libfind.dylib>\n", argv[0]); | |
fprintf(stderr, "Prints filesystem path to libfind.dylib (maybe loading libfirst.dylib first)\n"); | |
return 1; | |
} | |
const char *load_name = argv[1]; | |
const char *find_name = argv[2] ? argv[2] : load_name; | |
void *load_handle = dlopen(load_name, RTLD_NOW | RTLD_LOCAL); | |
void *find_handle = dlopen(find_name, RTLD_NOW | RTLD_LOCAL | RTLD_NOLOAD); | |
if (!find_handle) { | |
fprintf(stderr, "Could Not Open find lirbary: %s\n", dlerror()); | |
dlclose(load_handle); | |
return 1; | |
} | |
const char *find_path = dlpath(find_handle); | |
if (find_path) { | |
printf("%s: %s\n", find_name, find_path); | |
} else { | |
fprintf(stderr, "%s not found\n", find_name); | |
} | |
dlclose(find_handle); | |
dlclose(load_handle); | |
return !find_path; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment