[PATCH 4/5] ls: detect infinite loop with recursivity

From: Quentin Rameau <quinq_AT_quinq.eu.org>
Date: Fri, 12 Jun 2015 20:03:04 +0200

populate an history of visited directories inodes and search it before
recursing
---
 ls.c | 48 +++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 45 insertions(+), 3 deletions(-)
diff --git a/ls.c b/ls.c
index e726a7e..bb44357 100644
--- a/ls.c
+++ b/ls.c
_AT_@ -21,9 +21,15 @@ struct entry {
 	gid_t   gid;
 	off_t   size;
 	time_t  t;
-	ino_t   ino;
+	dev_t   dev;
+	ino_t   ino, tino;
 };
 
+static struct {
+	dev_t dev;
+	ino_t ino;
+} tree[PATH_MAX] = { { 0, 0 } };
+
 static int Aflag = 0;
 static int aflag = 0;
 static int cflag = 0;
_AT_@ -69,9 +75,17 @@ mkent(struct entry *ent, char *path, int dostat, int follow)
 		ent->t = st.st_atime;
 	else
 		ent->t = st.st_mtime;
+	ent->dev   = st.st_dev;
 	ent->ino   = st.st_ino;
-	if (S_ISLNK(ent->mode))
-		ent->tmode = stat(path, &st) == 0 ? st.st_mode : 0;
+	if (S_ISLNK(ent->mode)) {
+		if (stat(path, &st) == 0) {
+			ent->tmode = st.st_mode;
+			ent->dev   = st.st_dev;
+			ent->tino  = st.st_ino;
+		} else {
+			ent->tmode = ent->tino = 0;
+		}
+	}
 }
 
 static char *
_AT_@ -270,15 +284,42 @@ lsdir(const char *path, const struct entry *dir)
 	free(ents);
 }
 
+static int
+visit(const struct entry *ent)
+{
+	dev_t dev;
+	ino_t ino;
+	int i;
+
+	dev = ent->dev;
+	ino = S_ISLNK(ent->mode) ? ent->tino : ent->ino;
+
+	for (i = 0; tree[i].ino && i < PATH_MAX; ++i) {
+		if (ino == tree[i].ino && dev == tree[i].dev)
+			return -1;
+	}
+
+	tree[i].ino = ino;
+	tree[i].dev = dev;
+	return i;
+}
+
 static void
 ls(const char *path, const struct entry *ent, int listdir)
 {
+	int treeind;
 	char cwd[PATH_MAX];
 
 	if (!listdir) {
 		output(ent);
 	} else if (S_ISDIR(ent->mode) ||
 	    (S_ISLNK(ent->mode) && S_ISDIR(ent->tmode))) {
+		if ((treeind = visit(ent)) < 0) {
+			fprintf(stderr, "%s%s: already visited\n",
+			    path, ent->name);
+			return;
+		}
+
 		if (!getcwd(cwd, PATH_MAX))
 			eprintf("getcwd:");
 
_AT_@ -289,6 +330,7 @@ ls(const char *path, const struct entry *ent, int listdir)
 
 		printf("%s", path);
 		lsdir(path, ent);
+		tree[treeind].ino = 0;
 
 		if (chdir(cwd) < 0)
 			eprintf("chdir %s:", cwd);
-- 
2.4.3
--FcDMekJBvgbQ11GR
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="0005-ls-group-sorting-options.patch"
Received on Mon Sep 17 2001 - 00:00:00 CEST

This archive was generated by hypermail 2.3.0 : Thu Jun 18 2015 - 17:34:31 CEST