diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index b407ae9e..f05d6204 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -3604,7 +3604,7 @@ pathexp.c does not end in a backslash, we need to return true. Fixes bug reported by Robert Elz -lib/glob/gm_loop.c +lib/glob/glob_loop.c - INTERNAL_GLOB_PATTERN_P: same change to return TRUE for a backslash that doesn't end the pattern @@ -4925,3 +4925,41 @@ subst.c tilde expansion at all, even for the previously-special-case array subscript expansion. Report from Bize Ma - expand_word_internal: take out Q_ARRAYSUB check for tilde expansion + + 12/26 + ----- +builtins/evalstring.c + - parse_and_execute: if the eval builtin gets a parser error while + parsing a string in posix mode, don't exit the shell if the eval + was run by the command builtin. report from Martijn Dekker + + +examples/loadables/{basename,dirname}.c + - dirname_builtin: skip over any `--' ending the options. Report from + Peng Yu + + 12/27 + ----- +examples/loadables/mkdir.c + - make_path: add argument noting whether or not the user specified -m; + only attempt the chmod on an existing directory if the user did so + - make_path: when creating intermediate directories, perform the + mkdir (path, 0) and chmod separately as the posix text recommends + + 12/28 + ----- +parser.h + - PST_COMMENT: new state, set when the shell is reading characters + until newline as part of comment processing + +parse.y + - shell_getc: don't return a space at the end of a token if the parser + is consuming a comment. Fixes bug reported by Harald van Dijk + + + 12/31 + ----- +lib/glob/glob_loop.c + - INTERNAL_GLOB_PATTERN_P: revert change from 4/27 that makes this + function return non-zero for a backslash in the string. Based on a + report from Tom Ryder diff --git a/MANIFEST b/MANIFEST index 44996811..03de2210 100644 --- a/MANIFEST +++ b/MANIFEST @@ -990,6 +990,7 @@ tests/errors4.sub f tests/errors5.sub f tests/errors6.sub f tests/errors7.sub f +tests/errors8.sub f tests/execscript f tests/exec.right f tests/exec1.sub f 755 @@ -1058,6 +1059,7 @@ tests/glob.tests f tests/glob1.sub f tests/glob2.sub f tests/glob3.sub f +tests/glob4.sub f tests/glob.right f tests/globstar.tests f tests/globstar.right f diff --git a/builtins/evalstring.c b/builtins/evalstring.c index 5073ca49..1496eeec 100644 --- a/builtins/evalstring.c +++ b/builtins/evalstring.c @@ -448,11 +448,11 @@ parse_and_execute (string, from_file, flags) } else { - last_result = EXECUTION_FAILURE; + last_result = EX_BADUSAGE; /* was EXECUTION_FAILURE */ if (interactive_shell == 0 && this_shell_builtin && (this_shell_builtin == source_builtin || this_shell_builtin == eval_builtin) && - last_command_exit_value == EX_BADSYNTAX && posixly_correct) + last_command_exit_value == EX_BADSYNTAX && posixly_correct && executing_command_builtin == 0) { should_jump_to_top_level = 1; code = ERREXIT; diff --git a/examples/loadables/basename.c b/examples/loadables/basename.c index 3ca18441..8ebdff4f 100644 --- a/examples/loadables/basename.c +++ b/examples/loadables/basename.c @@ -46,6 +46,7 @@ basename_builtin (list) if (no_options (list)) return (EX_USAGE); + list = loptend; string = list->word->word; suffix = (char *)NULL; diff --git a/examples/loadables/dirname.c b/examples/loadables/dirname.c index 69019cbc..d802ca77 100644 --- a/examples/loadables/dirname.c +++ b/examples/loadables/dirname.c @@ -30,6 +30,7 @@ #include "builtins.h" #include "shell.h" #include "common.h" +#include "bashgetopt.h" int dirname_builtin (list) @@ -38,15 +39,16 @@ dirname_builtin (list) int slen; char *string; + if (no_options (list)) + return (EX_USAGE); + list = loptend; + if (list == 0 || list->next) { builtin_usage (); return (EX_USAGE); } - if (no_options (list)) - return (EX_USAGE); - string = list->word->word; slen = strlen (string); diff --git a/examples/loadables/mkdir.c b/examples/loadables/mkdir.c index 767ad9eb..b3811199 100644 --- a/examples/loadables/mkdir.c +++ b/examples/loadables/mkdir.c @@ -52,12 +52,12 @@ int mkdir_builtin (list) WORD_LIST *list; { - int opt, pflag, omode, rval, nmode, parent_mode; + int opt, pflag, mflag, omode, rval, nmode, parent_mode; char *mode; WORD_LIST *l; reset_internal_getopt (); - pflag = 0; + pflag = mflag = 0; mode = (char *)NULL; while ((opt = internal_getopt(list, "m:p")) != -1) switch (opt) @@ -66,6 +66,7 @@ mkdir_builtin (list) pflag = 1; break; case 'm': + mflag = 1; mode = list_optarg; break; CASE_HELPOPT; @@ -115,7 +116,7 @@ mkdir_builtin (list) for (rval = EXECUTION_SUCCESS, l = list; l; l = l->next) { - if (pflag && make_path (l->word->word, nmode, parent_mode)) + if (pflag && make_path (l->word->word, mflag, nmode, parent_mode)) { rval = EXECUTION_FAILURE; continue; @@ -133,8 +134,9 @@ mkdir_builtin (list) this changes the process's umask; make sure that all paths leading to a return reset it to ORIGINAL_UMASK */ static int -make_path (path, nmode, parent_mode) +make_path (path, user_mode, nmode, parent_mode) char *path; + int user_mode; int nmode, parent_mode; { int oumask; @@ -149,7 +151,7 @@ make_path (path, nmode, parent_mode) return 1; } - if (chmod (path, nmode)) + if (user_mode && chmod (path, nmode)) { builtin_error ("%s: %s", path, strerror (errno)); return 1; @@ -173,13 +175,20 @@ make_path (path, nmode, parent_mode) *p = '\0'; if (stat (npath, &sb) != 0) { - if (mkdir (npath, parent_mode)) + if (mkdir (npath, 0)) { builtin_error ("cannot create directory `%s': %s", npath, strerror (errno)); umask (original_umask); free (npath); return 1; } + if (chmod (npath, parent_mode) != 0) + { + builtin_error ("cannot chmod directory `%s': %s", npath, strerror (errno)); + umask (original_umask); + free (npath); + return 1; + } } else if (S_ISDIR (sb.st_mode) == 0) { diff --git a/lib/glob/glob_loop.c b/lib/glob/glob_loop.c index 7d6ae211..5f319cc2 100644 --- a/lib/glob/glob_loop.c +++ b/lib/glob/glob_loop.c @@ -54,11 +54,17 @@ INTERNAL_GLOB_PATTERN_P (pattern) continue; case L('\\'): +#if 0 /* Don't let the pattern end in a backslash (GMATCH returns no match if the pattern ends in a backslash anyway), but otherwise return 1, since the matching engine uses backslash as an escape character and it can be removed. */ return (*p != L('\0')); +#else + /* The pattern may not end with a backslash. */ + if (*p++ == L('\0')) + return 0; +#endif } return 0; diff --git a/parse.y b/parse.y index 3e100fca..a431f260 100644 --- a/parse.y +++ b/parse.y @@ -419,7 +419,10 @@ inputunit: simple_list simple_list_terminator only interesting in non-interactive shells */ global_command = (COMMAND *)NULL; if (last_command_exit_value == 0) +{ +itrace("parser: forcing EX_BADUSAGE; executing_command_builtin = %d", executing_command_builtin); last_command_exit_value = EX_BADUSAGE; /* force error return */ +} handle_eof_input_unit (); if (interactive && parse_and_execute_level == 0) { @@ -2552,10 +2555,11 @@ next_alias_char: return the space that will delimit the token and postpone the pop_string. This set of conditions duplicates what used to be in mk_alexpansion () below, with the addition that we don't add a space if we're currently - reading a quoted string. */ + reading a quoted string or in a shell comment. */ #ifndef OLD_ALIAS_HACK if (uc == 0 && pushed_string_list && pushed_string_list->flags != PSH_SOURCE && pushed_string_list->flags != PSH_DPAREN && + (parser_state & PST_COMMENT) == 0 && shell_input_line_index > 0 && shell_input_line[shell_input_line_index-1] != ' ' && shell_input_line[shell_input_line_index-1] != '\n' && @@ -3267,8 +3271,10 @@ itrace("shell_getc: bash_input.location.string = `%s'", bash_input.location.stri if MBTEST(character == '#' && (!interactive || interactive_comments)) { /* A comment. Discard until EOL or EOF, and then return a newline. */ + parser_state |= PST_COMMENT; discard_until ('\n'); shell_getc (0); + parser_state &= ~PST_COMMENT; character = '\n'; /* this will take the next if statement and return. */ } diff --git a/parser.h b/parser.h index 88c799d8..54dd2c88 100644 --- a/parser.h +++ b/parser.h @@ -46,7 +46,7 @@ #define PST_HEREDOC 0x020000 /* reading body of here-document */ #define PST_REPARSE 0x040000 /* re-parsing in parse_string_to_word_list */ #define PST_REDIRLIST 0x080000 /* parsing a list of redirections preceding a simple command name */ - +#define PST_COMMENT 0x100000 /* parsing a shell comment; used by aliases */ /* Definition of the delimiter stack. Needed by parse.y and bashhist.c. */ struct dstack { diff --git a/tests/alias4.sub b/tests/alias4.sub index 966b93d1..6ea513a1 100644 --- a/tests/alias4.sub +++ b/tests/alias4.sub @@ -59,3 +59,12 @@ unalias -a alias e=echo eval ' +a? +argv[1] = +a? +aa argv[1] = argv[2] = argv[3] = @@ -70,7 +75,7 @@ argv[2] = argv[3] = argv[4] = tmp/l1 tmp/l2 tmp/*4 tmp/l3 -./glob.tests: line 46: no match: tmp/*4 +./glob.tests: line 47: no match: tmp/*4 argv[1] = argv[1] = <*> argv[1] = diff --git a/tests/glob.tests b/tests/glob.tests index cfb086fd..01913bbe 100644 --- a/tests/glob.tests +++ b/tests/glob.tests @@ -11,6 +11,7 @@ expect() ${THIS_SH} ./glob1.sub ${THIS_SH} ./glob2.sub ${THIS_SH} ./glob3.sub +${THIS_SH} ./glob4.sub MYDIR=$PWD # save where we are diff --git a/tests/glob4.sub b/tests/glob4.sub new file mode 100644 index 00000000..378b5a92 --- /dev/null +++ b/tests/glob4.sub @@ -0,0 +1,13 @@ +trap "rm 'a?' aa" EXIT +touch 'a?' aa + +set -- a \?; IFS=\\; var=$*; +recho "$var" +unset IFS; printf "%s\n" ${var} + +var='a\?' +recho "$var" +printf "%s\n" ${var} + +var='a\a' +printf "%s\n" ${var}