diff options
author | Rob Landley <rob@landley.net> | 2006-05-02 23:46:52 +0400 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2006-05-02 23:46:52 +0400 |
commit | 2631486f1bfac59f9217350effcda627da7be875 (patch) | |
tree | 05e2fe55bc8e22b10ec129346f1be4c0b6727091 /coreutils | |
parent | 6389ff111569d985112e63809a75149e03c7983b (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')
-rw-r--r-- | coreutils/ls.c | 18 |
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); } |