Fix typo in manual
[platform/upstream/glibc.git] / io / fts.c
index bf18299..5ba202b 100644 (file)
--- 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) {
@@ -125,14 +125,17 @@ fts_open(argv, options, compar)
                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;
                }
@@ -248,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. */
@@ -374,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);
 
                /*
@@ -392,7 +396,7 @@ next:       tmp = p;
                                return (NULL);
                        }
                        fts_load(sp, p);
-                       return (sp->fts_cur = p);
+                       return p;
                }
 
                /*
@@ -418,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) {
@@ -463,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;
 }
 
 /*
@@ -691,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;
@@ -702,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;
@@ -744,7 +748,10 @@ mem1:                              saved_errno = errno;
                        p->fts_flags |= FTS_ISW;
 #endif
 
-               if (cderrno) {
+               /* 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 (0 && cderrno) {
                        if (nlinks) {
                                p->fts_info = FTS_NS;
                                p->fts_errno = cderrno;
@@ -819,6 +826,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);
        }
 
@@ -826,6 +834,7 @@ mem1:                               saved_errno = errno;
        if (!nitems) {
                if (type == BREAD)
                        cur->fts_info = FTS_DP;
+               fts_lfree(head);
                return (NULL);
        }
 
@@ -962,7 +971,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;
@@ -1032,10 +1041,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);