diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-11-23 12:50:54 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-11-23 12:50:54 +0000 |
commit | f962a0354e2426ef9781df97e4b02b32e438783c (patch) | |
tree | 4e0b3363932fbc0a30d5242b58ca5a0fea48d2a8 /shell/hush.c | |
parent | f23c3f95e88302923147f159115180da7cf0344e (diff) | |
download | busybox-w32-f962a0354e2426ef9781df97e4b02b32e438783c.tar.gz busybox-w32-f962a0354e2426ef9781df97e4b02b32e438783c.tar.bz2 busybox-w32-f962a0354e2426ef9781df97e4b02b32e438783c.zip |
hush: plug memory leak
Diffstat (limited to 'shell/hush.c')
-rw-r--r-- | shell/hush.c | 43 |
1 files changed, 38 insertions, 5 deletions
diff --git a/shell/hush.c b/shell/hush.c index a76327721..5c641904c 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -144,6 +144,40 @@ static const char *indenter(int i) | |||
144 | #endif | 144 | #endif |
145 | 145 | ||
146 | 146 | ||
147 | /* | ||
148 | * Leak hunting. Use hush_leaktool.sh for post-processing. | ||
149 | */ | ||
150 | #ifdef FOR_HUSH_LEAKTOOL | ||
151 | void *xxmalloc(int lineno, size_t size) | ||
152 | { | ||
153 | void *ptr = xmalloc((size + 0xff) & ~0xff); | ||
154 | fprintf(stderr, "line %d: malloc %p\n", lineno, ptr); | ||
155 | return ptr; | ||
156 | } | ||
157 | void *xxrealloc(int lineno, void *ptr, size_t size) | ||
158 | { | ||
159 | ptr = xrealloc(ptr, (size + 0xff) & ~0xff); | ||
160 | fprintf(stderr, "line %d: realloc %p\n", lineno, ptr); | ||
161 | return ptr; | ||
162 | } | ||
163 | char *xxstrdup(int lineno, const char *str) | ||
164 | { | ||
165 | char *ptr = xstrdup(str); | ||
166 | fprintf(stderr, "line %d: strdup %p\n", lineno, ptr); | ||
167 | return ptr; | ||
168 | } | ||
169 | void xxfree(void *ptr) | ||
170 | { | ||
171 | fprintf(stderr, "free %p\n", ptr); | ||
172 | free(ptr); | ||
173 | } | ||
174 | #define xmalloc(s) xxmalloc(__LINE__, s) | ||
175 | #define xrealloc(p, s) xxrealloc(__LINE__, p, s) | ||
176 | #define xstrdup(s) xxstrdup(__LINE__, s) | ||
177 | #define free(p) xxfree(p) | ||
178 | #endif | ||
179 | |||
180 | |||
147 | #if !ENABLE_HUSH_INTERACTIVE | 181 | #if !ENABLE_HUSH_INTERACTIVE |
148 | #undef ENABLE_FEATURE_EDITING | 182 | #undef ENABLE_FEATURE_EDITING |
149 | #define ENABLE_FEATURE_EDITING 0 | 183 | #define ENABLE_FEATURE_EDITING 0 |
@@ -256,7 +290,6 @@ struct child_prog { | |||
256 | smallint subshell; /* flag, non-zero if group must be forked */ | 290 | smallint subshell; /* flag, non-zero if group must be forked */ |
257 | smallint is_stopped; /* is the program currently running? */ | 291 | smallint is_stopped; /* is the program currently running? */ |
258 | struct redir_struct *redirects; /* I/O redirections */ | 292 | struct redir_struct *redirects; /* I/O redirections */ |
259 | char **glob_result; /* result of parameter globbing */ | ||
260 | struct pipe *family; /* pointer back to the child's parent pipe */ | 293 | struct pipe *family; /* pointer back to the child's parent pipe */ |
261 | //sp counting seems to be broken... so commented out, grep for '//sp:' | 294 | //sp counting seems to be broken... so commented out, grep for '//sp:' |
262 | //sp: int sp; /* number of SPECIAL_VAR_SYMBOL */ | 295 | //sp: int sp; /* number of SPECIAL_VAR_SYMBOL */ |
@@ -2198,8 +2231,8 @@ static int free_pipe(struct pipe *pi, int indent) | |||
2198 | for (a = 0, p = child->argv; *p; a++, p++) { | 2231 | for (a = 0, p = child->argv; *p; a++, p++) { |
2199 | debug_printf_clean("%s argv[%d] = %s\n", indenter(indent), a, *p); | 2232 | debug_printf_clean("%s argv[%d] = %s\n", indenter(indent), a, *p); |
2200 | } | 2233 | } |
2201 | free_strings(child->glob_result); | 2234 | free_strings(child->argv); |
2202 | child->glob_result = NULL; | 2235 | child->argv = NULL; |
2203 | } else if (child->group) { | 2236 | } else if (child->group) { |
2204 | debug_printf_clean("%s begin group (subshell:%d)\n", indenter(indent), child->subshell); | 2237 | debug_printf_clean("%s begin group (subshell:%d)\n", indenter(indent), child->subshell); |
2205 | ret_code = free_pipe_list(child->group, indent+3); | 2238 | ret_code = free_pipe_list(child->group, indent+3); |
@@ -2333,6 +2366,7 @@ static int xglob(o_string *dest, char ***pglob) | |||
2333 | debug_printf("globhack returned %d\n", gr); | 2366 | debug_printf("globhack returned %d\n", gr); |
2334 | /* quote removal, or more accurately, backslash removal */ | 2367 | /* quote removal, or more accurately, backslash removal */ |
2335 | *pglob = globhack(dest->data, *pglob); | 2368 | *pglob = globhack(dest->data, *pglob); |
2369 | globfree(&globdata); | ||
2336 | return 0; | 2370 | return 0; |
2337 | } | 2371 | } |
2338 | if (gr != 0) { /* GLOB_ABORTED ? */ | 2372 | if (gr != 0) { /* GLOB_ABORTED ? */ |
@@ -2340,7 +2374,6 @@ static int xglob(o_string *dest, char ***pglob) | |||
2340 | } | 2374 | } |
2341 | if (globdata.gl_pathv && globdata.gl_pathv[0]) | 2375 | if (globdata.gl_pathv && globdata.gl_pathv[0]) |
2342 | *pglob = add_strings_to_strings(1, *pglob, globdata.gl_pathv); | 2376 | *pglob = add_strings_to_strings(1, *pglob, globdata.gl_pathv); |
2343 | /* globprint(glob_target); */ | ||
2344 | globfree(&globdata); | 2377 | globfree(&globdata); |
2345 | return gr; | 2378 | return gr; |
2346 | } | 2379 | } |
@@ -3001,6 +3034,7 @@ static int done_word(o_string *dest, struct p_context *ctx) | |||
3001 | 3034 | ||
3002 | b_reset(dest); | 3035 | b_reset(dest); |
3003 | if (ctx->pending_redirect) { | 3036 | if (ctx->pending_redirect) { |
3037 | /* NB: don't free_strings(ctx->pending_redirect->glob_word) here */ | ||
3004 | if (ctx->pending_redirect->glob_word | 3038 | if (ctx->pending_redirect->glob_word |
3005 | && ctx->pending_redirect->glob_word[0] | 3039 | && ctx->pending_redirect->glob_word[0] |
3006 | && ctx->pending_redirect->glob_word[1] | 3040 | && ctx->pending_redirect->glob_word[1] |
@@ -3056,7 +3090,6 @@ static int done_command(struct p_context *ctx) | |||
3056 | /*child->argv = NULL;*/ | 3090 | /*child->argv = NULL;*/ |
3057 | /*child->is_stopped = 0;*/ | 3091 | /*child->is_stopped = 0;*/ |
3058 | /*child->group = NULL;*/ | 3092 | /*child->group = NULL;*/ |
3059 | /*child->glob_result = NULL;*/ | ||
3060 | child->family = pi; | 3093 | child->family = pi; |
3061 | //sp: /*child->sp = 0;*/ | 3094 | //sp: /*child->sp = 0;*/ |
3062 | //pt: child->parse_type = ctx->parse_type; | 3095 | //pt: child->parse_type = ctx->parse_type; |