diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-03 00:07:05 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-03 00:07:05 +0000 |
commit | f9f74293465e98f2af117a1821a8fbb97cdbc3ed (patch) | |
tree | 5a696966b90b08535a6d1f581357aeb65dfdbeb0 | |
parent | 027e3fddb580bf3b397f2392b7e6aeab69adac79 (diff) | |
download | busybox-w32-f9f74293465e98f2af117a1821a8fbb97cdbc3ed.tar.gz busybox-w32-f9f74293465e98f2af117a1821a8fbb97cdbc3ed.tar.bz2 busybox-w32-f9f74293465e98f2af117a1821a8fbb97cdbc3ed.zip |
hush: explain parsing context structure
plug leak in setup_redirect on error path
function old new delta
done_command 84 86 +2
done_word 657 658 +1
done_pipe 105 106 +1
initialize_context 39 38 -1
setup_redirect 219 212 -7
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/2 up/down: 4/-8) Total: -4 bytes
-rw-r--r-- | shell/hush.c | 53 |
1 files changed, 32 insertions, 21 deletions
diff --git a/shell/hush.c b/shell/hush.c index eeec13b3d..d401948aa 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -359,9 +359,13 @@ struct pipe { | |||
359 | 359 | ||
360 | /* This holds pointers to the various results of parsing */ | 360 | /* This holds pointers to the various results of parsing */ |
361 | struct parse_context { | 361 | struct parse_context { |
362 | struct command *command; | 362 | /* linked list of pipes */ |
363 | struct pipe *list_head; | 363 | struct pipe *list_head; |
364 | /* last pipe (being constructed right now) */ | ||
364 | struct pipe *pipe; | 365 | struct pipe *pipe; |
366 | /* last command in pipe (being constructed right now) */ | ||
367 | struct command *command; | ||
368 | /* last redirect in command->redirects list */ | ||
365 | struct redir_struct *pending_redirect; | 369 | struct redir_struct *pending_redirect; |
366 | #if HAS_KEYWORDS | 370 | #if HAS_KEYWORDS |
367 | smallint ctx_res_w; | 371 | smallint ctx_res_w; |
@@ -369,7 +373,15 @@ struct parse_context { | |||
369 | #if ENABLE_HUSH_CASE | 373 | #if ENABLE_HUSH_CASE |
370 | smallint ctx_dsemicolon; /* ";;" seen */ | 374 | smallint ctx_dsemicolon; /* ";;" seen */ |
371 | #endif | 375 | #endif |
372 | int old_flag; /* bitmask of FLAG_xxx, for figuring out valid reserved words */ | 376 | /* bitmask of FLAG_xxx, for figuring out valid reserved words */ |
377 | int old_flag; | ||
378 | /* group we are enclosed in: | ||
379 | * example 1: "{ { false; ..." | ||
380 | * example 2: "if true; then { false; ..." | ||
381 | * example 3: "if true; then if false; ..." | ||
382 | * when we find closing "}" / "fi" / whatever, we move list_head | ||
383 | * into stack->command->group and delete ourself. | ||
384 | */ | ||
373 | struct parse_context *stack; | 385 | struct parse_context *stack; |
374 | #endif | 386 | #endif |
375 | }; | 387 | }; |
@@ -3288,37 +3300,36 @@ static int redirect_dup_num(struct in_str *input) | |||
3288 | * for file descriptor duplication, e.g., "2>&1". | 3300 | * for file descriptor duplication, e.g., "2>&1". |
3289 | * Return code is 0 normally, 1 if a syntax error is detected in src. | 3301 | * Return code is 0 normally, 1 if a syntax error is detected in src. |
3290 | * Resource errors (in xmalloc) cause the process to exit */ | 3302 | * Resource errors (in xmalloc) cause the process to exit */ |
3291 | static int setup_redirect(struct parse_context *ctx, int fd, redir_type style, | 3303 | static int setup_redirect(struct parse_context *ctx, |
3292 | struct in_str *input) | 3304 | int fd, |
3305 | redir_type style, | ||
3306 | struct in_str *input) | ||
3293 | { | 3307 | { |
3294 | struct command *command = ctx->command; | 3308 | struct command *command = ctx->command; |
3295 | struct redir_struct *redir = command->redirects; | 3309 | struct redir_struct *redir; |
3296 | struct redir_struct *last_redir = NULL; | 3310 | struct redir_struct **redirp; |
3311 | int dup_num; | ||
3312 | |||
3313 | /* Check for a '2>&1' type redirect */ | ||
3314 | dup_num = redirect_dup_num(input); | ||
3315 | if (dup_num == -2) | ||
3316 | return 1; /* syntax error */ | ||
3297 | 3317 | ||
3298 | /* Create a new redir_struct and drop it onto the end of the linked list */ | 3318 | /* Create a new redir_struct and drop it onto the end of the linked list */ |
3299 | while (redir) { | 3319 | redirp = &command->redirects; |
3300 | last_redir = redir; | 3320 | while ((redir = *redirp) != NULL) { |
3301 | redir = redir->next; | 3321 | redirp = &(redir->next); |
3302 | } | 3322 | } |
3303 | redir = xzalloc(sizeof(struct redir_struct)); | 3323 | *redirp = redir = xzalloc(sizeof(*redir)); |
3304 | /* redir->next = NULL; */ | 3324 | /* redir->next = NULL; */ |
3305 | /* redir->rd_filename = NULL; */ | 3325 | /* redir->rd_filename = NULL; */ |
3306 | if (last_redir) { | ||
3307 | last_redir->next = redir; | ||
3308 | } else { | ||
3309 | command->redirects = redir; | ||
3310 | } | ||
3311 | |||
3312 | redir->rd_type = style; | 3326 | redir->rd_type = style; |
3313 | redir->fd = (fd == -1) ? redir_table[style].default_fd : fd; | 3327 | redir->fd = (fd == -1) ? redir_table[style].default_fd : fd; |
3314 | 3328 | ||
3315 | debug_printf("Redirect type %d%s\n", redir->fd, redir_table[style].descrip); | 3329 | debug_printf("Redirect type %d%s\n", redir->fd, redir_table[style].descrip); |
3316 | 3330 | ||
3317 | /* Check for a '2>&1' type redirect */ | 3331 | redir->dup = dup_num; |
3318 | redir->dup = redirect_dup_num(input); | 3332 | if (dup_num != -1) { |
3319 | if (redir->dup == -2) | ||
3320 | return 1; /* syntax error */ | ||
3321 | if (redir->dup != -1) { | ||
3322 | /* Erik had a check here that the file descriptor in question | 3333 | /* Erik had a check here that the file descriptor in question |
3323 | * is legit; I postpone that to "run time" | 3334 | * is legit; I postpone that to "run time" |
3324 | * A "-" representation of "close me" shows up as a -3 here */ | 3335 | * A "-" representation of "close me" shows up as a -3 here */ |