]> git.draconx.ca Git - gentoo-fixes.git/blob - sys-apps/man/files/man-1.6c-cut-duplicate-manpaths.patch
sys-apps/man: Fix borken Gentoo man-1.6g-echo-escape.patch
[gentoo-fixes.git] / sys-apps / man / files / man-1.6c-cut-duplicate-manpaths.patch
1 http://bugs.gentoo.org/90186
2
3 If we have entries in MANPATH that are really symlinks to other entries,
4 then many man functions will yield duplicate entries.
5
6 Without this patch, we see this behavior:
7 $ echo $MANPATH
8 /usr/share/man:/usr/man
9 $ man --path
10 /usr/share/man:/usr/man
11 $ ls -ld /usr/share/man /usr/man
12 lrwxrwxrwx  1 /usr/man -> /usr/share/man
13 drwxr-xr-x 36 /usr/share/man
14 $ man -k passwd
15 passwd               (1)  - change user password
16 passwd               (1)  - change user password
17
18 With this patch, we get:
19 $ echo $MANPATH
20 /usr/share/man:/usr/man
21 $ man --path
22 /usr/share/man
23 $ ls -ld /usr/share/man /usr/man
24 lrwxrwxrwx  1 /usr/man -> /usr/share/man
25 drwxr-xr-x 36 /usr/share/man
26 $ man -k passwd
27 passwd               (1)  - change user password
28
29 --- man-1.6c/src/manpath.c
30 +++ man-1.6c/src/manpath.c
31 @@ -380,6 +380,44 @@
32       }
33  }
34  
35 +void trim_symlinked_manpaths (void);
36 +void
37 +trim_symlinked_manpaths () {
38 +       /*
39 +        * Skip symlinks to other entries in path.
40 +        * Do this after we've built the entire list.
41 +        */
42 +       struct stat *stat_cache;
43 +       size_t i, j, size;
44 +
45 +       if (!mandirlist)
46 +               return;
47 +
48 +       for (size = 0; mandirlist[size]; ++size)
49 +               /* count # of elements */;
50 +       if (size == 0)
51 +               return;
52 +       /* cache stat information for every element */
53 +       stat_cache = (struct stat *) my_malloc (size * sizeof(*stat_cache));
54 +       for (i = 0; i < size; ++i)
55 +               stat(mandirlist[i], &stat_cache[i]);
56 +
57 +#define EQU_STAT(s,d) ((s).st_dev == (d).st_dev && (s).st_ino == (d).st_ino)
58 +       for (i = 0; i < size; ++i) {
59 +               for (j = i+1; j < size; ++j) {
60 +                       if (EQU_STAT(stat_cache[i], stat_cache[j])) {
61 +                               /* these two entries are the same, so cut out the second one */
62 +                               memmove(mandirlist+j, mandirlist+j+1, (size-j)*sizeof(*mandirlist));
63 +                               memmove(stat_cache+j, stat_cache+j+1, (size-j)*sizeof(*stat_cache));
64 +                               mandirlist[--size] = NULL;
65 +                               --j;
66 +                       }
67 +               }
68 +       }
69 +
70 +       free(stat_cache);
71 +}
72 +
73  void
74  init_manpath () {
75       static int done = 0;
76 @@ -391,6 +431,7 @@
77                (manp = getenv ("MANPATH")) == NULL)
78                manp = "";               /* default path */
79           split (manp, to_mandirlist, 0);
80 +         trim_symlinked_manpaths ();
81           done = 1;
82       }
83  }