[PATCH v2] lsof: correct check for symbolic link

Thomas De Schampheleire patrickdepinguin+busybox at gmail.com
Fri Jun 21 05:52:20 UTC 2013


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.

With this patch, the symbolic link check is done with lstat and a subsequent
S_ISLNK check, if the d_type field does not contain useful information.
If neither works, ignore 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 at gmail.com>

---
v2: avoid lstat overhead when possible

 procps/lsof.c |  22 +++++++++++++++++-----
 1 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/procps/lsof.c b/procps/lsof.c
--- a/procps/lsof.c
+++ b/procps/lsof.c
@@ -61,12 +61,24 @@ int lsof_main(int argc UNUSED_PARAM, cha
 		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);
-					printf("%d\t%s\t%s\n", proc->pid, proc->exe, fdlink);
-					free(fdlink);
+				safe_strncpy(name + baseofs, entry->d_name, 10);
+
+				if (entry->d_type == DT_UNKNOWN) {
+					struct stat st;
+
+					if (lstat(name, &st) != 0)
+						continue;
+
+					if (!S_ISLNK(st.st_mode))
+						continue;
+
+				} else if (entry->d_type != DT_LNK) {
+						continue;
 				}
+
+				fdlink = xmalloc_readlink(name);
+				printf("%d\t%s\t%s\n", proc->pid, proc->exe, fdlink);
+				free(fdlink);
 			}
 			closedir(d_fd);
 		}


More information about the busybox mailing list