diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2012-10-09 12:05:51 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2012-10-09 12:05:51 +0000 |
commit | 509212aa98c5e38adb67481a079c9a09d3829f44 (patch) | |
tree | b5cdc614c48c429cb7bd1f595795485d51a44a0a /newlib/libc/posix/wordfree.c | |
parent | 277e7f0e2e6fc9fb533b301fc0627cfe4fd9d1ae (diff) | |
download | cygnal-509212aa98c5e38adb67481a079c9a09d3829f44.tar.gz cygnal-509212aa98c5e38adb67481a079c9a09d3829f44.tar.bz2 cygnal-509212aa98c5e38adb67481a079c9a09d3829f44.zip |
* libc/posix/wordfree.c (wordfree): The wrong words are freed
when WRDE_DOOFFS is in use. Restructure the code so that the memory
needed to be freed is instead kept in an internal linked list...
* libc/posix/wordexp2.h: ...as defined here...
* libc/posix/wordexp.c (wordexp): ...and build this internal
linked list here, avoiding wasteful strdup calls in the process.
Diffstat (limited to 'newlib/libc/posix/wordfree.c')
-rw-r--r-- | newlib/libc/posix/wordfree.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/newlib/libc/posix/wordfree.c b/newlib/libc/posix/wordfree.c index 2d1208c3e..024a619d9 100644 --- a/newlib/libc/posix/wordfree.c +++ b/newlib/libc/posix/wordfree.c @@ -18,13 +18,15 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <sys/queue.h> #include <wordexp.h> +#include "wordexp2.h" void wordfree(wordexp_t *pwordexp) { - int i; + ext_wordv_t *wordv; if (pwordexp == NULL) return; @@ -32,10 +34,14 @@ wordfree(wordexp_t *pwordexp) if (pwordexp->we_wordv == NULL) return; - for(i = 0; i < pwordexp->we_wordc; i++) - free(pwordexp->we_wordv[i]); + wordv = WE_WORDV_TO_EXT_WORDV(pwordexp->we_wordv); + while (!SLIST_EMPTY(&wordv->list)) { + struct ewords_entry *entry = SLIST_FIRST(&wordv->list); + SLIST_REMOVE_HEAD(&wordv->list, next); + free(entry); + } - free(pwordexp->we_wordv); + free(wordv); pwordexp->we_wordv = NULL; } |