|
Packit |
992a25 |
/***********************************************************************
|
|
Packit |
992a25 |
* *
|
|
Packit |
992a25 |
* This software is part of the ast package *
|
|
Packit |
992a25 |
* Copyright (c) 1997-2012 AT&T Intellectual Property *
|
|
Packit |
992a25 |
* and is licensed under the *
|
|
Packit |
992a25 |
* Eclipse Public License, Version 1.0 *
|
|
Packit |
992a25 |
* by AT&T Intellectual Property *
|
|
Packit |
992a25 |
* *
|
|
Packit |
992a25 |
* A copy of the License is available at *
|
|
Packit |
992a25 |
* http://www.eclipse.org/org/documents/epl-v10.html *
|
|
Packit |
992a25 |
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
|
|
Packit |
992a25 |
* *
|
|
Packit |
992a25 |
* Information and Software Systems Research *
|
|
Packit |
992a25 |
* AT&T Research *
|
|
Packit |
992a25 |
* Florham Park NJ *
|
|
Packit |
992a25 |
* *
|
|
Packit |
992a25 |
* Glenn Fowler <gsf@research.att.com> *
|
|
Packit |
992a25 |
* *
|
|
Packit |
992a25 |
***********************************************************************/
|
|
Packit |
992a25 |
#pragma prototyped
|
|
Packit |
992a25 |
/*
|
|
Packit |
992a25 |
* Glenn Fowler
|
|
Packit |
992a25 |
* AT&T Research
|
|
Packit |
992a25 |
*/
|
|
Packit |
992a25 |
|
|
Packit |
992a25 |
#include "dlllib.h"
|
|
Packit |
992a25 |
|
|
Packit |
992a25 |
/*
|
|
Packit |
992a25 |
* find and load lib plugin/module library name with optional version ver and dlopen() flags
|
|
Packit |
992a25 |
* at least one dlopen() is called to initialize dlerror()
|
|
Packit |
992a25 |
* if path!=0 then library path up to size chars copied to path with trailing 0
|
|
Packit |
992a25 |
* if name contains a directory prefix then library search is limited to the dir and siblings
|
|
Packit |
992a25 |
*/
|
|
Packit |
992a25 |
|
|
Packit |
992a25 |
extern void*
|
|
Packit |
992a25 |
dllplugin(const char* lib, const char* name, const char* ver, unsigned long rel, unsigned long* cur, int flags, char* path, size_t size)
|
|
Packit |
992a25 |
{
|
|
Packit |
992a25 |
void* dll;
|
|
Packit |
992a25 |
int err;
|
|
Packit |
992a25 |
int hit;
|
|
Packit |
992a25 |
Dllscan_t* dls;
|
|
Packit |
992a25 |
Dllent_t* dle;
|
|
Packit |
992a25 |
|
|
Packit |
992a25 |
err = hit = 0;
|
|
Packit |
992a25 |
for (;;)
|
|
Packit |
992a25 |
{
|
|
Packit |
992a25 |
if (dls = dllsopen(lib, name, ver))
|
|
Packit |
992a25 |
{
|
|
Packit |
992a25 |
while (dle = dllsread(dls))
|
|
Packit |
992a25 |
{
|
|
Packit |
992a25 |
hit = 1;
|
|
Packit |
992a25 |
#if 0
|
|
Packit |
992a25 |
again:
|
|
Packit |
992a25 |
#endif
|
|
Packit |
992a25 |
if (dll = dllopen(dle->path, flags|RTLD_GLOBAL|RTLD_PARENT))
|
|
Packit |
992a25 |
{
|
|
Packit |
992a25 |
if (!dllcheck(dll, dle->path, rel, cur))
|
|
Packit |
992a25 |
{
|
|
Packit |
992a25 |
err = state.error;
|
|
Packit |
992a25 |
dlclose(dll);
|
|
Packit |
992a25 |
dll = 0;
|
|
Packit |
992a25 |
continue;
|
|
Packit |
992a25 |
}
|
|
Packit |
992a25 |
if (path && size)
|
|
Packit |
992a25 |
strlcpy(path, dle->path, size);
|
|
Packit |
992a25 |
break;
|
|
Packit |
992a25 |
}
|
|
Packit |
992a25 |
else
|
|
Packit |
992a25 |
{
|
|
Packit |
992a25 |
#if 0
|
|
Packit |
992a25 |
/*
|
|
Packit |
992a25 |
* dlopen() should load implicit libraries
|
|
Packit |
992a25 |
* this code does that
|
|
Packit |
992a25 |
* but it doesn't help on galadriel
|
|
Packit |
992a25 |
*/
|
|
Packit |
992a25 |
|
|
Packit |
992a25 |
char* s;
|
|
Packit |
992a25 |
char* e;
|
|
Packit |
992a25 |
|
|
Packit |
992a25 |
if ((s = dllerror(1)) && (e = strchr(s, ':')))
|
|
Packit |
992a25 |
{
|
|
Packit |
992a25 |
*e = 0;
|
|
Packit |
992a25 |
error(1, "AHA %s implicit", s);
|
|
Packit |
992a25 |
dll = dllplugin(lib, s, 0, 0, 0, flags, path, size);
|
|
Packit |
992a25 |
*e = ':';
|
|
Packit |
992a25 |
if (dll)
|
|
Packit |
992a25 |
{
|
|
Packit |
992a25 |
error(1, "AHA implicit %s => %s", s, path);
|
|
Packit |
992a25 |
goto again;
|
|
Packit |
992a25 |
}
|
|
Packit |
992a25 |
}
|
|
Packit |
992a25 |
#endif
|
|
Packit |
992a25 |
errorf("dll", NiL, 1, "dllplugin: %s dlopen failed: %s", dle->path, dllerror(1));
|
|
Packit |
992a25 |
err = state.error;
|
|
Packit |
992a25 |
}
|
|
Packit |
992a25 |
}
|
|
Packit |
992a25 |
dllsclose(dls);
|
|
Packit |
992a25 |
}
|
|
Packit |
992a25 |
if (hit)
|
|
Packit |
992a25 |
{
|
|
Packit |
992a25 |
if (!dll)
|
|
Packit |
992a25 |
state.error = err;
|
|
Packit |
992a25 |
return dll;
|
|
Packit |
992a25 |
}
|
|
Packit |
992a25 |
if (!lib)
|
|
Packit |
992a25 |
break;
|
|
Packit |
992a25 |
lib = 0;
|
|
Packit |
992a25 |
}
|
|
Packit |
992a25 |
if (dll = dllopen(name, flags))
|
|
Packit |
992a25 |
{
|
|
Packit |
992a25 |
if (!dllcheck(dll, name, rel, cur))
|
|
Packit |
992a25 |
{
|
|
Packit |
992a25 |
dlclose(dll);
|
|
Packit |
992a25 |
dll = 0;
|
|
Packit |
992a25 |
}
|
|
Packit |
992a25 |
else if (path && size)
|
|
Packit |
992a25 |
strlcpy(path, name, size);
|
|
Packit |
992a25 |
}
|
|
Packit |
992a25 |
return dll;
|
|
Packit |
992a25 |
}
|
|
Packit |
992a25 |
|
|
Packit |
992a25 |
extern void*
|
|
Packit |
992a25 |
dllplug(const char* lib, const char* name, const char* ver, int flags, char* path, size_t size)
|
|
Packit |
992a25 |
{
|
|
Packit |
992a25 |
return dllplugin(lib, name, ver, 0, NiL, flags, path, size);
|
|
Packit |
992a25 |
}
|