This helps a bit with native java on ELF, at least I get to main now,
but there other problems later... For you working on other versions
try it.
I am surprised other ports have not depended on this, or maybe keep
their /usr/lib rather clean. The existing algorithm is quite
broken... major numbers are optional too (dlopen("libc.so") is quite ok),
It is broken both in specs and in implementation (i.e. the
implementation does not even implement the broken spec, as
getdirentries does not return files in the order assumed, and even if
it did, it would be lexicographical order, not numeric :-) )
Niklas
Index: library_mquery.c
RCS file: /cvs/src/libexec/ld.so/library_mquery.c,v
retrieving revision 1.9
diff -u -r1.9 library_mquery.c
--- library_mquery.c 22 Jun 2003 21:39:01 -0000 1.9
+++ library_mquery.c 26 Jun 2003 14:12:09 -0000
@@ -84,16 +84,16 @@
match = 0;
if ((_dl_strcmp((char *)lsod.sod_name, (char *)sodp->sod_name) == 0) &&
(lsod.sod_library == sodp->sod_library) &&
- (sodp->sod_major == lsod.sod_major) &&
+ ((sodp->sod_major == -1) || (sodp->sod_major == lsod.sod_major)) &&
((sodp->sod_minor == -1) ||
(lsod.sod_minor >= sodp->sod_minor))) {
match = 1;
/* return version matched */
+ sodp->sod_major = lsod.sod_major;
sodp->sod_minor = lsod.sod_minor;
}
_dl_free((char *)lsod.sod_name);
-
return match;
}
@@ -107,6 +107,7 @@
const char *pp;
int match, len;
DIR *dd;
+ struct sod tsod, bsod; /* transient and best sod */
/* if we are to search default directories, and hints
* are not to be used, search the standard path from ldconfig
@@ -167,33 +168,43 @@
if ((dd = _dl_opendir(lp)) != NULL) {
match = 0;
while ((dp = _dl_readdir(dd)) != NULL) {
- if (_dl_match_file(sodp, dp->d_name,
+ tsod = *sodp;
+ if (_dl_match_file(&tsod, dp->d_name,
dp->d_namlen)) {
/*
- * When a match is found, sodp is
- * updated with the minor found.
- * We continue looking at this
- * directory, thus this will find
- * the largest matching library
- * in this directory.
- * we save off the d_name now
- * so that it doesn't have to be
- * recreated from the hint.
+ * When a match is found, tsod is
+ * updated with the major+minor found.
+ * This version is compared with the
+ * largest so far (kept in bsod),
+ * and saved if larger.
*/
- match = 1;
- len = _dl_strlcpy(_dl_hint_store, lp,
- MAXPATHLEN);
- if (lp[len-1] != '/') {
- _dl_hint_store[len] = '/';
- len++;
+ if (!match ||
+ tsod.sod_major > bsod.sod_major ||
+ ((tsod.sod_major ==
+ bsod.sod_major) &&
+ tsod.sod_minor > bsod.sod_minor)) {
+ bsod = tsod;
+ match = 1;
+ len = _dl_strlcpy(
+ _dl_hint_store, lp,
+ MAXPATHLEN);
+ if (lp[len-1] != '/') {
+ _dl_hint_store[len] =
+ '/';
+ len++;
+ }
+ _dl_strlcpy(
+ &_dl_hint_store[len],
+ dp->d_name,
+ MAXPATHLEN-len);
}
- _dl_strlcpy(&_dl_hint_store[len],
- dp->d_name, MAXPATHLEN-len);
}
}
_dl_closedir(dd);
- if (match)
+ if (match) {
+ *sodp = bsod;
return (_dl_hint_store);
+ }
}
if (*pp) /* Try curdir if ':' at end */
Received on Thu Jun 26 10:35:50 2003
This archive was generated by hypermail 2.1.8
: Wed Aug 23 2006 - 13:45:02 EDT
|