[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

A simpler shlib.c patch



There is definitely something fishy going on with findshlib in shlib.c

The test around line 278:
                        if (major != -1 && found_dot_a) { /* XXX */
                                free(path);
                                path = NULL;
                                found_dot_a = 0;
                        }
is bogus.

Assume a call such as  major=24; minor=-1; findshlib("foo", &major, &minor, 1);
take a directory with holds libfoo.a and libfoo.so.25.2

If you encounter libfoo.a first, the test will reset path, and you
won't find the library.

If you encounter libfoo.so.25.2 first, it won't pass the major number
equality test, so path will still be NULL by the time libfoo.a is 
encountered, and libfoo.a will be found.

There are several possible ways to solve the dilemma. I don't really
know which one is appropriate:
- assume that encountering ANY libfoo.so will cancel libfoo.a, even
if the major number doesn't match. In such a case, we need a flag that says
we found a libfoo.so.* and test that flag, instead of path == NULL for
libfoo.a.
- assume that only appropriate libfoo.so.* cancel libfoo.a.
In which case, no test is needed.


Looking more closely at /usr/src, I found *NO* instance of calling
findshlib with major != -1 and do_dot_a == 1.

I'm all for scraping that code... after all, libzoinx.a should only be used
if we don't find a .so that matches better right ? and cmpndewey() takes
care of all precedence problems already, if you look closely...

--- shlib.c.orig	Fri Jan 14 10:04:34 2000
+++ shlib.c	Fri Jan 14 11:57:58 2000
@@ -232,7 +232,7 @@ int	do_dot_a;
 	int		tmp[MAXDEWEY];
 	int		i;
 	int		len;
-	char		*lname, *path = NULL;
+	char		*lname;
 	int		major = *majorp, minor = *minorp;
 
 	len = strlen(name);
@@ -245,13 +245,11 @@ int	do_dot_a;
 	for (i = 0; i < n_search_dirs; i++) {
 		DIR		*dd = opendir(search_dirs[i]);
 		struct dirent	*dp;
-		int		found_dot_a = 0;
-		int		might_take_it;
+		char 		*path = NULL;
 
 		if (dd == NULL)
 			continue;
 
-		might_take_it = 0;
 		while ((dp = readdir(dd)) != NULL) {
 			int	n;
 
@@ -262,7 +260,6 @@ int	do_dot_a;
 					(dp->d_name+len)[1] == 'a') {
 
 				path = concat(search_dirs[i], "/", dp->d_name, 0);
-				found_dot_a = 1;
 			}
 
 			if (dp->d_namlen < len + 4)
@@ -275,25 +272,13 @@ int	do_dot_a;
 			if ((n = getdewey(tmp, dp->d_name+len+4)) == 0)
 				continue;
 
-			if (major != -1 && found_dot_a) { /* XXX */
-				free(path);
-				path = NULL;
-				found_dot_a = 0;
-			}
-
-			if (major == -1 && minor == -1) {
-				might_take_it = 1;
-			} else if (major != -1 && minor == -1) {
-				if (tmp[0] == major)
-					might_take_it = 1;
-			} else if (major != -1 && minor != -1) {
-				if (tmp[0] == major)
-					if (n == 1 || tmp[1] >= minor)
-						might_take_it = 1;
-			}
-
-			if (!might_take_it)
-				continue;
+			/* skip inappropriate versions. */
+			if (major != -1) {
+				if (tmp[0] != major)
+					continue;
+				if (n != 1 && minor != -1 && tmp[1] < minor)
+					continue;
+			} 
 
 			if (cmpndewey(tmp, n, dewey, ndewey) <= 0)
 				continue;
@@ -302,7 +287,6 @@ int	do_dot_a;
 			if (path)
 				free(path);
 			path = concat(search_dirs[i], "/", dp->d_name, 0);
-			found_dot_a = 0;
 			bcopy(tmp, dewey, sizeof(dewey));
 			ndewey = n;
 			*majorp = dewey[0];
@@ -310,12 +294,12 @@ int	do_dot_a;
 		}
 		closedir(dd);
 
-		if (found_dot_a || might_take_it)
+		if (path != NULL)
 			/*
 			 * There's a lib in this dir; take it.
 			 */
 			return path;
 	}
 
-	return path;
+	return NULL;
 }

-- 
	Marc Espie		
|anime, sf, juggling, unicycle, acrobatics, comics...
|AmigaOS, OpenBSD, C++, perl, Icon, PostScript...
| `real programmers don't die, they just get out of beta'