You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
84 lines
2.1 KiB
84 lines
2.1 KiB
13 years ago
|
http://bugs.gentoo.org/90186
|
||
|
|
||
|
If we have entries in MANPATH that are really symlinks to other entries,
|
||
|
then many man functions will yield duplicate entries.
|
||
|
|
||
|
Without this patch, we see this behavior:
|
||
|
$ echo $MANPATH
|
||
|
/usr/share/man:/usr/man
|
||
|
$ man --path
|
||
|
/usr/share/man:/usr/man
|
||
|
$ ls -ld /usr/share/man /usr/man
|
||
|
lrwxrwxrwx 1 /usr/man -> /usr/share/man
|
||
|
drwxr-xr-x 36 /usr/share/man
|
||
|
$ man -k passwd
|
||
|
passwd (1) - change user password
|
||
|
passwd (1) - change user password
|
||
|
|
||
|
With this patch, we get:
|
||
|
$ echo $MANPATH
|
||
|
/usr/share/man:/usr/man
|
||
|
$ man --path
|
||
|
/usr/share/man
|
||
|
$ ls -ld /usr/share/man /usr/man
|
||
|
lrwxrwxrwx 1 /usr/man -> /usr/share/man
|
||
|
drwxr-xr-x 36 /usr/share/man
|
||
|
$ man -k passwd
|
||
|
passwd (1) - change user password
|
||
|
|
||
|
--- man-1.6c/src/manpath.c
|
||
|
+++ man-1.6c/src/manpath.c
|
||
|
@@ -380,6 +380,44 @@
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+void trim_symlinked_manpaths (void);
|
||
|
+void
|
||
|
+trim_symlinked_manpaths () {
|
||
|
+ /*
|
||
|
+ * Skip symlinks to other entries in path.
|
||
|
+ * Do this after we've built the entire list.
|
||
|
+ */
|
||
|
+ struct stat *stat_cache;
|
||
|
+ size_t i, j, size;
|
||
|
+
|
||
|
+ if (!mandirlist)
|
||
|
+ return;
|
||
|
+
|
||
|
+ for (size = 0; mandirlist[size]; ++size)
|
||
|
+ /* count # of elements */;
|
||
|
+ if (size == 0)
|
||
|
+ return;
|
||
|
+ /* cache stat information for every element */
|
||
|
+ stat_cache = (struct stat *) my_malloc (size * sizeof(*stat_cache));
|
||
|
+ for (i = 0; i < size; ++i)
|
||
|
+ stat(mandirlist[i], &stat_cache[i]);
|
||
|
+
|
||
|
+#define EQU_STAT(s,d) ((s).st_dev == (d).st_dev && (s).st_ino == (d).st_ino)
|
||
|
+ for (i = 0; i < size; ++i) {
|
||
|
+ for (j = i+1; j < size; ++j) {
|
||
|
+ if (EQU_STAT(stat_cache[i], stat_cache[j])) {
|
||
|
+ /* these two entries are the same, so cut out the second one */
|
||
|
+ memmove(mandirlist+j, mandirlist+j+1, (size-j)*sizeof(*mandirlist));
|
||
|
+ memmove(stat_cache+j, stat_cache+j+1, (size-j)*sizeof(*stat_cache));
|
||
|
+ mandirlist[--size] = NULL;
|
||
|
+ --j;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ free(stat_cache);
|
||
|
+}
|
||
|
+
|
||
|
void
|
||
|
init_manpath () {
|
||
|
static int done = 0;
|
||
|
@@ -391,6 +431,7 @@
|
||
|
(manp = getenv ("MANPATH")) == NULL)
|
||
|
manp = ""; /* default path */
|
||
|
split (manp, to_mandirlist, 0);
|
||
|
+ trim_symlinked_manpaths ();
|
||
|
done = 1;
|
||
|
}
|
||
|
}
|