diff options
author | Niklas Hallqvist <niklas@cvs.openbsd.org> | 2003-07-02 08:18:04 +0000 |
---|---|---|
committer | Niklas Hallqvist <niklas@cvs.openbsd.org> | 2003-07-02 08:18:04 +0000 |
commit | c7495ea8858ea103edd6c4e8907eb2853fc89b6b (patch) | |
tree | 98ee02e54a44ca3f9c0c83c25ceb056ec3f8ded5 /libexec | |
parent | cae5ac552c9570cac8d94c9395014e06609c779a (diff) |
Correct library search algorithm, wrt versioned objects
Diffstat (limited to 'libexec')
-rw-r--r-- | libexec/ld.so/library.c | 58 | ||||
-rw-r--r-- | libexec/ld.so/library_mquery.c | 58 |
2 files changed, 72 insertions, 44 deletions
diff --git a/libexec/ld.so/library.c b/libexec/ld.so/library.c index 4d6e20aa1f4..9d515878393 100644 --- a/libexec/ld.so/library.c +++ b/libexec/ld.so/library.c @@ -1,4 +1,4 @@ -/* $OpenBSD: library.c,v 1.29 2003/06/22 21:39:01 drahn Exp $ */ +/* $OpenBSD: library.c,v 1.30 2003/07/02 08:18:03 niklas Exp $ */ /* * Copyright (c) 2002 Dale Rahn @@ -84,16 +84,16 @@ _dl_match_file(struct sod *sodp, char *name, int namelen) 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 @@ _dl_find_shlib(struct sod *sodp, const char *searchpath, int nohints) 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,46 @@ nohints: 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 == -1 || + 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); + if (tsod.sod_major == -1) + break; } - _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 */ diff --git a/libexec/ld.so/library_mquery.c b/libexec/ld.so/library_mquery.c index 888903559b1..6224e5a5417 100644 --- a/libexec/ld.so/library_mquery.c +++ b/libexec/ld.so/library_mquery.c @@ -1,4 +1,4 @@ -/* $OpenBSD: library_mquery.c,v 1.9 2003/06/22 21:39:01 drahn Exp $ */ +/* $OpenBSD: library_mquery.c,v 1.10 2003/07/02 08:18:03 niklas Exp $ */ /* * Copyright (c) 2002 Dale Rahn @@ -84,16 +84,16 @@ _dl_match_file(struct sod *sodp, char *name, int namelen) 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 @@ _dl_find_shlib(struct sod *sodp, const char *searchpath, int nohints) 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,46 @@ nohints: 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 == -1 || + 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); + if (tsod.sod_major == -1) + break; } - _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 */ |