From 3e7b0e61200b118fd83f56fc3ebaeedba455600e Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Wed, 16 May 2007 12:52:15 +0000 Subject: hush: simplify read builtin; fix set_local_var (misplaced 'goto skip;') --- shell/hush.c | 60 ++++++++++++++++++------------------------------------------ 1 file changed, 18 insertions(+), 42 deletions(-) diff --git a/shell/hush.c b/shell/hush.c index e3dd6663e..2e78e4a04 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -854,32 +854,24 @@ static int builtin_pwd(char **argv ATTRIBUTE_UNUSED) /* built-in 'read VAR' handler */ static int builtin_read(char **argv) { - int res; + char string[BUFSIZ]; + char *p; + const char *name = argv[1] ? argv[1] : "REPLY"; + int name_len = strlen(name); - if (argv[1]) { - char string[BUFSIZ]; - char *var = NULL; - - string[0] = '\0'; /* In case stdin has only EOF */ - /* read string */ - fgets(string, sizeof(string), stdin); - chomp(string); - var = malloc(strlen(argv[1]) + strlen(string) + 2); - if (var) { - sprintf(var, "%s=%s", argv[1], string); - res = set_local_var(var, 0); - } else - res = -1; - if (res) - bb_perror_msg("read"); - free(var); /* So not move up to avoid breaking errno */ - return res; - } - do res = getchar(); while (res != '\n' && res != EOF); - return 0; + if (name_len >= sizeof(string) - 2) + return EXIT_FAILURE; + strcpy(string, name); + p = string + name_len; + *p++ = '='; + *p = '\0'; /* In case stdin has only EOF */ + /* read string. name_len+1 chars are already used by 'name=' */ + fgets(p, sizeof(string) - 1 - name_len, stdin); + chomp(p); + return set_local_var(string, 0); } -/* built-in 'set VAR=value' handler */ +/* built-in 'set [VAR=value]' handler */ static int builtin_set(char **argv) { char *temp = argv[1]; @@ -959,7 +951,7 @@ static int builtin_umask(char **argv) /* built-in 'unset VAR' handler */ static int builtin_unset(char **argv) { - /* bash returned already true */ + /* bash always returns true */ unset_local_var(argv[1]); return EXIT_SUCCESS; } @@ -2418,8 +2410,6 @@ static int expand_on_ifs(char **list, int n, char **posp, const char *str) * to be filled). This routine is extremely tricky: has to deal with * variables/parameters with whitespace, $* and $@, and constructs like * 'echo -$*-'. If you play here, you must run testsuite afterwards! */ -/* NB: support for double-quoted expansion is not used yet (we never set - * magic bit 0x80 elsewhere...) */ /* NB: another bug is that we cannot detect empty strings yet: * "" or $empty"" expands to zero words, has to expand to empty word */ static int expand_vars_to_list(char **list, int n, char **posp, char *arg) @@ -2663,20 +2653,6 @@ static char *insert_var_value(char *inp) } - - - - - - - - - - - - - - /* This is used to get/check local shell variables */ static const char *get_local_var(const char *s) { @@ -2717,7 +2693,7 @@ static int set_local_var(const char *s, int flg_export) for (cur = top_vars; cur; cur = cur->next) { if (strcmp(cur->name, name) == 0) { if (strcmp(cur->value, value) == 0) { - if (flg_export > 0 && cur->flg_export == 0) + if (flg_export && !cur->flg_export) cur->flg_export = flg_export; else result++; @@ -2730,8 +2706,8 @@ static int set_local_var(const char *s, int flg_export) free((char*)cur->value); cur->value = strdup(value); } + goto skip; } - goto skip; } // TODO: need simpler/generic rollback on malloc failure - see ash -- cgit v1.2.3