blob: ac7f939f40cfb5192471eac18f62b07f0707f8bc [file] [log] [blame]
/*
* ======== gld.c ========
*
*! Revision History
*! ================
*! 17-Jan-2006 sasha updated per new RTSC types and headers
*! 06-Apr-2004 jgc: Added (_920T_LE_) to (_SUN_) and (_LINUX_)
*! #if defined preprocessor directives
*! 30-Nov-2001 jgc: Added defined(_LINUX_) to _SUN_ tests
*/
#include <xdc/std.h>
#include <string.h>
#if defined(xdc_target__os_Windows)
#include <windows.h>
#include <io.h> /* access() declaration */
#else
#include <dlfcn.h> /* dlopen() declarations */
#include <unistd.h> /* access() declaration */
#endif
#define GT_TRACE 0
#define GT_ASSERT 0
#include <gt.h>
#include "gld.h"
#define MAXNAME 1024
#if defined(xdc_target__os_Windows)
#define DIRSTRING "\\"
#define PATHSEP ";"
#else
#define DIRSTRING "/"
#define PATHSEP ":;"
#endif
static GT_Mask curTrace;
static Int curInit = 0;
static String searchPath = NULL;
static Bool findFile(String baseName, String searchPath, Char pathName[]);
static Int getDirLen(String dir);
/*
* ======== GLD_create ========
*/
Ptr GLD_create(String name)
{
Ptr lib;
Char tmpBuf[MAXNAME + 1];
GT_1trace(curTrace, GT_ENTER, "GLD_create(%s)\n", name);
/* if we can find the file ourselves, use this new path */
if (findFile(name, searchPath, tmpBuf)) {
name = tmpBuf;
}
#if defined(xdc_target__os_Windows)
/* Note that LoadLibrary will automatically add a ".dll" extension
* if name does not contain a "."; in addition, a name that ends
* with "." is assumed to *not* have an extension.
*/
lib = (Ptr)LoadLibrary(name);
#else
lib = dlopen(name, RTLD_LAZY);
#endif
return (lib);
}
/*
* ======== GLD_delete ========
*/
Void GLD_delete(Ptr lib)
{
GT_1trace(curTrace, GT_ENTER, "GLD_delete(0x%lx)\n", lib);
#if defined(xdc_target__os_Windows)
FreeLibrary(lib);
#else
dlclose(lib);
#endif
}
/*
* ======== GLD_exit ========
*/
Void GLD_exit(Void)
{
if (curInit-- == 1) {
GT_exit();
}
}
/*
* ======== GLD_getFxn ========
*/
Fxn GLD_getFxn(Ptr lib, String name)
{
Fxn fxn;
GT_2trace(curTrace, GT_ENTER, "GLD_getFxn(0x%lx, %s)\n", lib, name);
#if defined(xdc_target__os_Windows)
fxn = (Fxn)GetProcAddress(lib, name);
#else
fxn = (Fxn)dlsym(lib, name);
#endif
return (fxn);
}
/*
* ======== GLD_init ========
*/
Void GLD_init(Void)
{
if (curInit++ == 0) {
GT_init();
GT_create(&curTrace, "GD");
}
}
/*
* ======== GLD_setpath ========
*/
Void GLD_setpath(String path)
{
GT_1trace(curTrace, GT_ENTER, "GLD_setpath(%s)\n", path);
searchPath = path;
}
/*
* ======== findFile ========
* pathName *must* be a buffer of at least MAXNAME + 1 characters.
*/
static Bool findFile(String baseName, String searchPath, Char pathName[])
{
Int baseLen, dirLen;
String dir;
Bool status = FALSE;
#if !defined(xdc_target__os_Windows)
Char *cp;
Char tmpBaseName[MAXNAME + 1];
GT_3trace(curTrace, GT_1CLASS, "findFile(%s, %s, 0x%lx)\n",
baseName, searchPath == NULL ? "" : searchPath, pathName);
/* if a Windows dll name is passed in try the loading the unadorned
* name; otherwise, try loading name directly.
*/
if ((cp = strrchr(baseName, '.')) != NULL
&& (strcmp(cp, ".dll") == 0 || strcmp(cp, ".DLL") == 0) ) {
/* copy baseName to tmpBaseName */
strncpy(tmpBaseName, baseName, MAXNAME + 1);
tmpBaseName[MAXNAME] = '\0';
if ((cp = strrchr(tmpBaseName, '.')) != NULL) {
*cp = '\0';
}
/* use new name as the base name for path search */
baseName = tmpBaseName;
status = TRUE;
strcpy(pathName, baseName);
}
#endif
if (searchPath == NULL) {
return (status);
}
/* loop through searchPath trying each directory to locate baseName */
baseLen = strlen(baseName);
dir = searchPath;
while (dir[0] != '\0' && strchr(PATHSEP, dir[0]) != NULL) {
dir++;
}
for (dirLen = getDirLen(dir); dirLen != 0; dirLen = getDirLen(dir)) {
if ((dirLen + baseLen + 1) <= MAXNAME) {
memset(pathName, 0, MAXNAME);
strncpy(pathName, dir, dirLen);
strcat(pathName, DIRSTRING);
strcat(pathName, baseName);
/* if name is found, return success */
GT_1trace(curTrace, GT_1CLASS, "looking for %s ...\n", pathName);
if (access(pathName, 0) == 0) {
return (TRUE);
}
}
/* point dir to next directory path, skipping PATHSEP characters */
dir += dirLen;
while (dir[0] != '\0' && strchr(PATHSEP, dir[0]) != NULL) {
dir++;
}
}
return (FALSE);
}
/*
* ======== getDirLen ========
*/
static Int getDirLen(String dir)
{
String end;
if ((end = strpbrk(dir, PATHSEP)) == NULL) {
return (strlen(dir));
}
return (end - dir);
}