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
This commit is contained in:
parent
027e3fddb5
commit
f9f7429346
53
shell/hush.c
53
shell/hush.c
@ -359,9 +359,13 @@ struct pipe {
|
|||||||
|
|
||||||
/* This holds pointers to the various results of parsing */
|
/* This holds pointers to the various results of parsing */
|
||||||
struct parse_context {
|
struct parse_context {
|
||||||
struct command *command;
|
/* linked list of pipes */
|
||||||
struct pipe *list_head;
|
struct pipe *list_head;
|
||||||
|
/* last pipe (being constructed right now) */
|
||||||
struct pipe *pipe;
|
struct pipe *pipe;
|
||||||
|
/* last command in pipe (being constructed right now) */
|
||||||
|
struct command *command;
|
||||||
|
/* last redirect in command->redirects list */
|
||||||
struct redir_struct *pending_redirect;
|
struct redir_struct *pending_redirect;
|
||||||
#if HAS_KEYWORDS
|
#if HAS_KEYWORDS
|
||||||
smallint ctx_res_w;
|
smallint ctx_res_w;
|
||||||
@ -369,7 +373,15 @@ struct parse_context {
|
|||||||
#if ENABLE_HUSH_CASE
|
#if ENABLE_HUSH_CASE
|
||||||
smallint ctx_dsemicolon; /* ";;" seen */
|
smallint ctx_dsemicolon; /* ";;" seen */
|
||||||
#endif
|
#endif
|
||||||
int old_flag; /* bitmask of FLAG_xxx, for figuring out valid reserved words */
|
/* bitmask of FLAG_xxx, for figuring out valid reserved words */
|
||||||
|
int old_flag;
|
||||||
|
/* group we are enclosed in:
|
||||||
|
* example 1: "{ { false; ..."
|
||||||
|
* example 2: "if true; then { false; ..."
|
||||||
|
* example 3: "if true; then if false; ..."
|
||||||
|
* when we find closing "}" / "fi" / whatever, we move list_head
|
||||||
|
* into stack->command->group and delete ourself.
|
||||||
|
*/
|
||||||
struct parse_context *stack;
|
struct parse_context *stack;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
@ -3288,37 +3300,36 @@ static int redirect_dup_num(struct in_str *input)
|
|||||||
* for file descriptor duplication, e.g., "2>&1".
|
* for file descriptor duplication, e.g., "2>&1".
|
||||||
* Return code is 0 normally, 1 if a syntax error is detected in src.
|
* Return code is 0 normally, 1 if a syntax error is detected in src.
|
||||||
* Resource errors (in xmalloc) cause the process to exit */
|
* Resource errors (in xmalloc) cause the process to exit */
|
||||||
static int setup_redirect(struct parse_context *ctx, int fd, redir_type style,
|
static int setup_redirect(struct parse_context *ctx,
|
||||||
struct in_str *input)
|
int fd,
|
||||||
|
redir_type style,
|
||||||
|
struct in_str *input)
|
||||||
{
|
{
|
||||||
struct command *command = ctx->command;
|
struct command *command = ctx->command;
|
||||||
struct redir_struct *redir = command->redirects;
|
struct redir_struct *redir;
|
||||||
struct redir_struct *last_redir = NULL;
|
struct redir_struct **redirp;
|
||||||
|
int dup_num;
|
||||||
|
|
||||||
|
/* Check for a '2>&1' type redirect */
|
||||||
|
dup_num = redirect_dup_num(input);
|
||||||
|
if (dup_num == -2)
|
||||||
|
return 1; /* syntax error */
|
||||||
|
|
||||||
/* Create a new redir_struct and drop it onto the end of the linked list */
|
/* Create a new redir_struct and drop it onto the end of the linked list */
|
||||||
while (redir) {
|
redirp = &command->redirects;
|
||||||
last_redir = redir;
|
while ((redir = *redirp) != NULL) {
|
||||||
redir = redir->next;
|
redirp = &(redir->next);
|
||||||
}
|
}
|
||||||
redir = xzalloc(sizeof(struct redir_struct));
|
*redirp = redir = xzalloc(sizeof(*redir));
|
||||||
/* redir->next = NULL; */
|
/* redir->next = NULL; */
|
||||||
/* redir->rd_filename = NULL; */
|
/* redir->rd_filename = NULL; */
|
||||||
if (last_redir) {
|
|
||||||
last_redir->next = redir;
|
|
||||||
} else {
|
|
||||||
command->redirects = redir;
|
|
||||||
}
|
|
||||||
|
|
||||||
redir->rd_type = style;
|
redir->rd_type = style;
|
||||||
redir->fd = (fd == -1) ? redir_table[style].default_fd : fd;
|
redir->fd = (fd == -1) ? redir_table[style].default_fd : fd;
|
||||||
|
|
||||||
debug_printf("Redirect type %d%s\n", redir->fd, redir_table[style].descrip);
|
debug_printf("Redirect type %d%s\n", redir->fd, redir_table[style].descrip);
|
||||||
|
|
||||||
/* Check for a '2>&1' type redirect */
|
redir->dup = dup_num;
|
||||||
redir->dup = redirect_dup_num(input);
|
if (dup_num != -1) {
|
||||||
if (redir->dup == -2)
|
|
||||||
return 1; /* syntax error */
|
|
||||||
if (redir->dup != -1) {
|
|
||||||
/* Erik had a check here that the file descriptor in question
|
/* Erik had a check here that the file descriptor in question
|
||||||
* is legit; I postpone that to "run time"
|
* is legit; I postpone that to "run time"
|
||||||
* A "-" representation of "close me" shows up as a -3 here */
|
* A "-" representation of "close me" shows up as a -3 here */
|
||||||
|
Loading…
Reference in New Issue
Block a user