Rahul Jain wrote:
>
> I am all for adding options to makefile(s) to build Xerces-C in different
> ways as long as these are non-breaking changes. The other issues we have
> to address while talking about static Xerces-C libraries are:
> * what value will be assigned to fgLibLocation
> * what is the fallback logic of discovering the ICU converter files.
> These issues are only relevant in the context of the using ICU and become
> non-issues if native transcoding option is used.
Righto. I don't want to go round breaking ICU so I'll leave this aspect
alone for now.
>
> Coming back to fixing the problem of 'panic' when the dynamically
> loaded Xerces-C library is installed in system default places like
> '/lib' and '/usr/lib', we should augument the code to look into these
> directories in addition to the values specified for LD_LIBRARY_PATH.
>
> A still better solution is to figure out how we can find out the
> loaded libraries via a system call (like we currently do under Solaris, AIX
> and HPUX).
The Linux dlopen man page states that libraries are searched for in
A colon-separated list of directories in the user's
LD_LIBRARY path environment variable.
The list of libraries specified in
/etc/ld.so.cache.
/usr/lib, followed by /lib.
but I've not found a reference to any way to get Linux to tell us what
libraries it's currently got loaded. Here's a (slightly longwinded)
patch which follows dlopen's behaviour in searching for the shared
library:
diff -u -u -r1.3 LinuxPlatformUtils.cpp
--- LinuxPlatformUtils.cpp 1999/11/23 02:00:48 1.3
+++ LinuxPlatformUtils.cpp 1999/12/09 14:28:28
@@ -209,49 +209,122 @@
char* libEnvVar = getenv(sharedLibEnvVar);
char* libPath = NULL;
- if (libEnvVar == NULL)
+ if (libEnvVar != NULL)
{
- panic(XMLPlatformUtils::Panic_CantFindLib);
- }
+ //
+ // Its necessary to create a copy because strtok() modifies the
+ // string as it returns tokens. We don't want to modify the
string
+ // returned to by getenv().
+ //
- //
- // Its necessary to create a copy because strtok() modifies the
- // string as it returns tokens. We don't want to modify the string
- // returned to by getenv().
- //
+ libPath = new char[strlen(libEnvVar) + 1];
+ strcpy(libPath, libEnvVar);
- libPath = new char[strlen(libEnvVar) + 1];
- strcpy(libPath, libEnvVar);
+ // First do the searching process for the first directory
listing
+ char* allPaths = libPath;
+ char* libPathName;
- // First do the searching process for the first directory listing
+ while ((libPathName = strtok(allPaths, ":")) != NULL)
+ {
+ FILE* dummyFptr = 0;
+ allPaths = 0;
- char* allPaths = libPath;
- char* libPathName;
+ char* libfile = new char[strlen(libPathName) +
strlen(libName) + 2];
+ strcpy(libfile, libPathName);
+ strcat(libfile, "/");
+ strcat(libfile, libName);
+
+ dummyFptr = (FILE *) fopen(libfile, "rb");
+ delete [] libfile;
+ if (dummyFptr != NULL)
+ {
+ fclose(dummyFptr);
+ libraryPath = new char[strlen(libPathName)+1];
+ strcpy((char *) libraryPath, libPathName);
+ break;
+ }
- while ((libPathName = strtok(allPaths, ":")) != NULL)
- {
- FILE* dummyFptr = 0;
- allPaths = 0;
+ } // while
- char* libfile = new char[strlen(libPathName) + strlen(libName)
+ 2];
- strcpy(libfile, libPathName);
- strcat(libfile, "/");
- strcat(libfile, libName);
-
- dummyFptr = (FILE *) fopen(libfile, "rb");
- delete [] libfile;
- if (dummyFptr != NULL)
- {
- fclose(dummyFptr);
- libraryPath = new char[strlen(libPathName)+1];
- strcpy((char *) libraryPath, libPathName);
- break;
- }
+ delete libPath;
+ }
- } // while
+ // If we've not found it in LD_LIBRARY_PATH, check
+ // locations specified in /etc/ld.so.conf
+
+ if(libraryPath == NULL)
+ {
+ FILE* ldsoconf = fopen("/etc/ld.so.conf", "r");
+ if(ldsoconf != NULL)
+ {
+ // Read lines specifying directories to search
+
+ char libPathName[256];
+ while(fgets(libPathName, 256, ldsoconf) != NULL)
+ {
+ // Chop off newline if present
+ char *newline = strrchr(libPathName, '\n');
+ if(newline != NULL)
+ *newline = '\0';
+
+ char* libfile = new char[strlen(libPathName) +
strlen(libName) + 2];
+ strcpy(libfile, libPathName);
+ strcat(libfile, "/");
+ strcat(libfile, libName);
+
+ FILE* dummyFptr = (FILE *) fopen(libfile, "rb");
+ delete [] libfile;
+ if (dummyFptr != NULL)
+ {
+ fclose(dummyFptr);
+ libraryPath = new char[strlen(libPathName)+1];
+ strcpy((char *) libraryPath, libPathName);
+ break;
+ }
+ } // while
+
+ fclose(ldsoconf);
+ }
+ }
+
+ // Finally check /usr/lib and then /lib
- delete libPath;
+ if(libraryPath == NULL)
+ {
+ char* libPathName = "/usr/lib";
+ char* libfile = new char[strlen(libPathName) + strlen(libName)
+ 2];
+ strcpy(libfile, libPathName);
+ strcat(libfile, "/");
+ strcat(libfile, libName);
+
+ FILE* dummyFptr = (FILE *) fopen(libfile, "rb");
+ delete [] libfile;
+ if (dummyFptr != NULL)
+ {
+ fclose(dummyFptr);
+ libraryPath = new char[strlen(libPathName)+1];
+ strcpy((char *) libraryPath, libPathName);
+ }
+ else
+ {
+ // Finally(!) check /lib
+ char* libPathName = "/lib";
+ char* libfile = new char[strlen(libPathName) +
strlen(libName) + 2];
+ strcpy(libfile, libPathName);
+ strcat(libfile, "/");
+ strcat(libfile, libName);
+
+ FILE* dummyFptr = (FILE *) fopen(libfile, "rb");
+ delete [] libfile;
+ if (dummyFptr != NULL)
+ {
+ fclose(dummyFptr);
+ libraryPath = new char[strlen(libPathName)+1];
+ strcpy((char *) libraryPath, libPathName);
+ }
+ }
+ }
XMLPlatformUtils::fgLibLocation = libraryPath;
Seems to work okay on my system, with the libray in LD_LIBRARY_PATH, in
an /etc/ld.so.conf specified directory, and with the library in /lib. I
hope the indentation and coding style is as expected -- is there an
Apache group spec for this?
Someone'll hit us with the Right Way to do this now... ;)
Best regards,
Mike.
--
Mike Mason, Software Engineer
XML Script Development Team Office: 44-1865-203192
http://www.xmlscript.org/ Mobile: 44-7050-288923