about summary refs log tree commit diff
path: root/io/fts.c
diff options
context:
space:
mode:
Diffstat (limited to 'io/fts.c')
-rw-r--r--io/fts.c54
1 files changed, 32 insertions, 22 deletions
diff --git a/io/fts.c b/io/fts.c
index f0df56cc7b..8e628b481d 100644
--- a/io/fts.c
+++ b/io/fts.c
@@ -53,7 +53,7 @@ static char sccsid[] = "@(#)fts.c	8.6 (Berkeley) 8/14/94";
 #endif
 
 
-static FTSENT	*fts_alloc (FTS *, const char *, int) internal_function;
+static FTSENT	*fts_alloc (FTS *, const char *, size_t) internal_function;
 static FTSENT	*fts_build (FTS *, int) internal_function;
 static void	 fts_lfree (FTSENT *) internal_function;
 static void	 fts_load (FTS *, FTSENT *) internal_function;
@@ -93,8 +93,8 @@ fts_open(argv, options, compar)
 	register FTS *sp;
 	register FTSENT *p, *root;
 	register int nitems;
-	FTSENT *parent, *tmp;
-	int len;
+	FTSENT *parent = NULL;
+	FTSENT *tmp;
 
 	/* Options check. */
 	if (options & ~FTS_OPTIONMASK) {
@@ -120,18 +120,22 @@ fts_open(argv, options, compar)
 #ifndef MAXPATHLEN
 #define MAXPATHLEN 1024
 #endif
-	if (fts_palloc(sp, MAX(fts_maxarglen(argv), MAXPATHLEN)))
+	size_t maxarglen = fts_maxarglen(argv);
+	if (fts_palloc(sp, MAX(maxarglen, MAXPATHLEN)))
 		goto mem1;
 
 	/* Allocate/initialize root's parent. */
-	if ((parent = fts_alloc(sp, "", 0)) == NULL)
-		goto mem2;
-	parent->fts_level = FTS_ROOTPARENTLEVEL;
+	if (*argv != NULL) {
+		if ((parent = fts_alloc(sp, "", 0)) == NULL)
+			goto mem2;
+		parent->fts_level = FTS_ROOTPARENTLEVEL;
+	  }
 
 	/* Allocate/initialize root(s). */
 	for (root = NULL, nitems = 0; *argv != NULL; ++argv, ++nitems) {
 		/* Don't allow zero-length paths. */
-		if ((len = strlen(*argv)) == 0) {
+		size_t len = strlen(*argv);
+		if (len == 0) {
 			__set_errno (ENOENT);
 			goto mem3;
 		}
@@ -247,8 +251,7 @@ fts_close(sp)
 	/* Free up child linked list, sort array, path buffer. */
 	if (sp->fts_child)
 		fts_lfree(sp->fts_child);
-	if (sp->fts_array)
-		free(sp->fts_array);
+	free(sp->fts_array);
 	free(sp->fts_path);
 
 	/* Return to original directory, save errno if necessary. */
@@ -373,12 +376,14 @@ fts_read(sp)
 		}
 		p = sp->fts_child;
 		sp->fts_child = NULL;
+		sp->fts_cur = p;
 		goto name;
 	}
 
 	/* Move to the next node on this level. */
 next:	tmp = p;
 	if ((p = p->fts_link) != NULL) {
+		sp->fts_cur = p;
 		free(tmp);
 
 		/*
@@ -391,7 +396,7 @@ next:	tmp = p;
 				return (NULL);
 			}
 			fts_load(sp, p);
-			return (sp->fts_cur = p);
+			return p;
 		}
 
 		/*
@@ -417,11 +422,12 @@ next:	tmp = p;
 name:		t = sp->fts_path + NAPPEND(p->fts_parent);
 		*t++ = '/';
 		memmove(t, p->fts_name, p->fts_namelen + 1);
-		return (sp->fts_cur = p);
+		return p;
 	}
 
 	/* Move up to the parent node. */
 	p = tmp->fts_parent;
+	sp->fts_cur = p;
 	free(tmp);
 
 	if (p->fts_level == FTS_ROOTPARENTLEVEL) {
@@ -462,7 +468,7 @@ name:		t = sp->fts_path + NAPPEND(p->fts_parent);
 		return (NULL);
 	}
 	p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP;
-	return (sp->fts_cur = p);
+	return p;
 }
 
 /*
@@ -690,7 +696,7 @@ fts_build(sp, type)
 		if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name))
 			continue;
 
-		if ((p = fts_alloc(sp, dp->d_name, (int)_D_EXACT_NAMLEN (dp))) == NULL)
+		if ((p = fts_alloc(sp, dp->d_name, _D_EXACT_NAMLEN (dp))) == NULL)
 			goto mem1;
 		if (_D_EXACT_NAMLEN (dp) >= maxlen) {/* include space for NUL */
 			oldaddr = sp->fts_path;
@@ -701,8 +707,7 @@ fts_build(sp, type)
 				 * structures already allocated.
 				 */
 mem1:				saved_errno = errno;
-				if (p)
-					free(p);
+				free(p);
 				fts_lfree(head);
 				(void)__closedir(dirp);
 				cur->fts_info = FTS_ERR;
@@ -743,6 +748,10 @@ mem1:				saved_errno = errno;
 			p->fts_flags |= FTS_ISW;
 #endif
 
+#if 0
+		/* Unreachable code.  cderrno is only ever set to a nonnull
+		   value if dirp is closed at the same time.  But then we
+		   cannot enter this loop.  */
 		if (cderrno) {
 			if (nlinks) {
 				p->fts_info = FTS_NS;
@@ -750,7 +759,9 @@ mem1:				saved_errno = errno;
 			} else
 				p->fts_info = FTS_NSOK;
 			p->fts_accpath = cur->fts_accpath;
-		} else if (nlinks == 0
+		} else
+#endif
+		if (nlinks == 0
 #if defined DT_DIR && defined _DIRENT_HAVE_D_TYPE
 			   || (nostat &&
 			       dp->d_type != DT_DIR && dp->d_type != DT_UNKNOWN)
@@ -818,6 +829,7 @@ mem1:				saved_errno = errno;
 	     fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) {
 		cur->fts_info = FTS_ERR;
 		SET(FTS_STOP);
+		fts_lfree(head);
 		return (NULL);
 	}
 
@@ -825,6 +837,7 @@ mem1:				saved_errno = errno;
 	if (!nitems) {
 		if (type == BREAD)
 			cur->fts_info = FTS_DP;
+		fts_lfree(head);
 		return (NULL);
 	}
 
@@ -961,7 +974,7 @@ internal_function
 fts_alloc(sp, name, namelen)
 	FTS *sp;
 	const char *name;
-	register int namelen;
+	size_t namelen;
 {
 	register FTSENT *p;
 	size_t len;
@@ -1031,10 +1044,7 @@ fts_palloc(sp, more)
 	 * We limit fts_pathlen to USHRT_MAX to be safe in both cases.
 	 */
 	if (sp->fts_pathlen < 0 || sp->fts_pathlen >= USHRT_MAX) {
-		if (sp->fts_path) {
-			free(sp->fts_path);
-			sp->fts_path = NULL;
-		}
+		free(sp->fts_path);
 		sp->fts_path = NULL;
 		__set_errno (ENAMETOOLONG);
 		return (1);