summaryrefslogtreecommitdiffhomepage
path: root/coreutils/ls.c
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2006-05-02 19:46:52 +0000
committerRob Landley <rob@landley.net>2006-05-02 19:46:52 +0000
commit2631486f1bfac59f9217350effcda627da7be875 (patch)
tree05e2fe55bc8e22b10ec129346f1be4c0b6727091 /coreutils/ls.c
parent6389ff111569d985112e63809a75149e03c7983b (diff)
Patch from Shaun Jackman:
ls has an ugly bug. ls uses an array of pointers, the elements of which are all in a linked list. To free the elements, instead of freeing all the elements in the array, array[0..nelements], it frees by iterating the linked list starting at array[0], which it assumes is the head of the list. Unfortunately, ls also sorts the array! So, array[0] is no longer the head, but somewhere in the middle of the linked list. This patch fixes this bug, and also adds an ENABLE_FEATURE_CLEAN_UP stanza.
Diffstat (limited to 'coreutils/ls.c')
-rw-r--r--coreutils/ls.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/coreutils/ls.c b/coreutils/ls.c
index c9d24ff4a..9cbb4cab7 100644
--- a/coreutils/ls.c
+++ b/coreutils/ls.c
@@ -338,20 +338,18 @@ static struct dnode **dnalloc(int num)
}
#ifdef CONFIG_FEATURE_LS_RECURSIVE
-static void dfree(struct dnode **dnp)
+static void dfree(struct dnode **dnp, int nfiles)
{
- struct dnode *cur, *next;
+ int i;
if (dnp == NULL)
return;
- cur = dnp[0];
- while (cur != NULL) {
+ for (i = 0; i < nfiles; i++) {
+ struct dnode *cur = dnp[i];
if(cur->allocated)
free(cur->fullname); /* free the filename */
- next = cur->next;
free(cur); /* free the dnode */
- cur = next;
}
free(dnp); /* free the array holding the dnode pointers */
}
@@ -561,7 +559,7 @@ static void showdirs(struct dnode **dn, int ndirs, int first)
free(dnd); /* free the array of dnode pointers to the dirs */
}
}
- dfree(subdnp); /* free the dnodes and the fullname mem */
+ dfree(subdnp, nfiles); /* free the dnodes and the fullname mem */
#endif
}
}
@@ -1151,13 +1149,19 @@ int ls_main(int argc, char **argv)
shellsort(dnf, dnfiles);
#endif
showfiles(dnf, dnfiles);
+ if (ENABLE_FEATURE_CLEAN_UP)
+ free(dnf);
}
if (dndirs > 0) {
#ifdef CONFIG_FEATURE_LS_SORTFILES
shellsort(dnd, dndirs);
#endif
showdirs(dnd, dndirs, dnfiles == 0);
+ if (ENABLE_FEATURE_CLEAN_UP)
+ free(dnd);
}
}
+ if (ENABLE_FEATURE_CLEAN_UP)
+ dfree(dnp, nfiles);
return (status);
}