lsof: correct check for symbolic link
authorThomas De Schampheleire <thomas.de.schampheleire@gmail.com>
Fri, 21 Jun 2013 19:27:56 +0000 (21:27 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Thu, 27 Jun 2013 01:44:46 +0000 (03:44 +0200)
Busybox lsof used the d_type field of a 'struct dirent' to verify whether the
entry is a symbolic link. This field, however, is not portable. On at least
one board [1] I have seen, that field is 0, and the check fails even though
the entry is a link.

The explicit check for a symbolic link is really only needed to skip the
default directory entries '.' and '..'. The directory /proc/<pid>/fd/
should not contain anything else but these two and symbolic links.
With these assumptions, this patch replaces the explicit link check with a
basic check for '.' and '..' (and any hidden file). In the unlikely case that
there are other file types, xmalloc_readlink() will return NULL, and we can
skip the entry.

[1] A MIPS-based board with glibc 2.9, Linux 2.6.32.27.

Signed-off-by: Thomas De Schampheleire <thomas.de.schampheleire@gmail.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
procps/lsof.c

index 7e0ffa4e5ecb6035ee0bbaec973b5f93eed5b145..b0156a538112510daba89b62e878941a610a088f 100644 (file)
@@ -61,9 +61,12 @@ int lsof_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
                d_fd = opendir(name);
                if (d_fd) {
                        while ((entry = readdir(d_fd)) != NULL) {
-                               if (entry->d_type == DT_LNK) {
-                                       safe_strncpy(name + baseofs, entry->d_name, 10);
-                                       fdlink = xmalloc_readlink(name);
+                               /* Skip entries '.' and '..' (and any hidden file) */
+                               if (entry->d_name[0] == '.')
+                                       continue;
+
+                               safe_strncpy(name + baseofs, entry->d_name, 10);
+                               if ((fdlink = xmalloc_readlink(name)) != NULL) {
                                        printf("%d\t%s\t%s\n", proc->pid, proc->exe, fdlink);
                                        free(fdlink);
                                }