void* dllopen(const char* name, int mode) { void* dll; Dllinfo_t* info; char* olibpath; char* path; char* oenv; char* nenv[2]; char* dir; char* base; int len; if (!environ) { nenv[0] = nenv[1] = 0; environ = nenv; } info = dllinfo(); oenv = environ[0]; olibpath = getenv(info->env); if (base = strrchr(name, '/')) { dir = (char*)name; len = ++base - dir; } else { dir = "./"; len = 2; base = (char*)name; } path = sfprints("%-.*s%s%c%s=%-.*s%s%s", len, dir, base, 0, info->env, len, dir, olibpath ? ":" : "", olibpath ? olibpath : ""); environ[0] = path + strlen(path) + 1; state.error = 0; dll = dlopen(path, mode); if (environ == nenv) environ = 0; else environ[0] = oenv; return dll; }
int b_dlls(int argc, char** argv, Shbltin_t* context) { int i; int r; int flags; int only; unsigned long ver; char** syms; char* arg[3]; void* dll; void* sym; Dllscan_t* dls; Dllent_t* dle; Dllinfo_t* dli; cmdinit(argc, argv, context, ERROR_CATALOG, 0); flags = 0; only = 0; for (;;) { switch (optget(argv, usage)) { case 0: break; case 'b': flags |= LIST_BASE; continue; case 'c': only = 1; continue; case 'i': flags |= LIST_INFO; continue; case 'l': flags |= LIST_LONG; continue; case 'p': flags |= LIST_PATH; continue; case ':': error(2, "%s", opt_info.arg); continue; case '?': error(ERROR_usage(2), "%s", opt_info.arg); continue; } break; } argv += opt_info.index; if (error_info.errors) error(ERROR_usage(2), "%s", optusage(NiL)); r = 0; if (flags & LIST_INFO) { if (!(dli = dllinfo())) error(2, "cannot determine native dll info"); sfprintf(sfstdout, "sibling=(%s", dli->sibling[0]); for (i = 1; dli->sibling[i]; i++) sfprintf(sfstdout, " %s", dli->sibling[i]); sfprintf(sfstdout, ") env=%s prefix=%s suffix=%s flags=", dli->env, dli->prefix, dli->suffix); i = 0; if (dli->flags & DLL_INFO_PREVER) { i = 1; sfprintf(sfstdout, "PREVER"); } if (dli->flags & DLL_INFO_DOTVER) { if (i) sfputc(sfstdout, '|'); sfprintf(sfstdout, "DOTVER"); } sfputc(sfstdout, '\n'); } else if (!(flags & (LIST_BASE|LIST_PATH))) flags |= LIST_BASE|LIST_PATH; if (flags &= (LIST_BASE|LIST_PATH|LIST_LONG)) { for (i = 0; i < elementsof(arg); i++) if (arg[i] = *argv) argv++; if (only && !*argv) error(ERROR_usage(2), "%s", optusage(NiL)); r = 1; for (;;) { if (dls = dllsopen(arg[0], arg[1], arg[2])) { while (dle = dllsread(dls)) { r = 0; if (!only) { if (!(flags & LIST_LONG)) dll = 0; else if (dll = dlopen(dle->path, RTLD_LAZY)) ver = dllversion(dll, NiL); else ver = 0; switch (flags) { case LIST_BASE: sfprintf(sfstdout, "%s\n", dle->name); break; case LIST_BASE|LIST_LONG: sfprintf(sfstdout, "%14s %08lu\n", dle->name, ver); break; case LIST_PATH|LIST_LONG: sfprintf(sfstdout, "%08lu %s\n", ver, dle->path); break; case LIST_PATH: sfprintf(sfstdout, "%s\n", dle->path); break; case LIST_BASE|LIST_PATH: sfprintf(sfstdout, "%14s %s\n", dle->name, dle->path); break; default: sfprintf(sfstdout, "%14s %08lu %s\n", dle->name, ver, dle->path); break; } if (*(syms = argv)) { if (dll || (dll = dlopen(dle->path, RTLD_LAZY))) { do { sfprintf(sfstdout, " %14s ", *syms); if (sym = dlllook(dll, *syms)) sfprintf(sfstdout, "%p\n", sym); else sfprintf(sfstdout, "%s\n", dlerror()); } while (*++syms); dlclose(dll); } else sfprintf(sfstdout, " %s\n", dlerror()); } } else if (dll = dlopen(dle->path, RTLD_LAZY)) { i = 1; for (syms = argv; *syms; syms++) if (sym = dlllook(dll, *syms)) { if (i) { i = 0; switch (flags) { case LIST_BASE: sfprintf(sfstdout, "%s\n", dle->name); break; case LIST_PATH: sfprintf(sfstdout, "%s\n", dle->path); break; default: sfprintf(sfstdout, "%14s %s\n", dle->name, dle->path); break; } } sfprintf(sfstdout, " %14s %p\n", *syms, sym); } dlclose(dll); } } dllsclose(dls); } if (!r || !arg[0] || streq(arg[0], "-") || !arg[1] || streq(arg[1], "-")) break; arg[0] = 0; } } return r || error_info.errors; }