diff options
author | landley <landley@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2006-05-02 19:46:52 +0000 |
---|---|---|
committer | landley <landley@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2006-05-02 19:46:52 +0000 |
commit | 1d1fd21e3536c1c593a3efa4c939d8035f594f76 (patch) | |
tree | 05e2fe55bc8e22b10ec129346f1be4c0b6727091 /coreutils/ls.c | |
parent | 744bfe6bfcfd653d714aedeb061d196cb60e6d03 (diff) | |
download | busybox-w32-1d1fd21e3536c1c593a3efa4c939d8035f594f76.tar.gz busybox-w32-1d1fd21e3536c1c593a3efa4c939d8035f594f76.tar.bz2 busybox-w32-1d1fd21e3536c1c593a3efa4c939d8035f594f76.zip |
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.
git-svn-id: svn://busybox.net/trunk/busybox@14978 69ca8d6d-28ef-0310-b511-8ec308f3f277
Diffstat (limited to 'coreutils/ls.c')
-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) | |||
338 | } | 338 | } |
339 | 339 | ||
340 | #ifdef CONFIG_FEATURE_LS_RECURSIVE | 340 | #ifdef CONFIG_FEATURE_LS_RECURSIVE |
341 | static void dfree(struct dnode **dnp) | 341 | static void dfree(struct dnode **dnp, int nfiles) |
342 | { | 342 | { |
343 | struct dnode *cur, *next; | 343 | int i; |
344 | 344 | ||
345 | if (dnp == NULL) | 345 | if (dnp == NULL) |
346 | return; | 346 | return; |
347 | 347 | ||
348 | cur = dnp[0]; | 348 | for (i = 0; i < nfiles; i++) { |
349 | while (cur != NULL) { | 349 | struct dnode *cur = dnp[i]; |
350 | if(cur->allocated) | 350 | if(cur->allocated) |
351 | free(cur->fullname); /* free the filename */ | 351 | free(cur->fullname); /* free the filename */ |
352 | next = cur->next; | ||
353 | free(cur); /* free the dnode */ | 352 | free(cur); /* free the dnode */ |
354 | cur = next; | ||
355 | } | 353 | } |
356 | free(dnp); /* free the array holding the dnode pointers */ | 354 | free(dnp); /* free the array holding the dnode pointers */ |
357 | } | 355 | } |
@@ -561,7 +559,7 @@ static void showdirs(struct dnode **dn, int ndirs, int first) | |||
561 | free(dnd); /* free the array of dnode pointers to the dirs */ | 559 | free(dnd); /* free the array of dnode pointers to the dirs */ |
562 | } | 560 | } |
563 | } | 561 | } |
564 | dfree(subdnp); /* free the dnodes and the fullname mem */ | 562 | dfree(subdnp, nfiles); /* free the dnodes and the fullname mem */ |
565 | #endif | 563 | #endif |
566 | } | 564 | } |
567 | } | 565 | } |
@@ -1151,13 +1149,19 @@ int ls_main(int argc, char **argv) | |||
1151 | shellsort(dnf, dnfiles); | 1149 | shellsort(dnf, dnfiles); |
1152 | #endif | 1150 | #endif |
1153 | showfiles(dnf, dnfiles); | 1151 | showfiles(dnf, dnfiles); |
1152 | if (ENABLE_FEATURE_CLEAN_UP) | ||
1153 | free(dnf); | ||
1154 | } | 1154 | } |
1155 | if (dndirs > 0) { | 1155 | if (dndirs > 0) { |
1156 | #ifdef CONFIG_FEATURE_LS_SORTFILES | 1156 | #ifdef CONFIG_FEATURE_LS_SORTFILES |
1157 | shellsort(dnd, dndirs); | 1157 | shellsort(dnd, dndirs); |
1158 | #endif | 1158 | #endif |
1159 | showdirs(dnd, dndirs, dnfiles == 0); | 1159 | showdirs(dnd, dndirs, dnfiles == 0); |
1160 | if (ENABLE_FEATURE_CLEAN_UP) | ||
1161 | free(dnd); | ||
1160 | } | 1162 | } |
1161 | } | 1163 | } |
1164 | if (ENABLE_FEATURE_CLEAN_UP) | ||
1165 | dfree(dnp, nfiles); | ||
1162 | return (status); | 1166 | return (status); |
1163 | } | 1167 | } |