Thu, 04 Oct 2012 20:30:05 +0200
Correct out of date build configuration, porting to Solaris 11 network
link infrastructure and new libpcap logic. This additionally allows for
device drivers in subdirectories of /dev. Correct packaged nmap
personalities and signatures to work out of the box. Finally, hack
arpd logic to properly close sockets and quit on TERM by repeating
signaling in the run command script. Sadly, all this fails to correct
the run time behaviour of honeyd which fails to bind to the IP layer.
michael@428 | 1 | Index: assoc.c |
michael@428 | 2 | --- assoc.c.orig 2009-08-06 02:19:40.000000000 +0200 |
michael@428 | 3 | +++ assoc.c 2012-06-27 10:31:02.000000000 +0200 |
michael@428 | 4 | @@ -77,6 +77,11 @@ |
michael@428 | 5 | b = hash_search (key, hash, HASH_CREATE); |
michael@428 | 6 | if (b == 0) |
michael@428 | 7 | return -1; |
michael@428 | 8 | + /* If we are overwriting an existing element's value, we're not going to |
michael@428 | 9 | + use the key. Nothing in the array assignment code path frees the key |
michael@428 | 10 | + string, so we can free it here to avoid a memory leak. */ |
michael@428 | 11 | + if (b->key != key) |
michael@428 | 12 | + free (key); |
michael@428 | 13 | FREE (b->data); |
michael@428 | 14 | b->data = value ? savestring (value) : (char *)0; |
michael@428 | 15 | return (0); |
michael@428 | 16 | Index: bashline.c |
michael@428 | 17 | --- bashline.c.orig 2011-01-16 21:32:47.000000000 +0100 |
michael@428 | 18 | +++ bashline.c 2012-06-27 10:31:03.000000000 +0200 |
michael@428 | 19 | @@ -121,6 +121,9 @@ |
michael@428 | 20 | static int filename_completion_ignore __P((char **)); |
michael@428 | 21 | static int bash_push_line __P((void)); |
michael@428 | 22 | |
michael@428 | 23 | +static rl_icppfunc_t *save_directory_hook __P((void)); |
michael@428 | 24 | +static void reset_directory_hook __P((rl_icppfunc_t *)); |
michael@428 | 25 | + |
michael@428 | 26 | static void cleanup_expansion_error __P((void)); |
michael@428 | 27 | static void maybe_make_readline_line __P((char *)); |
michael@428 | 28 | static void set_up_new_line __P((char *)); |
michael@428 | 29 | @@ -243,10 +246,17 @@ |
michael@428 | 30 | /* Perform spelling correction on directory names during word completion */ |
michael@428 | 31 | int dircomplete_spelling = 0; |
michael@428 | 32 | |
michael@428 | 33 | +/* Expand directory names during word/filename completion. */ |
michael@428 | 34 | +int dircomplete_expand = 0; |
michael@428 | 35 | +int dircomplete_expand_relpath = 0; |
michael@428 | 36 | + |
michael@428 | 37 | static char *bash_completer_word_break_characters = " \t\n\"'@><=;|&(:"; |
michael@428 | 38 | static char *bash_nohostname_word_break_characters = " \t\n\"'><=;|&(:"; |
michael@428 | 39 | /* )) */ |
michael@428 | 40 | |
michael@428 | 41 | +static const char *default_filename_quote_characters = " \t\n\\\"'@<>=;|&()#$`?*[!:{~"; /*}*/ |
michael@428 | 42 | +static char *custom_filename_quote_characters = 0; |
michael@428 | 43 | + |
michael@428 | 44 | static rl_hook_func_t *old_rl_startup_hook = (rl_hook_func_t *)NULL; |
michael@428 | 45 | |
michael@428 | 46 | static int dot_in_path = 0; |
michael@428 | 47 | @@ -501,7 +511,7 @@ |
michael@428 | 48 | |
michael@428 | 49 | /* Tell the completer that we might want to follow symbolic links or |
michael@428 | 50 | do other expansion on directory names. */ |
michael@428 | 51 | - rl_directory_rewrite_hook = bash_directory_completion_hook; |
michael@428 | 52 | + set_directory_hook (); |
michael@428 | 53 | |
michael@428 | 54 | rl_filename_rewrite_hook = bash_filename_rewrite_hook; |
michael@428 | 55 | |
michael@428 | 56 | @@ -529,7 +539,7 @@ |
michael@428 | 57 | enable_hostname_completion (perform_hostname_completion); |
michael@428 | 58 | |
michael@428 | 59 | /* characters that need to be quoted when appearing in filenames. */ |
michael@428 | 60 | - rl_filename_quote_characters = " \t\n\\\"'@<>=;|&()#$`?*[!:{~"; /*}*/ |
michael@428 | 61 | + rl_filename_quote_characters = default_filename_quote_characters; |
michael@428 | 62 | |
michael@428 | 63 | rl_filename_quoting_function = bash_quote_filename; |
michael@428 | 64 | rl_filename_dequoting_function = bash_dequote_filename; |
michael@428 | 65 | @@ -564,8 +574,10 @@ |
michael@428 | 66 | tilde_initialize (); |
michael@428 | 67 | rl_attempted_completion_function = attempt_shell_completion; |
michael@428 | 68 | rl_completion_entry_function = NULL; |
michael@428 | 69 | - rl_directory_rewrite_hook = bash_directory_completion_hook; |
michael@428 | 70 | rl_ignore_some_completions_function = filename_completion_ignore; |
michael@428 | 71 | + rl_filename_quote_characters = default_filename_quote_characters; |
michael@428 | 72 | + |
michael@428 | 73 | + set_directory_hook (); |
michael@428 | 74 | } |
michael@428 | 75 | |
michael@428 | 76 | /* Contains the line to push into readline. */ |
michael@428 | 77 | @@ -1279,6 +1291,9 @@ |
michael@428 | 78 | matches = (char **)NULL; |
michael@428 | 79 | rl_ignore_some_completions_function = filename_completion_ignore; |
michael@428 | 80 | |
michael@428 | 81 | + rl_filename_quote_characters = default_filename_quote_characters; |
michael@428 | 82 | + set_directory_hook (); |
michael@428 | 83 | + |
michael@428 | 84 | /* Determine if this could be a command word. It is if it appears at |
michael@428 | 85 | the start of the line (ignoring preceding whitespace), or if it |
michael@428 | 86 | appears after a character that separates commands. It cannot be a |
michael@428 | 87 | @@ -1591,6 +1606,12 @@ |
michael@428 | 88 | } |
michael@428 | 89 | else |
michael@428 | 90 | { |
michael@428 | 91 | + if (dircomplete_expand && dot_or_dotdot (filename_hint)) |
michael@428 | 92 | + { |
michael@428 | 93 | + dircomplete_expand = 0; |
michael@428 | 94 | + set_directory_hook (); |
michael@428 | 95 | + dircomplete_expand = 1; |
michael@428 | 96 | + } |
michael@428 | 97 | mapping_over = 4; |
michael@428 | 98 | goto inner; |
michael@428 | 99 | } |
michael@428 | 100 | @@ -1791,6 +1812,9 @@ |
michael@428 | 101 | |
michael@428 | 102 | inner: |
michael@428 | 103 | val = rl_filename_completion_function (filename_hint, istate); |
michael@428 | 104 | + if (mapping_over == 4 && dircomplete_expand) |
michael@428 | 105 | + set_directory_hook (); |
michael@428 | 106 | + |
michael@428 | 107 | istate = 1; |
michael@428 | 108 | |
michael@428 | 109 | if (val == 0) |
michael@428 | 110 | @@ -2693,6 +2717,52 @@ |
michael@428 | 111 | return conv; |
michael@428 | 112 | } |
michael@428 | 113 | |
michael@428 | 114 | +/* Functions to save and restore the appropriate directory hook */ |
michael@428 | 115 | +/* This is not static so the shopt code can call it */ |
michael@428 | 116 | +void |
michael@428 | 117 | +set_directory_hook () |
michael@428 | 118 | +{ |
michael@428 | 119 | + if (dircomplete_expand) |
michael@428 | 120 | + { |
michael@428 | 121 | + rl_directory_completion_hook = bash_directory_completion_hook; |
michael@428 | 122 | + rl_directory_rewrite_hook = (rl_icppfunc_t *)0; |
michael@428 | 123 | + } |
michael@428 | 124 | + else |
michael@428 | 125 | + { |
michael@428 | 126 | + rl_directory_rewrite_hook = bash_directory_completion_hook; |
michael@428 | 127 | + rl_directory_completion_hook = (rl_icppfunc_t *)0; |
michael@428 | 128 | + } |
michael@428 | 129 | +} |
michael@428 | 130 | + |
michael@428 | 131 | +static rl_icppfunc_t * |
michael@428 | 132 | +save_directory_hook () |
michael@428 | 133 | +{ |
michael@428 | 134 | + rl_icppfunc_t *ret; |
michael@428 | 135 | + |
michael@428 | 136 | + if (dircomplete_expand) |
michael@428 | 137 | + { |
michael@428 | 138 | + ret = rl_directory_completion_hook; |
michael@428 | 139 | + rl_directory_completion_hook = (rl_icppfunc_t *)NULL; |
michael@428 | 140 | + } |
michael@428 | 141 | + else |
michael@428 | 142 | + { |
michael@428 | 143 | + ret = rl_directory_rewrite_hook; |
michael@428 | 144 | + rl_directory_rewrite_hook = (rl_icppfunc_t *)NULL; |
michael@428 | 145 | + } |
michael@428 | 146 | + |
michael@428 | 147 | + return ret; |
michael@428 | 148 | +} |
michael@428 | 149 | + |
michael@428 | 150 | +static void |
michael@428 | 151 | +restore_directory_hook (hookf) |
michael@428 | 152 | + rl_icppfunc_t *hookf; |
michael@428 | 153 | +{ |
michael@428 | 154 | + if (dircomplete_expand) |
michael@428 | 155 | + rl_directory_completion_hook = hookf; |
michael@428 | 156 | + else |
michael@428 | 157 | + rl_directory_rewrite_hook = hookf; |
michael@428 | 158 | +} |
michael@428 | 159 | + |
michael@428 | 160 | /* Handle symbolic link references and other directory name |
michael@428 | 161 | expansions while hacking completion. This should return 1 if it modifies |
michael@428 | 162 | the DIRNAME argument, 0 otherwise. It should make sure not to modify |
michael@428 | 163 | @@ -2702,20 +2772,31 @@ |
michael@428 | 164 | char **dirname; |
michael@428 | 165 | { |
michael@428 | 166 | char *local_dirname, *new_dirname, *t; |
michael@428 | 167 | - int return_value, should_expand_dirname; |
michael@428 | 168 | + int return_value, should_expand_dirname, nextch, closer; |
michael@428 | 169 | WORD_LIST *wl; |
michael@428 | 170 | struct stat sb; |
michael@428 | 171 | |
michael@428 | 172 | - return_value = should_expand_dirname = 0; |
michael@428 | 173 | + return_value = should_expand_dirname = nextch = closer = 0; |
michael@428 | 174 | local_dirname = *dirname; |
michael@428 | 175 | |
michael@428 | 176 | - if (mbschr (local_dirname, '$')) |
michael@428 | 177 | - should_expand_dirname = 1; |
michael@428 | 178 | + if (t = mbschr (local_dirname, '$')) |
michael@428 | 179 | + { |
michael@428 | 180 | + should_expand_dirname = '$'; |
michael@428 | 181 | + nextch = t[1]; |
michael@428 | 182 | + /* Deliberately does not handle the deprecated $[...] arithmetic |
michael@428 | 183 | + expansion syntax */ |
michael@428 | 184 | + if (nextch == '(') |
michael@428 | 185 | + closer = ')'; |
michael@428 | 186 | + else if (nextch == '{') |
michael@428 | 187 | + closer = '}'; |
michael@428 | 188 | + else |
michael@428 | 189 | + nextch = 0; |
michael@428 | 190 | + } |
michael@428 | 191 | else |
michael@428 | 192 | { |
michael@428 | 193 | t = mbschr (local_dirname, '`'); |
michael@428 | 194 | if (t && unclosed_pair (local_dirname, strlen (local_dirname), "`") == 0) |
michael@428 | 195 | - should_expand_dirname = 1; |
michael@428 | 196 | + should_expand_dirname = '`'; |
michael@428 | 197 | } |
michael@428 | 198 | |
michael@428 | 199 | #if defined (HAVE_LSTAT) |
michael@428 | 200 | @@ -2739,6 +2820,23 @@ |
michael@428 | 201 | free (new_dirname); |
michael@428 | 202 | dispose_words (wl); |
michael@428 | 203 | local_dirname = *dirname; |
michael@428 | 204 | + /* XXX - change rl_filename_quote_characters here based on |
michael@428 | 205 | + should_expand_dirname/nextch/closer. This is the only place |
michael@428 | 206 | + custom_filename_quote_characters is modified. */ |
michael@428 | 207 | + if (rl_filename_quote_characters && *rl_filename_quote_characters) |
michael@428 | 208 | + { |
michael@428 | 209 | + int i, j, c; |
michael@428 | 210 | + i = strlen (default_filename_quote_characters); |
michael@428 | 211 | + custom_filename_quote_characters = xrealloc (custom_filename_quote_characters, i+1); |
michael@428 | 212 | + for (i = j = 0; c = default_filename_quote_characters[i]; i++) |
michael@428 | 213 | + { |
michael@428 | 214 | + if (c == should_expand_dirname || c == nextch || c == closer) |
michael@428 | 215 | + continue; |
michael@428 | 216 | + custom_filename_quote_characters[j++] = c; |
michael@428 | 217 | + } |
michael@428 | 218 | + custom_filename_quote_characters[j] = '\0'; |
michael@428 | 219 | + rl_filename_quote_characters = custom_filename_quote_characters; |
michael@428 | 220 | + } |
michael@428 | 221 | } |
michael@428 | 222 | else |
michael@428 | 223 | { |
michael@428 | 224 | @@ -2758,11 +2856,31 @@ |
michael@428 | 225 | local_dirname = *dirname = new_dirname; |
michael@428 | 226 | } |
michael@428 | 227 | |
michael@428 | 228 | + /* no_symbolic_links == 0 -> use (default) logical view of the file system. |
michael@428 | 229 | + local_dirname[0] == '.' && local_dirname[1] == '/' means files in the |
michael@428 | 230 | + current directory (./). |
michael@428 | 231 | + local_dirname[0] == '.' && local_dirname[1] == 0 means relative pathnames |
michael@428 | 232 | + in the current directory (e.g., lib/sh). |
michael@428 | 233 | + XXX - should we do spelling correction on these? */ |
michael@428 | 234 | + |
michael@428 | 235 | + /* This is test as it was in bash-4.2: skip relative pathnames in current |
michael@428 | 236 | + directory. Change test to |
michael@428 | 237 | + (local_dirname[0] != '.' || (local_dirname[1] && local_dirname[1] != '/')) |
michael@428 | 238 | + if we want to skip paths beginning with ./ also. */ |
michael@428 | 239 | if (no_symbolic_links == 0 && (local_dirname[0] != '.' || local_dirname[1])) |
michael@428 | 240 | { |
michael@428 | 241 | char *temp1, *temp2; |
michael@428 | 242 | int len1, len2; |
michael@428 | 243 | |
michael@428 | 244 | + /* If we have a relative path |
michael@428 | 245 | + (local_dirname[0] != '/' && local_dirname[0] != '.') |
michael@428 | 246 | + that is canonical after appending it to the current directory, then |
michael@428 | 247 | + temp1 = temp2+'/' |
michael@428 | 248 | + That is, |
michael@428 | 249 | + strcmp (temp1, temp2) == 0 |
michael@428 | 250 | + after adding a slash to temp2 below. It should be safe to not |
michael@428 | 251 | + change those. |
michael@428 | 252 | + */ |
michael@428 | 253 | t = get_working_directory ("symlink-hook"); |
michael@428 | 254 | temp1 = make_absolute (local_dirname, t); |
michael@428 | 255 | free (t); |
michael@428 | 256 | @@ -2797,7 +2915,15 @@ |
michael@428 | 257 | temp2[len2 + 1] = '\0'; |
michael@428 | 258 | } |
michael@428 | 259 | } |
michael@428 | 260 | - return_value |= STREQ (local_dirname, temp2) == 0; |
michael@428 | 261 | + |
michael@428 | 262 | + /* dircomplete_expand_relpath == 0 means we want to leave relative |
michael@428 | 263 | + pathnames that are unchanged by canonicalization alone. |
michael@428 | 264 | + *local_dirname != '/' && *local_dirname != '.' == relative pathname |
michael@428 | 265 | + (consistent with general.c:absolute_pathname()) |
michael@428 | 266 | + temp1 == temp2 (after appending a slash to temp2) means the pathname |
michael@428 | 267 | + is not changed by canonicalization as described above. */ |
michael@428 | 268 | + if (dircomplete_expand_relpath || ((local_dirname[0] != '/' && local_dirname[0] != '.') && STREQ (temp1, temp2) == 0)) |
michael@428 | 269 | + return_value |= STREQ (local_dirname, temp2) == 0; |
michael@428 | 270 | free (local_dirname); |
michael@428 | 271 | *dirname = temp2; |
michael@428 | 272 | free (temp1); |
michael@428 | 273 | @@ -3002,12 +3128,13 @@ |
michael@428 | 274 | |
michael@428 | 275 | orig_func = rl_completion_entry_function; |
michael@428 | 276 | orig_attempt_func = rl_attempted_completion_function; |
michael@428 | 277 | - orig_dir_func = rl_directory_rewrite_hook; |
michael@428 | 278 | orig_ignore_func = rl_ignore_some_completions_function; |
michael@428 | 279 | orig_rl_completer_word_break_characters = rl_completer_word_break_characters; |
michael@428 | 280 | + |
michael@428 | 281 | + orig_dir_func = save_directory_hook (); |
michael@428 | 282 | + |
michael@428 | 283 | rl_completion_entry_function = rl_filename_completion_function; |
michael@428 | 284 | rl_attempted_completion_function = (rl_completion_func_t *)NULL; |
michael@428 | 285 | - rl_directory_rewrite_hook = (rl_icppfunc_t *)NULL; |
michael@428 | 286 | rl_ignore_some_completions_function = filename_completion_ignore; |
michael@428 | 287 | rl_completer_word_break_characters = " \t\n\"\'"; |
michael@428 | 288 | |
michael@428 | 289 | @@ -3015,10 +3142,11 @@ |
michael@428 | 290 | |
michael@428 | 291 | rl_completion_entry_function = orig_func; |
michael@428 | 292 | rl_attempted_completion_function = orig_attempt_func; |
michael@428 | 293 | - rl_directory_rewrite_hook = orig_dir_func; |
michael@428 | 294 | rl_ignore_some_completions_function = orig_ignore_func; |
michael@428 | 295 | rl_completer_word_break_characters = orig_rl_completer_word_break_characters; |
michael@428 | 296 | |
michael@428 | 297 | + restore_directory_hook (orig_dir_func); |
michael@428 | 298 | + |
michael@428 | 299 | return r; |
michael@428 | 300 | } |
michael@428 | 301 | |
michael@428 | 302 | Index: bashline.h |
michael@428 | 303 | --- bashline.h.orig 2009-01-04 20:32:22.000000000 +0100 |
michael@428 | 304 | +++ bashline.h 2012-06-27 10:31:03.000000000 +0200 |
michael@428 | 305 | @@ -33,10 +33,15 @@ |
michael@428 | 306 | extern void bashline_reinitialize __P((void)); |
michael@428 | 307 | extern int bash_re_edit __P((char *)); |
michael@428 | 308 | |
michael@428 | 309 | +extern void bashline_set_event_hook __P((void)); |
michael@428 | 310 | +extern void bashline_reset_event_hook __P((void)); |
michael@428 | 311 | + |
michael@428 | 312 | extern int bind_keyseq_to_unix_command __P((char *)); |
michael@428 | 313 | |
michael@428 | 314 | extern char **bash_default_completion __P((const char *, int, int, int, int)); |
michael@428 | 315 | |
michael@428 | 316 | +void set_directory_hook __P((void)); |
michael@428 | 317 | + |
michael@428 | 318 | /* Used by programmable completion code. */ |
michael@428 | 319 | extern char *command_word_completion_function __P((const char *, int)); |
michael@428 | 320 | extern char *bash_groupname_completion_function __P((const char *, int)); |
michael@428 | 321 | Index: builtins/declare.def |
michael@428 | 322 | --- builtins/declare.def.orig 2010-05-31 00:25:21.000000000 +0200 |
michael@428 | 323 | +++ builtins/declare.def 2012-06-27 10:31:02.000000000 +0200 |
michael@428 | 324 | @@ -513,6 +513,11 @@ |
michael@428 | 325 | *subscript_start = '['; /* ] */ |
michael@428 | 326 | var = assign_array_element (name, value, 0); /* XXX - not aflags */ |
michael@428 | 327 | *subscript_start = '\0'; |
michael@428 | 328 | + if (var == 0) /* some kind of assignment error */ |
michael@428 | 329 | + { |
michael@428 | 330 | + assign_error++; |
michael@428 | 331 | + NEXT_VARIABLE (); |
michael@428 | 332 | + } |
michael@428 | 333 | } |
michael@428 | 334 | else if (simple_array_assign) |
michael@428 | 335 | { |
michael@428 | 336 | Index: builtins/fc.def |
michael@428 | 337 | --- builtins/fc.def.orig 2010-05-31 00:25:38.000000000 +0200 |
michael@428 | 338 | +++ builtins/fc.def 2012-06-27 10:31:02.000000000 +0200 |
michael@428 | 339 | @@ -304,7 +304,7 @@ |
michael@428 | 340 | last_hist = i - rh - hist_last_line_added; |
michael@428 | 341 | |
michael@428 | 342 | /* XXX */ |
michael@428 | 343 | - if (saved_command_line_count > 0 && i == last_hist && hlist[last_hist] == 0) |
michael@428 | 344 | + if (i == last_hist && hlist[last_hist] == 0) |
michael@428 | 345 | while (last_hist >= 0 && hlist[last_hist] == 0) |
michael@428 | 346 | last_hist--; |
michael@428 | 347 | if (last_hist < 0) |
michael@428 | 348 | @@ -475,7 +475,7 @@ |
michael@428 | 349 | HIST_ENTRY **hlist; |
michael@428 | 350 | { |
michael@428 | 351 | int sign, n, clen, rh; |
michael@428 | 352 | - register int i, j; |
michael@428 | 353 | + register int i, j, last_hist; |
michael@428 | 354 | register char *s; |
michael@428 | 355 | |
michael@428 | 356 | sign = 1; |
michael@428 | 357 | @@ -495,7 +495,15 @@ |
michael@428 | 358 | has been enabled (interactive or not) should use it in the last_hist |
michael@428 | 359 | calculation as if it were on. */ |
michael@428 | 360 | rh = remember_on_history || ((subshell_environment & SUBSHELL_COMSUB) && enable_history_list); |
michael@428 | 361 | - i -= rh + hist_last_line_added; |
michael@428 | 362 | + last_hist = i - rh - hist_last_line_added; |
michael@428 | 363 | + |
michael@428 | 364 | + if (i == last_hist && hlist[last_hist] == 0) |
michael@428 | 365 | + while (last_hist >= 0 && hlist[last_hist] == 0) |
michael@428 | 366 | + last_hist--; |
michael@428 | 367 | + if (last_hist < 0) |
michael@428 | 368 | + return (-1); |
michael@428 | 369 | + |
michael@428 | 370 | + i = last_hist; |
michael@428 | 371 | |
michael@428 | 372 | /* No specification defaults to most recent command. */ |
michael@428 | 373 | if (command == NULL) |
michael@428 | 374 | Index: builtins/printf.def |
michael@428 | 375 | --- builtins/printf.def.orig 2010-11-23 16:02:55.000000000 +0100 |
michael@428 | 376 | +++ builtins/printf.def 2012-06-27 10:31:02.000000000 +0200 |
michael@428 | 377 | @@ -255,6 +255,8 @@ |
michael@428 | 378 | #endif |
michael@428 | 379 | { |
michael@428 | 380 | vflag = 1; |
michael@428 | 381 | + if (vbsize == 0) |
michael@428 | 382 | + vbuf = xmalloc (vbsize = 16); |
michael@428 | 383 | vblen = 0; |
michael@428 | 384 | if (vbuf) |
michael@428 | 385 | vbuf[0] = 0; |
michael@428 | 386 | @@ -465,6 +467,9 @@ |
michael@428 | 387 | secs = shell_start_time; /* roughly $SECONDS */ |
michael@428 | 388 | else |
michael@428 | 389 | secs = arg; |
michael@428 | 390 | +#if defined (HAVE_TZSET) |
michael@428 | 391 | + sv_tz ("TZ"); /* XXX -- just make sure */ |
michael@428 | 392 | +#endif |
michael@428 | 393 | tm = localtime (&secs); |
michael@428 | 394 | n = strftime (timebuf, sizeof (timebuf), timefmt, tm); |
michael@428 | 395 | free (timefmt); |
michael@428 | 396 | Index: builtins/read.def |
michael@428 | 397 | --- builtins/read.def.orig 2011-01-04 17:43:36.000000000 +0100 |
michael@428 | 398 | +++ builtins/read.def 2012-06-27 10:31:02.000000000 +0200 |
michael@428 | 399 | @@ -642,6 +642,12 @@ |
michael@428 | 400 | xfree (input_string); |
michael@428 | 401 | return EXECUTION_FAILURE; /* readonly or noassign */ |
michael@428 | 402 | } |
michael@428 | 403 | + if (assoc_p (var)) |
michael@428 | 404 | + { |
michael@428 | 405 | + builtin_error (_("%s: cannot convert associative to indexed array"), arrayname); |
michael@428 | 406 | + xfree (input_string); |
michael@428 | 407 | + return EXECUTION_FAILURE; /* existing associative array */ |
michael@428 | 408 | + } |
michael@428 | 409 | array_flush (array_cell (var)); |
michael@428 | 410 | |
michael@428 | 411 | alist = list_string (input_string, ifs_chars, 0); |
michael@428 | 412 | @@ -731,7 +737,7 @@ |
michael@428 | 413 | xfree (t1); |
michael@428 | 414 | } |
michael@428 | 415 | else |
michael@428 | 416 | - var = bind_read_variable (varname, t); |
michael@428 | 417 | + var = bind_read_variable (varname, t ? t : ""); |
michael@428 | 418 | } |
michael@428 | 419 | else |
michael@428 | 420 | { |
michael@428 | 421 | @@ -792,7 +798,7 @@ |
michael@428 | 422 | xfree (t); |
michael@428 | 423 | } |
michael@428 | 424 | else |
michael@428 | 425 | - var = bind_read_variable (list->word->word, input_string); |
michael@428 | 426 | + var = bind_read_variable (list->word->word, input_string ? input_string : ""); |
michael@428 | 427 | |
michael@428 | 428 | if (var) |
michael@428 | 429 | { |
michael@428 | 430 | Index: builtins/shopt.def |
michael@428 | 431 | --- builtins/shopt.def.orig 2010-07-03 04:42:44.000000000 +0200 |
michael@428 | 432 | +++ builtins/shopt.def 2012-06-27 10:31:03.000000000 +0200 |
michael@428 | 433 | @@ -61,6 +61,10 @@ |
michael@428 | 434 | #include "common.h" |
michael@428 | 435 | #include "bashgetopt.h" |
michael@428 | 436 | |
michael@428 | 437 | +#if defined (READLINE) |
michael@428 | 438 | +# include "../bashline.h" |
michael@428 | 439 | +#endif |
michael@428 | 440 | + |
michael@428 | 441 | #if defined (HISTORY) |
michael@428 | 442 | # include "../bashhist.h" |
michael@428 | 443 | #endif |
michael@428 | 444 | @@ -94,7 +98,7 @@ |
michael@428 | 445 | extern int hist_verify, history_reediting, perform_hostname_completion; |
michael@428 | 446 | extern int no_empty_command_completion; |
michael@428 | 447 | extern int force_fignore; |
michael@428 | 448 | -extern int dircomplete_spelling; |
michael@428 | 449 | +extern int dircomplete_spelling, dircomplete_expand; |
michael@428 | 450 | |
michael@428 | 451 | extern int enable_hostname_completion __P((int)); |
michael@428 | 452 | #endif |
michael@428 | 453 | @@ -121,6 +125,10 @@ |
michael@428 | 454 | static int set_restricted_shell __P((char *, int)); |
michael@428 | 455 | #endif |
michael@428 | 456 | |
michael@428 | 457 | +#if defined (READLINE) |
michael@428 | 458 | +static int shopt_set_complete_direxpand __P((char *, int)); |
michael@428 | 459 | +#endif |
michael@428 | 460 | + |
michael@428 | 461 | static int shopt_login_shell; |
michael@428 | 462 | static int shopt_compat31; |
michael@428 | 463 | static int shopt_compat32; |
michael@428 | 464 | @@ -150,6 +158,7 @@ |
michael@428 | 465 | { "compat40", &shopt_compat40, set_compatibility_level }, |
michael@428 | 466 | { "compat41", &shopt_compat41, set_compatibility_level }, |
michael@428 | 467 | #if defined (READLINE) |
michael@428 | 468 | + { "direxpand", &dircomplete_expand, shopt_set_complete_direxpand }, |
michael@428 | 469 | { "dirspell", &dircomplete_spelling, (shopt_set_func_t *)NULL }, |
michael@428 | 470 | #endif |
michael@428 | 471 | { "dotglob", &glob_dot_filenames, (shopt_set_func_t *)NULL }, |
michael@428 | 472 | @@ -535,6 +544,17 @@ |
michael@428 | 473 | return 0; |
michael@428 | 474 | } |
michael@428 | 475 | |
michael@428 | 476 | +#if defined (READLINE) |
michael@428 | 477 | +static int |
michael@428 | 478 | +shopt_set_complete_direxpand (option_name, mode) |
michael@428 | 479 | + char *option_name; |
michael@428 | 480 | + int mode; |
michael@428 | 481 | +{ |
michael@428 | 482 | + set_directory_hook (); |
michael@428 | 483 | + return 0; |
michael@428 | 484 | +} |
michael@428 | 485 | +#endif |
michael@428 | 486 | + |
michael@428 | 487 | #if defined (RESTRICTED_SHELL) |
michael@428 | 488 | /* Don't allow the value of restricted_shell to be modified. */ |
michael@428 | 489 | |
michael@428 | 490 | Index: command.h |
michael@428 | 491 | --- command.h.orig 2010-08-03 01:36:51.000000000 +0200 |
michael@428 | 492 | +++ command.h 2012-06-27 10:31:02.000000000 +0200 |
michael@428 | 493 | @@ -97,6 +97,7 @@ |
michael@428 | 494 | #define W_HASCTLESC 0x200000 /* word contains literal CTLESC characters */ |
michael@428 | 495 | #define W_ASSIGNASSOC 0x400000 /* word looks like associative array assignment */ |
michael@428 | 496 | #define W_ARRAYIND 0x800000 /* word is an array index being expanded */ |
michael@428 | 497 | +#define W_ASSNGLOBAL 0x1000000 /* word is a global assignment to declare (declare/typeset -g) */ |
michael@428 | 498 | |
michael@428 | 499 | /* Possible values for subshell_environment */ |
michael@428 | 500 | #define SUBSHELL_ASYNC 0x01 /* subshell caused by `command &' */ |
michael@428 | 501 | Index: doc/bash.1 |
michael@428 | 502 | --- doc/bash.1.orig 2011-01-16 21:31:39.000000000 +0100 |
michael@428 | 503 | +++ doc/bash.1 2012-06-27 10:31:03.000000000 +0200 |
michael@431 | 504 | @@ -8954,6 +8954,16 @@ |
michael@428 | 505 | quoted. This is the behavior of posix mode through version 4.1. |
michael@428 | 506 | The default bash behavior remains as in previous versions. |
michael@428 | 507 | .TP 8 |
michael@428 | 508 | +.B direxpand |
michael@428 | 509 | +If set, |
michael@428 | 510 | +.B bash |
michael@428 | 511 | +replaces directory names with the results of word expansion when performing |
michael@428 | 512 | +filename completion. This changes the contents of the readline editing |
michael@428 | 513 | +buffer. |
michael@428 | 514 | +If not set, |
michael@428 | 515 | +.B bash |
michael@428 | 516 | +attempts to preserve what the user typed. |
michael@428 | 517 | +.TP 8 |
michael@428 | 518 | .B dirspell |
michael@428 | 519 | If set, |
michael@428 | 520 | .B bash |
michael@428 | 521 | Index: doc/bashref.texi |
michael@428 | 522 | --- doc/bashref.texi.orig 2011-01-16 21:31:57.000000000 +0100 |
michael@428 | 523 | +++ doc/bashref.texi 2012-06-27 10:31:03.000000000 +0200 |
michael@428 | 524 | @@ -4535,6 +4535,13 @@ |
michael@428 | 525 | quoted. This is the behavior of @sc{posix} mode through version 4.1. |
michael@428 | 526 | The default Bash behavior remains as in previous versions. |
michael@428 | 527 | |
michael@428 | 528 | +@item direxpand |
michael@428 | 529 | +If set, Bash |
michael@428 | 530 | +replaces directory names with the results of word expansion when performing |
michael@428 | 531 | +filename completion. This changes the contents of the readline editing |
michael@428 | 532 | +buffer. |
michael@428 | 533 | +If not set, Bash attempts to preserve what the user typed. |
michael@428 | 534 | + |
michael@428 | 535 | @item dirspell |
michael@428 | 536 | If set, Bash |
michael@428 | 537 | attempts spelling correction on directory names during word completion |
michael@428 | 538 | Index: error.c |
michael@428 | 539 | --- error.c.orig 2009-08-22 04:31:31.000000000 +0200 |
michael@428 | 540 | +++ error.c 2012-06-27 10:31:02.000000000 +0200 |
michael@428 | 541 | @@ -200,7 +200,11 @@ |
michael@428 | 542 | |
michael@428 | 543 | va_end (args); |
michael@428 | 544 | if (exit_immediately_on_error) |
michael@428 | 545 | - exit_shell (1); |
michael@428 | 546 | + { |
michael@428 | 547 | + if (last_command_exit_value == 0) |
michael@428 | 548 | + last_command_exit_value = 1; |
michael@428 | 549 | + exit_shell (last_command_exit_value); |
michael@428 | 550 | + } |
michael@428 | 551 | } |
michael@428 | 552 | |
michael@428 | 553 | void |
michael@428 | 554 | Index: execute_cmd.c |
michael@428 | 555 | --- execute_cmd.c.orig 2011-02-09 23:32:25.000000000 +0100 |
michael@428 | 556 | +++ execute_cmd.c 2012-06-27 10:31:03.000000000 +0200 |
michael@428 | 557 | @@ -2196,6 +2196,7 @@ |
michael@428 | 558 | if (ignore_return && cmd) |
michael@428 | 559 | cmd->flags |= CMD_IGNORE_RETURN; |
michael@428 | 560 | |
michael@428 | 561 | +#if defined (JOB_CONTROL) |
michael@428 | 562 | lastpipe_flag = 0; |
michael@428 | 563 | begin_unwind_frame ("lastpipe-exec"); |
michael@428 | 564 | lstdin = -1; |
michael@428 | 565 | @@ -2204,7 +2205,7 @@ |
michael@428 | 566 | current shell environment. */ |
michael@428 | 567 | if (lastpipe_opt && job_control == 0 && asynchronous == 0 && pipe_out == NO_PIPE && prev > 0) |
michael@428 | 568 | { |
michael@428 | 569 | - lstdin = move_to_high_fd (0, 0, 255); |
michael@428 | 570 | + lstdin = move_to_high_fd (0, 1, -1); |
michael@428 | 571 | if (lstdin > 0) |
michael@428 | 572 | { |
michael@428 | 573 | do_piping (prev, pipe_out); |
michael@428 | 574 | @@ -2215,15 +2216,19 @@ |
michael@428 | 575 | lastpipe_jid = stop_pipeline (0, (COMMAND *)NULL); /* XXX */ |
michael@428 | 576 | add_unwind_protect (lastpipe_cleanup, lastpipe_jid); |
michael@428 | 577 | } |
michael@428 | 578 | - cmd->flags |= CMD_LASTPIPE; |
michael@428 | 579 | + if (cmd) |
michael@428 | 580 | + cmd->flags |= CMD_LASTPIPE; |
michael@428 | 581 | } |
michael@428 | 582 | if (prev >= 0) |
michael@428 | 583 | add_unwind_protect (close, prev); |
michael@428 | 584 | +#endif |
michael@428 | 585 | |
michael@428 | 586 | exec_result = execute_command_internal (cmd, asynchronous, prev, pipe_out, fds_to_close); |
michael@428 | 587 | |
michael@428 | 588 | +#if defined (JOB_CONTROL) |
michael@428 | 589 | if (lstdin > 0) |
michael@428 | 590 | restore_stdin (lstdin); |
michael@428 | 591 | +#endif |
michael@428 | 592 | |
michael@428 | 593 | if (prev >= 0) |
michael@428 | 594 | close (prev); |
michael@428 | 595 | @@ -2246,7 +2251,9 @@ |
michael@428 | 596 | unfreeze_jobs_list (); |
michael@428 | 597 | } |
michael@428 | 598 | |
michael@428 | 599 | +#if defined (JOB_CONTROL) |
michael@428 | 600 | discard_unwind_frame ("lastpipe-exec"); |
michael@428 | 601 | +#endif |
michael@428 | 602 | |
michael@428 | 603 | return (exec_result); |
michael@428 | 604 | } |
michael@428 | 605 | @@ -3575,13 +3582,13 @@ |
michael@428 | 606 | { |
michael@428 | 607 | WORD_LIST *w; |
michael@428 | 608 | struct builtin *b; |
michael@428 | 609 | - int assoc; |
michael@428 | 610 | + int assoc, global; |
michael@428 | 611 | |
michael@428 | 612 | if (words == 0) |
michael@428 | 613 | return; |
michael@428 | 614 | |
michael@428 | 615 | b = 0; |
michael@428 | 616 | - assoc = 0; |
michael@428 | 617 | + assoc = global = 0; |
michael@428 | 618 | |
michael@428 | 619 | for (w = words; w; w = w->next) |
michael@428 | 620 | if (w->word->flags & W_ASSIGNMENT) |
michael@428 | 621 | @@ -3598,12 +3605,17 @@ |
michael@428 | 622 | #if defined (ARRAY_VARS) |
michael@428 | 623 | if (assoc) |
michael@428 | 624 | w->word->flags |= W_ASSIGNASSOC; |
michael@428 | 625 | + if (global) |
michael@428 | 626 | + w->word->flags |= W_ASSNGLOBAL; |
michael@428 | 627 | #endif |
michael@428 | 628 | } |
michael@428 | 629 | #if defined (ARRAY_VARS) |
michael@428 | 630 | /* Note that we saw an associative array option to a builtin that takes |
michael@428 | 631 | assignment statements. This is a bit of a kludge. */ |
michael@428 | 632 | - else if (w->word->word[0] == '-' && strchr (w->word->word, 'A')) |
michael@428 | 633 | + else if (w->word->word[0] == '-' && (strchr (w->word->word+1, 'A') || strchr (w->word->word+1, 'g'))) |
michael@428 | 634 | +#else |
michael@428 | 635 | + else if (w->word->word[0] == '-' && strchr (w->word->word+1, 'g')) |
michael@428 | 636 | +#endif |
michael@428 | 637 | { |
michael@428 | 638 | if (b == 0) |
michael@428 | 639 | { |
michael@428 | 640 | @@ -3613,10 +3625,11 @@ |
michael@428 | 641 | else if (b && (b->flags & ASSIGNMENT_BUILTIN)) |
michael@428 | 642 | words->word->flags |= W_ASSNBLTIN; |
michael@428 | 643 | } |
michael@428 | 644 | - if (words->word->flags & W_ASSNBLTIN) |
michael@428 | 645 | + if ((words->word->flags & W_ASSNBLTIN) && strchr (w->word->word+1, 'A')) |
michael@428 | 646 | assoc = 1; |
michael@428 | 647 | + if ((words->word->flags & W_ASSNBLTIN) && strchr (w->word->word+1, 'g')) |
michael@428 | 648 | + global = 1; |
michael@428 | 649 | } |
michael@428 | 650 | -#endif |
michael@428 | 651 | } |
michael@428 | 652 | |
michael@428 | 653 | /* Return 1 if the file found by searching $PATH for PATHNAME, defaulting |
michael@428 | 654 | Index: expr.c |
michael@428 | 655 | --- expr.c.orig 2010-12-21 17:12:13.000000000 +0100 |
michael@428 | 656 | +++ expr.c 2012-06-27 10:31:02.000000000 +0200 |
michael@428 | 657 | @@ -476,19 +476,23 @@ |
michael@428 | 658 | |
michael@428 | 659 | if (special) |
michael@428 | 660 | { |
michael@428 | 661 | + if ((op == DIV || op == MOD) && value == 0) |
michael@428 | 662 | + { |
michael@428 | 663 | + if (noeval == 0) |
michael@428 | 664 | + evalerror (_("division by 0")); |
michael@428 | 665 | + else |
michael@428 | 666 | + value = 1; |
michael@428 | 667 | + } |
michael@428 | 668 | + |
michael@428 | 669 | switch (op) |
michael@428 | 670 | { |
michael@428 | 671 | case MUL: |
michael@428 | 672 | lvalue *= value; |
michael@428 | 673 | break; |
michael@428 | 674 | case DIV: |
michael@428 | 675 | - if (value == 0) |
michael@428 | 676 | - evalerror (_("division by 0")); |
michael@428 | 677 | lvalue /= value; |
michael@428 | 678 | break; |
michael@428 | 679 | case MOD: |
michael@428 | 680 | - if (value == 0) |
michael@428 | 681 | - evalerror (_("division by 0")); |
michael@428 | 682 | lvalue %= value; |
michael@428 | 683 | break; |
michael@428 | 684 | case PLUS: |
michael@428 | 685 | @@ -804,7 +808,12 @@ |
michael@428 | 686 | val2 = exppower (); |
michael@428 | 687 | |
michael@428 | 688 | if (((op == DIV) || (op == MOD)) && (val2 == 0)) |
michael@428 | 689 | - evalerror (_("division by 0")); |
michael@428 | 690 | + { |
michael@428 | 691 | + if (noeval == 0) |
michael@428 | 692 | + evalerror (_("division by 0")); |
michael@428 | 693 | + else |
michael@428 | 694 | + val2 = 1; |
michael@428 | 695 | + } |
michael@428 | 696 | |
michael@428 | 697 | if (op == MUL) |
michael@428 | 698 | val1 *= val2; |
michael@428 | 699 | Index: lib/glob/gmisc.c |
michael@428 | 700 | --- lib/glob/gmisc.c.orig 2011-02-05 22:11:17.000000000 +0100 |
michael@428 | 701 | +++ lib/glob/gmisc.c 2012-06-27 10:31:02.000000000 +0200 |
michael@428 | 702 | @@ -77,8 +77,8 @@ |
michael@428 | 703 | wchar_t *wpat; |
michael@428 | 704 | size_t wmax; |
michael@428 | 705 | { |
michael@428 | 706 | - wchar_t wc, *wbrack; |
michael@428 | 707 | - int matlen, t, in_cclass, in_collsym, in_equiv; |
michael@428 | 708 | + wchar_t wc; |
michael@428 | 709 | + int matlen, bracklen, t, in_cclass, in_collsym, in_equiv; |
michael@428 | 710 | |
michael@428 | 711 | if (*wpat == 0) |
michael@428 | 712 | return (0); |
michael@428 | 713 | @@ -118,58 +118,80 @@ |
michael@428 | 714 | break; |
michael@428 | 715 | case L'[': |
michael@428 | 716 | /* scan for ending `]', skipping over embedded [:...:] */ |
michael@428 | 717 | - wbrack = wpat; |
michael@428 | 718 | + bracklen = 1; |
michael@428 | 719 | wc = *wpat++; |
michael@428 | 720 | do |
michael@428 | 721 | { |
michael@428 | 722 | if (wc == 0) |
michael@428 | 723 | { |
michael@428 | 724 | - matlen += wpat - wbrack - 1; /* incremented below */ |
michael@428 | 725 | - break; |
michael@428 | 726 | + wpat--; /* back up to NUL */ |
michael@428 | 727 | + matlen += bracklen; |
michael@428 | 728 | + goto bad_bracket; |
michael@428 | 729 | } |
michael@428 | 730 | else if (wc == L'\\') |
michael@428 | 731 | { |
michael@428 | 732 | - wc = *wpat++; |
michael@428 | 733 | - if (*wpat == 0) |
michael@428 | 734 | - break; |
michael@428 | 735 | + /* *wpat == backslash-escaped character */ |
michael@428 | 736 | + bracklen++; |
michael@428 | 737 | + /* If the backslash or backslash-escape ends the string, |
michael@428 | 738 | + bail. The ++wpat skips over the backslash escape */ |
michael@428 | 739 | + if (*wpat == 0 || *++wpat == 0) |
michael@428 | 740 | + { |
michael@428 | 741 | + matlen += bracklen; |
michael@428 | 742 | + goto bad_bracket; |
michael@428 | 743 | + } |
michael@428 | 744 | } |
michael@428 | 745 | else if (wc == L'[' && *wpat == L':') /* character class */ |
michael@428 | 746 | { |
michael@428 | 747 | wpat++; |
michael@428 | 748 | + bracklen++; |
michael@428 | 749 | in_cclass = 1; |
michael@428 | 750 | } |
michael@428 | 751 | else if (in_cclass && wc == L':' && *wpat == L']') |
michael@428 | 752 | { |
michael@428 | 753 | wpat++; |
michael@428 | 754 | + bracklen++; |
michael@428 | 755 | in_cclass = 0; |
michael@428 | 756 | } |
michael@428 | 757 | else if (wc == L'[' && *wpat == L'.') /* collating symbol */ |
michael@428 | 758 | { |
michael@428 | 759 | wpat++; |
michael@428 | 760 | + bracklen++; |
michael@428 | 761 | if (*wpat == L']') /* right bracket can appear as collating symbol */ |
michael@428 | 762 | - wpat++; |
michael@428 | 763 | + { |
michael@428 | 764 | + wpat++; |
michael@428 | 765 | + bracklen++; |
michael@428 | 766 | + } |
michael@428 | 767 | in_collsym = 1; |
michael@428 | 768 | } |
michael@428 | 769 | else if (in_collsym && wc == L'.' && *wpat == L']') |
michael@428 | 770 | { |
michael@428 | 771 | wpat++; |
michael@428 | 772 | + bracklen++; |
michael@428 | 773 | in_collsym = 0; |
michael@428 | 774 | } |
michael@428 | 775 | else if (wc == L'[' && *wpat == L'=') /* equivalence class */ |
michael@428 | 776 | { |
michael@428 | 777 | wpat++; |
michael@428 | 778 | + bracklen++; |
michael@428 | 779 | if (*wpat == L']') /* right bracket can appear as equivalence class */ |
michael@428 | 780 | - wpat++; |
michael@428 | 781 | + { |
michael@428 | 782 | + wpat++; |
michael@428 | 783 | + bracklen++; |
michael@428 | 784 | + } |
michael@428 | 785 | in_equiv = 1; |
michael@428 | 786 | } |
michael@428 | 787 | else if (in_equiv && wc == L'=' && *wpat == L']') |
michael@428 | 788 | { |
michael@428 | 789 | wpat++; |
michael@428 | 790 | + bracklen++; |
michael@428 | 791 | in_equiv = 0; |
michael@428 | 792 | } |
michael@428 | 793 | + else |
michael@428 | 794 | + bracklen++; |
michael@428 | 795 | } |
michael@428 | 796 | while ((wc = *wpat++) != L']'); |
michael@428 | 797 | matlen++; /* bracket expression can only match one char */ |
michael@428 | 798 | +bad_bracket: |
michael@428 | 799 | break; |
michael@428 | 800 | } |
michael@428 | 801 | } |
michael@428 | 802 | @@ -213,8 +235,8 @@ |
michael@428 | 803 | char *pat; |
michael@428 | 804 | size_t max; |
michael@428 | 805 | { |
michael@428 | 806 | - char c, *brack; |
michael@428 | 807 | - int matlen, t, in_cclass, in_collsym, in_equiv; |
michael@428 | 808 | + char c; |
michael@428 | 809 | + int matlen, bracklen, t, in_cclass, in_collsym, in_equiv; |
michael@428 | 810 | |
michael@428 | 811 | if (*pat == 0) |
michael@428 | 812 | return (0); |
michael@428 | 813 | @@ -254,58 +276,80 @@ |
michael@428 | 814 | break; |
michael@428 | 815 | case '[': |
michael@428 | 816 | /* scan for ending `]', skipping over embedded [:...:] */ |
michael@428 | 817 | - brack = pat; |
michael@428 | 818 | + bracklen = 1; |
michael@428 | 819 | c = *pat++; |
michael@428 | 820 | do |
michael@428 | 821 | { |
michael@428 | 822 | if (c == 0) |
michael@428 | 823 | { |
michael@428 | 824 | - matlen += pat - brack - 1; /* incremented below */ |
michael@428 | 825 | - break; |
michael@428 | 826 | + pat--; /* back up to NUL */ |
michael@428 | 827 | + matlen += bracklen; |
michael@428 | 828 | + goto bad_bracket; |
michael@428 | 829 | } |
michael@428 | 830 | else if (c == '\\') |
michael@428 | 831 | { |
michael@428 | 832 | - c = *pat++; |
michael@428 | 833 | - if (*pat == 0) |
michael@428 | 834 | - break; |
michael@428 | 835 | + /* *pat == backslash-escaped character */ |
michael@428 | 836 | + bracklen++; |
michael@428 | 837 | + /* If the backslash or backslash-escape ends the string, |
michael@428 | 838 | + bail. The ++pat skips over the backslash escape */ |
michael@428 | 839 | + if (*pat == 0 || *++pat == 0) |
michael@428 | 840 | + { |
michael@428 | 841 | + matlen += bracklen; |
michael@428 | 842 | + goto bad_bracket; |
michael@428 | 843 | + } |
michael@428 | 844 | } |
michael@428 | 845 | else if (c == '[' && *pat == ':') /* character class */ |
michael@428 | 846 | { |
michael@428 | 847 | pat++; |
michael@428 | 848 | + bracklen++; |
michael@428 | 849 | in_cclass = 1; |
michael@428 | 850 | } |
michael@428 | 851 | else if (in_cclass && c == ':' && *pat == ']') |
michael@428 | 852 | { |
michael@428 | 853 | pat++; |
michael@428 | 854 | + bracklen++; |
michael@428 | 855 | in_cclass = 0; |
michael@428 | 856 | } |
michael@428 | 857 | else if (c == '[' && *pat == '.') /* collating symbol */ |
michael@428 | 858 | { |
michael@428 | 859 | pat++; |
michael@428 | 860 | + bracklen++; |
michael@428 | 861 | if (*pat == ']') /* right bracket can appear as collating symbol */ |
michael@428 | 862 | - pat++; |
michael@428 | 863 | + { |
michael@428 | 864 | + pat++; |
michael@428 | 865 | + bracklen++; |
michael@428 | 866 | + } |
michael@428 | 867 | in_collsym = 1; |
michael@428 | 868 | } |
michael@428 | 869 | else if (in_collsym && c == '.' && *pat == ']') |
michael@428 | 870 | { |
michael@428 | 871 | pat++; |
michael@428 | 872 | + bracklen++; |
michael@428 | 873 | in_collsym = 0; |
michael@428 | 874 | } |
michael@428 | 875 | else if (c == '[' && *pat == '=') /* equivalence class */ |
michael@428 | 876 | { |
michael@428 | 877 | pat++; |
michael@428 | 878 | + bracklen++; |
michael@428 | 879 | if (*pat == ']') /* right bracket can appear as equivalence class */ |
michael@428 | 880 | - pat++; |
michael@428 | 881 | + { |
michael@428 | 882 | + pat++; |
michael@428 | 883 | + bracklen++; |
michael@428 | 884 | + } |
michael@428 | 885 | in_equiv = 1; |
michael@428 | 886 | } |
michael@428 | 887 | else if (in_equiv && c == '=' && *pat == ']') |
michael@428 | 888 | { |
michael@428 | 889 | pat++; |
michael@428 | 890 | + bracklen++; |
michael@428 | 891 | in_equiv = 0; |
michael@428 | 892 | } |
michael@428 | 893 | + else |
michael@428 | 894 | + bracklen++; |
michael@428 | 895 | } |
michael@428 | 896 | while ((c = *pat++) != ']'); |
michael@428 | 897 | matlen++; /* bracket expression can only match one char */ |
michael@428 | 898 | +bad_bracket: |
michael@428 | 899 | break; |
michael@428 | 900 | } |
michael@428 | 901 | } |
michael@428 | 902 | Index: lib/readline/callback.c |
michael@428 | 903 | --- lib/readline/callback.c.orig 2010-06-06 18:18:58.000000000 +0200 |
michael@428 | 904 | +++ lib/readline/callback.c 2012-06-27 10:31:02.000000000 +0200 |
michael@428 | 905 | @@ -148,6 +148,9 @@ |
michael@428 | 906 | eof = _rl_vi_domove_callback (_rl_vimvcxt); |
michael@428 | 907 | /* Should handle everything, including cleanup, numeric arguments, |
michael@428 | 908 | and turning off RL_STATE_VIMOTION */ |
michael@428 | 909 | + if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0) |
michael@428 | 910 | + _rl_internal_char_cleanup (); |
michael@428 | 911 | + |
michael@428 | 912 | return; |
michael@428 | 913 | } |
michael@428 | 914 | #endif |
michael@428 | 915 | Index: lib/readline/vi_mode.c |
michael@428 | 916 | --- lib/readline/vi_mode.c.orig 2010-11-21 01:51:39.000000000 +0100 |
michael@428 | 917 | +++ lib/readline/vi_mode.c 2012-06-27 10:31:02.000000000 +0200 |
michael@428 | 918 | @@ -1114,7 +1114,7 @@ |
michael@428 | 919 | rl_beg_of_line (1, c); |
michael@428 | 920 | _rl_vi_last_motion = c; |
michael@428 | 921 | RL_UNSETSTATE (RL_STATE_VIMOTION); |
michael@428 | 922 | - return (0); |
michael@428 | 923 | + return (vidomove_dispatch (m)); |
michael@428 | 924 | } |
michael@428 | 925 | #if defined (READLINE_CALLBACKS) |
michael@428 | 926 | /* XXX - these need to handle rl_universal_argument bindings */ |
michael@428 | 927 | Index: lib/sh/zread.c |
michael@428 | 928 | --- lib/sh/zread.c.orig 2009-03-02 14:54:45.000000000 +0100 |
michael@428 | 929 | +++ lib/sh/zread.c 2012-06-27 10:31:02.000000000 +0200 |
michael@428 | 930 | @@ -160,14 +160,13 @@ |
michael@428 | 931 | zsyncfd (fd) |
michael@428 | 932 | int fd; |
michael@428 | 933 | { |
michael@428 | 934 | - off_t off; |
michael@428 | 935 | - int r; |
michael@428 | 936 | + off_t off, r; |
michael@428 | 937 | |
michael@428 | 938 | off = lused - lind; |
michael@428 | 939 | r = 0; |
michael@428 | 940 | if (off > 0) |
michael@428 | 941 | r = lseek (fd, -off, SEEK_CUR); |
michael@428 | 942 | |
michael@428 | 943 | - if (r >= 0) |
michael@428 | 944 | + if (r != -1) |
michael@428 | 945 | lused = lind = 0; |
michael@428 | 946 | } |
michael@428 | 947 | Index: parse.y |
michael@428 | 948 | --- parse.y.orig 2011-01-02 21:48:11.000000000 +0100 |
michael@428 | 949 | +++ parse.y 2012-06-27 10:31:02.000000000 +0200 |
michael@428 | 950 | @@ -2499,7 +2499,7 @@ |
michael@428 | 951 | We do this only if it is time to do so. Notice that only here |
michael@428 | 952 | is the mail alarm reset; nothing takes place in check_mail () |
michael@428 | 953 | except the checking of mail. Please don't change this. */ |
michael@428 | 954 | - if (prompt_is_ps1 && time_to_check_mail ()) |
michael@428 | 955 | + if (prompt_is_ps1 && parse_and_execute_level == 0 && time_to_check_mail ()) |
michael@428 | 956 | { |
michael@428 | 957 | check_mail (); |
michael@428 | 958 | reset_mail_timer (); |
michael@428 | 959 | @@ -3842,6 +3842,7 @@ |
michael@428 | 960 | int flags; |
michael@428 | 961 | { |
michael@428 | 962 | sh_parser_state_t ps; |
michael@428 | 963 | + sh_input_line_state_t ls; |
michael@428 | 964 | int orig_ind, nc, sflags; |
michael@428 | 965 | char *ret, *s, *ep, *ostring; |
michael@428 | 966 | |
michael@428 | 967 | @@ -3849,10 +3850,12 @@ |
michael@428 | 968 | orig_ind = *indp; |
michael@428 | 969 | ostring = string; |
michael@428 | 970 | |
michael@428 | 971 | +/*itrace("xparse_dolparen: size = %d shell_input_line = `%s'", shell_input_line_size, shell_input_line);*/ |
michael@428 | 972 | sflags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOFREE; |
michael@428 | 973 | if (flags & SX_NOLONGJMP) |
michael@428 | 974 | sflags |= SEVAL_NOLONGJMP; |
michael@428 | 975 | save_parser_state (&ps); |
michael@428 | 976 | + save_input_line_state (&ls); |
michael@428 | 977 | |
michael@428 | 978 | /*(*/ |
michael@428 | 979 | parser_state |= PST_CMDSUBST|PST_EOFTOKEN; /* allow instant ')' */ /*(*/ |
michael@428 | 980 | @@ -3861,6 +3864,8 @@ |
michael@428 | 981 | |
michael@428 | 982 | restore_parser_state (&ps); |
michael@428 | 983 | reset_parser (); |
michael@428 | 984 | + /* reset_parser clears shell_input_line and associated variables */ |
michael@428 | 985 | + restore_input_line_state (&ls); |
michael@428 | 986 | if (interactive) |
michael@428 | 987 | token_to_read = 0; |
michael@428 | 988 | |
michael@428 | 989 | @@ -5135,6 +5140,9 @@ |
michael@428 | 990 | case 'A': |
michael@428 | 991 | /* Make the current time/date into a string. */ |
michael@428 | 992 | (void) time (&the_time); |
michael@428 | 993 | +#if defined (HAVE_TZSET) |
michael@428 | 994 | + sv_tz ("TZ"); /* XXX -- just make sure */ |
michael@428 | 995 | +#endif |
michael@428 | 996 | tm = localtime (&the_time); |
michael@428 | 997 | |
michael@428 | 998 | if (c == 'd') |
michael@428 | 999 | @@ -5905,6 +5913,12 @@ |
michael@428 | 1000 | ps->expand_aliases = expand_aliases; |
michael@428 | 1001 | ps->echo_input_at_read = echo_input_at_read; |
michael@428 | 1002 | |
michael@428 | 1003 | + ps->token = token; |
michael@428 | 1004 | + ps->token_buffer_size = token_buffer_size; |
michael@428 | 1005 | + /* Force reallocation on next call to read_token_word */ |
michael@428 | 1006 | + token = 0; |
michael@428 | 1007 | + token_buffer_size = 0; |
michael@428 | 1008 | + |
michael@428 | 1009 | return (ps); |
michael@428 | 1010 | } |
michael@428 | 1011 | |
michael@428 | 1012 | @@ -5946,6 +5960,42 @@ |
michael@428 | 1013 | |
michael@428 | 1014 | expand_aliases = ps->expand_aliases; |
michael@428 | 1015 | echo_input_at_read = ps->echo_input_at_read; |
michael@428 | 1016 | + |
michael@428 | 1017 | + FREE (token); |
michael@428 | 1018 | + token = ps->token; |
michael@428 | 1019 | + token_buffer_size = ps->token_buffer_size; |
michael@428 | 1020 | +} |
michael@428 | 1021 | + |
michael@428 | 1022 | +sh_input_line_state_t * |
michael@428 | 1023 | +save_input_line_state (ls) |
michael@428 | 1024 | + sh_input_line_state_t *ls; |
michael@428 | 1025 | +{ |
michael@428 | 1026 | + if (ls == 0) |
michael@428 | 1027 | + ls = (sh_input_line_state_t *)xmalloc (sizeof (sh_input_line_state_t)); |
michael@428 | 1028 | + if (ls == 0) |
michael@428 | 1029 | + return ((sh_input_line_state_t *)NULL); |
michael@428 | 1030 | + |
michael@428 | 1031 | + ls->input_line = shell_input_line; |
michael@428 | 1032 | + ls->input_line_size = shell_input_line_size; |
michael@428 | 1033 | + ls->input_line_len = shell_input_line_len; |
michael@428 | 1034 | + ls->input_line_index = shell_input_line_index; |
michael@428 | 1035 | + |
michael@428 | 1036 | + /* force reallocation */ |
michael@428 | 1037 | + shell_input_line = 0; |
michael@428 | 1038 | + shell_input_line_size = shell_input_line_len = shell_input_line_index = 0; |
michael@428 | 1039 | +} |
michael@428 | 1040 | + |
michael@428 | 1041 | +void |
michael@428 | 1042 | +restore_input_line_state (ls) |
michael@428 | 1043 | + sh_input_line_state_t *ls; |
michael@428 | 1044 | +{ |
michael@428 | 1045 | + FREE (shell_input_line); |
michael@428 | 1046 | + shell_input_line = ls->input_line; |
michael@428 | 1047 | + shell_input_line_size = ls->input_line_size; |
michael@428 | 1048 | + shell_input_line_len = ls->input_line_len; |
michael@428 | 1049 | + shell_input_line_index = ls->input_line_index; |
michael@428 | 1050 | + |
michael@428 | 1051 | + set_line_mbstate (); |
michael@428 | 1052 | } |
michael@428 | 1053 | |
michael@428 | 1054 | /************************************************ |
michael@428 | 1055 | Index: patchlevel.h |
michael@428 | 1056 | --- patchlevel.h.orig 2010-06-13 02:14:48.000000000 +0200 |
michael@428 | 1057 | +++ patchlevel.h 2012-06-27 10:31:03.000000000 +0200 |
michael@428 | 1058 | @@ -25,6 +25,6 @@ |
michael@428 | 1059 | regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh |
michael@428 | 1060 | looks for to find the patch level (for the sccs version string). */ |
michael@428 | 1061 | |
michael@428 | 1062 | -#define PATCHLEVEL 0 |
michael@428 | 1063 | +#define PATCHLEVEL 29 |
michael@428 | 1064 | |
michael@428 | 1065 | #endif /* _PATCHLEVEL_H_ */ |
michael@428 | 1066 | Index: pathexp.c |
michael@428 | 1067 | --- pathexp.c.orig 2010-08-14 05:21:57.000000000 +0200 |
michael@428 | 1068 | +++ pathexp.c 2012-06-27 10:31:02.000000000 +0200 |
michael@428 | 1069 | @@ -196,7 +196,7 @@ |
michael@428 | 1070 | { |
michael@428 | 1071 | if ((qflags & QGLOB_FILENAME) && pathname[i+1] == '/') |
michael@428 | 1072 | continue; |
michael@428 | 1073 | - if ((qflags & QGLOB_REGEXP) && ere_char (pathname[i+1]) == 0) |
michael@428 | 1074 | + if (pathname[i+1] != CTLESC && (qflags & QGLOB_REGEXP) && ere_char (pathname[i+1]) == 0) |
michael@428 | 1075 | continue; |
michael@428 | 1076 | temp[j++] = '\\'; |
michael@428 | 1077 | i++; |
michael@428 | 1078 | Index: print_cmd.c |
michael@428 | 1079 | --- print_cmd.c.orig 2010-05-31 00:34:08.000000000 +0200 |
michael@428 | 1080 | +++ print_cmd.c 2012-06-27 10:31:02.000000000 +0200 |
michael@428 | 1081 | @@ -315,6 +315,7 @@ |
michael@428 | 1082 | cprintf ("( "); |
michael@428 | 1083 | skip_this_indent++; |
michael@428 | 1084 | make_command_string_internal (command->value.Subshell->command); |
michael@428 | 1085 | + PRINT_DEFERRED_HEREDOCS (""); |
michael@428 | 1086 | cprintf (" )"); |
michael@428 | 1087 | break; |
michael@428 | 1088 | |
michael@428 | 1089 | @@ -592,6 +593,7 @@ |
michael@428 | 1090 | newline ("do\n"); |
michael@428 | 1091 | indentation += indentation_amount; |
michael@428 | 1092 | make_command_string_internal (arith_for_command->action); |
michael@428 | 1093 | + PRINT_DEFERRED_HEREDOCS (""); |
michael@428 | 1094 | semicolon (); |
michael@428 | 1095 | indentation -= indentation_amount; |
michael@428 | 1096 | newline ("done"); |
michael@428 | 1097 | @@ -653,6 +655,7 @@ |
michael@428 | 1098 | } |
michael@428 | 1099 | |
michael@428 | 1100 | make_command_string_internal (group_command->command); |
michael@428 | 1101 | + PRINT_DEFERRED_HEREDOCS (""); |
michael@428 | 1102 | |
michael@428 | 1103 | if (inside_function_def) |
michael@428 | 1104 | { |
michael@428 | 1105 | Index: shell.h |
michael@428 | 1106 | --- shell.h.orig 2011-01-07 04:16:55.000000000 +0100 |
michael@428 | 1107 | +++ shell.h 2012-06-27 10:31:02.000000000 +0200 |
michael@428 | 1108 | @@ -136,6 +136,9 @@ |
michael@428 | 1109 | int parser_state; |
michael@428 | 1110 | int *token_state; |
michael@428 | 1111 | |
michael@428 | 1112 | + char *token; |
michael@428 | 1113 | + int token_buffer_size; |
michael@428 | 1114 | + |
michael@428 | 1115 | /* input line state -- line number saved elsewhere */ |
michael@428 | 1116 | int input_line_terminator; |
michael@428 | 1117 | int eof_encountered; |
michael@428 | 1118 | @@ -166,6 +169,16 @@ |
michael@428 | 1119 | |
michael@428 | 1120 | } sh_parser_state_t; |
michael@428 | 1121 | |
michael@428 | 1122 | +typedef struct _sh_input_line_state_t { |
michael@428 | 1123 | + char *input_line; |
michael@428 | 1124 | + int input_line_index; |
michael@428 | 1125 | + int input_line_size; |
michael@428 | 1126 | + int input_line_len; |
michael@428 | 1127 | +} sh_input_line_state_t; |
michael@428 | 1128 | + |
michael@428 | 1129 | /* Let's try declaring these here. */ |
michael@428 | 1130 | extern sh_parser_state_t *save_parser_state __P((sh_parser_state_t *)); |
michael@428 | 1131 | extern void restore_parser_state __P((sh_parser_state_t *)); |
michael@428 | 1132 | + |
michael@428 | 1133 | +extern sh_input_line_state_t *save_input_line_state __P((sh_input_line_state_t *)); |
michael@428 | 1134 | +extern void restore_input_line_state __P((sh_input_line_state_t *)); |
michael@428 | 1135 | Index: sig.c |
michael@428 | 1136 | --- sig.c.orig 2010-11-23 14:21:22.000000000 +0100 |
michael@428 | 1137 | +++ sig.c 2012-06-27 10:31:02.000000000 +0200 |
michael@428 | 1138 | @@ -46,6 +46,7 @@ |
michael@428 | 1139 | |
michael@428 | 1140 | #if defined (READLINE) |
michael@428 | 1141 | # include "bashline.h" |
michael@428 | 1142 | +# include <readline/readline.h> |
michael@428 | 1143 | #endif |
michael@428 | 1144 | |
michael@428 | 1145 | #if defined (HISTORY) |
michael@428 | 1146 | @@ -62,6 +63,7 @@ |
michael@428 | 1147 | #if defined (HISTORY) |
michael@428 | 1148 | extern int history_lines_this_session; |
michael@428 | 1149 | #endif |
michael@428 | 1150 | +extern int no_line_editing; |
michael@428 | 1151 | |
michael@428 | 1152 | extern void initialize_siglist (); |
michael@428 | 1153 | |
michael@428 | 1154 | @@ -505,7 +507,10 @@ |
michael@428 | 1155 | { |
michael@428 | 1156 | #if defined (HISTORY) |
michael@428 | 1157 | /* XXX - will inhibit history file being written */ |
michael@428 | 1158 | - history_lines_this_session = 0; |
michael@428 | 1159 | +# if defined (READLINE) |
michael@428 | 1160 | + if (interactive_shell == 0 || interactive == 0 || (sig != SIGHUP && sig != SIGTERM) || no_line_editing || (RL_ISSTATE (RL_STATE_READCMD) == 0)) |
michael@428 | 1161 | +# endif |
michael@428 | 1162 | + history_lines_this_session = 0; |
michael@428 | 1163 | #endif |
michael@428 | 1164 | terminate_immediately = 0; |
michael@428 | 1165 | termsig_handler (sig); |
michael@428 | 1166 | Index: subst.c |
michael@428 | 1167 | --- subst.c.orig 2011-01-02 22:12:51.000000000 +0100 |
michael@428 | 1168 | +++ subst.c 2012-06-27 10:31:03.000000000 +0200 |
michael@428 | 1169 | @@ -366,6 +366,11 @@ |
michael@428 | 1170 | f &= ~W_ASSNBLTIN; |
michael@428 | 1171 | fprintf (stderr, "W_ASSNBLTIN%s", f ? "|" : ""); |
michael@428 | 1172 | } |
michael@428 | 1173 | + if (f & W_ASSNGLOBAL) |
michael@428 | 1174 | + { |
michael@428 | 1175 | + f &= ~W_ASSNGLOBAL; |
michael@428 | 1176 | + fprintf (stderr, "W_ASSNGLOBAL%s", f ? "|" : ""); |
michael@428 | 1177 | + } |
michael@428 | 1178 | if (f & W_COMPASSIGN) |
michael@428 | 1179 | { |
michael@428 | 1180 | f &= ~W_COMPASSIGN; |
michael@428 | 1181 | @@ -1379,10 +1384,12 @@ |
michael@428 | 1182 | slen = strlen (string + *sindex) + *sindex; |
michael@428 | 1183 | |
michael@428 | 1184 | /* The handling of dolbrace_state needs to agree with the code in parse.y: |
michael@428 | 1185 | - parse_matched_pair() */ |
michael@428 | 1186 | - dolbrace_state = 0; |
michael@428 | 1187 | - if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) |
michael@428 | 1188 | - dolbrace_state = (flags & SX_POSIXEXP) ? DOLBRACE_QUOTE : DOLBRACE_PARAM; |
michael@428 | 1189 | + parse_matched_pair(). The different initial value is to handle the |
michael@428 | 1190 | + case where this function is called to parse the word in |
michael@428 | 1191 | + ${param op word} (SX_WORD). */ |
michael@428 | 1192 | + dolbrace_state = (flags & SX_WORD) ? DOLBRACE_WORD : DOLBRACE_PARAM; |
michael@428 | 1193 | + if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && (flags & SX_POSIXEXP)) |
michael@428 | 1194 | + dolbrace_state = DOLBRACE_QUOTE; |
michael@428 | 1195 | |
michael@428 | 1196 | i = *sindex; |
michael@428 | 1197 | while (c = string[i]) |
michael@428 | 1198 | @@ -2801,7 +2808,7 @@ |
michael@428 | 1199 | } |
michael@428 | 1200 | else if (assign_list) |
michael@428 | 1201 | { |
michael@428 | 1202 | - if (word->flags & W_ASSIGNARG) |
michael@428 | 1203 | + if ((word->flags & W_ASSIGNARG) && (word->flags & W_ASSNGLOBAL) == 0) |
michael@428 | 1204 | aflags |= ASS_MKLOCAL; |
michael@428 | 1205 | if (word->flags & W_ASSIGNASSOC) |
michael@428 | 1206 | aflags |= ASS_MKASSOC; |
michael@428 | 1207 | @@ -3371,7 +3378,7 @@ |
michael@428 | 1208 | if (string == 0 || *string == '\0') |
michael@428 | 1209 | return (WORD_LIST *)NULL; |
michael@428 | 1210 | |
michael@428 | 1211 | - td.flags = 0; |
michael@428 | 1212 | + td.flags = W_NOSPLIT2; /* no splitting, remove "" and '' */ |
michael@428 | 1213 | td.word = string; |
michael@428 | 1214 | tresult = call_expand_word_internal (&td, quoted, 1, dollar_at_p, has_dollar_at); |
michael@428 | 1215 | return (tresult); |
michael@428 | 1216 | @@ -3704,7 +3711,10 @@ |
michael@428 | 1217 | break; |
michael@428 | 1218 | } |
michael@428 | 1219 | else if (string[i] == CTLNUL) |
michael@428 | 1220 | - i++; |
michael@428 | 1221 | + { |
michael@428 | 1222 | + i++; |
michael@428 | 1223 | + continue; |
michael@428 | 1224 | + } |
michael@428 | 1225 | |
michael@428 | 1226 | prev_i = i; |
michael@428 | 1227 | ADVANCE_CHAR (string, slen, i); |
michael@428 | 1228 | @@ -4156,7 +4166,7 @@ |
michael@428 | 1229 | simple = (wpat[0] != L'\\' && wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'['); |
michael@428 | 1230 | #if defined (EXTENDED_GLOB) |
michael@428 | 1231 | if (extended_glob) |
michael@428 | 1232 | - simple |= (wpat[1] != L'(' || (wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'+' && wpat[0] != L'!' && wpat[0] != L'@')); /*)*/ |
michael@428 | 1233 | + simple &= (wpat[1] != L'(' || (wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'+' && wpat[0] != L'!' && wpat[0] != L'@')); /*)*/ |
michael@428 | 1234 | #endif |
michael@428 | 1235 | |
michael@428 | 1236 | /* If the pattern doesn't match anywhere in the string, go ahead and |
michael@428 | 1237 | @@ -4607,6 +4617,7 @@ |
michael@428 | 1238 | if (ifs_firstc == 0) |
michael@428 | 1239 | #endif |
michael@428 | 1240 | word->flags |= W_NOSPLIT; |
michael@428 | 1241 | + word->flags |= W_NOSPLIT2; |
michael@428 | 1242 | result = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL); |
michael@428 | 1243 | expand_no_split_dollar_star = 0; |
michael@428 | 1244 | |
michael@428 | 1245 | @@ -5798,6 +5809,16 @@ |
michael@428 | 1246 | is the only expansion that creates more than one word. */ |
michael@428 | 1247 | if (qdollaratp && ((hasdol && quoted) || l->next)) |
michael@428 | 1248 | *qdollaratp = 1; |
michael@428 | 1249 | + /* If we have a quoted null result (QUOTED_NULL(temp)) and the word is |
michael@428 | 1250 | + a quoted null (l->next == 0 && QUOTED_NULL(l->word->word)), the |
michael@428 | 1251 | + flags indicate it (l->word->flags & W_HASQUOTEDNULL), and the |
michael@428 | 1252 | + expansion is quoted (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) |
michael@428 | 1253 | + (which is more paranoia than anything else), we need to return the |
michael@428 | 1254 | + quoted null string and set the flags to indicate it. */ |
michael@428 | 1255 | + if (l->next == 0 && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && QUOTED_NULL(temp) && QUOTED_NULL(l->word->word) && (l->word->flags & W_HASQUOTEDNULL)) |
michael@428 | 1256 | + { |
michael@428 | 1257 | + w->flags |= W_HASQUOTEDNULL; |
michael@428 | 1258 | + } |
michael@428 | 1259 | dispose_words (l); |
michael@428 | 1260 | } |
michael@428 | 1261 | else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && hasdol) |
michael@428 | 1262 | @@ -7176,7 +7197,7 @@ |
michael@428 | 1263 | { |
michael@428 | 1264 | /* Extract the contents of the ${ ... } expansion |
michael@428 | 1265 | according to the Posix.2 rules. */ |
michael@428 | 1266 | - value = extract_dollar_brace_string (string, &sindex, quoted, (c == '%' || c == '#') ? SX_POSIXEXP : 0); |
michael@428 | 1267 | + value = extract_dollar_brace_string (string, &sindex, quoted, (c == '%' || c == '#' || c =='/' || c == '^' || c == ',' || c ==':') ? SX_POSIXEXP|SX_WORD : SX_WORD); |
michael@428 | 1268 | if (string[sindex] == RBRACE) |
michael@428 | 1269 | sindex++; |
michael@428 | 1270 | else |
michael@428 | 1271 | @@ -7268,6 +7289,7 @@ |
michael@428 | 1272 | default: |
michael@428 | 1273 | case '\0': |
michael@428 | 1274 | bad_substitution: |
michael@428 | 1275 | + last_command_exit_value = EXECUTION_FAILURE; |
michael@428 | 1276 | report_error (_("%s: bad substitution"), string ? string : "??"); |
michael@428 | 1277 | FREE (value); |
michael@428 | 1278 | FREE (temp); |
michael@428 | 1279 | Index: subst.h |
michael@428 | 1280 | --- subst.h.orig 2010-12-03 02:21:29.000000000 +0100 |
michael@428 | 1281 | +++ subst.h 2012-06-27 10:31:02.000000000 +0200 |
michael@428 | 1282 | @@ -56,6 +56,7 @@ |
michael@428 | 1283 | #define SX_NOLONGJMP 0x0040 /* don't longjmp on fatal error */ |
michael@428 | 1284 | #define SX_ARITHSUB 0x0080 /* extracting $(( ... )) (currently unused) */ |
michael@428 | 1285 | #define SX_POSIXEXP 0x0100 /* extracting new Posix pattern removal expansions in extract_dollar_brace_string */ |
michael@428 | 1286 | +#define SX_WORD 0x0200 /* extracting word in ${param op word} */ |
michael@428 | 1287 | |
michael@428 | 1288 | /* Remove backslashes which are quoting backquotes from STRING. Modifies |
michael@428 | 1289 | STRING, and returns a pointer to it. */ |
michael@428 | 1290 | Index: support/shobj-conf |
michael@428 | 1291 | --- support/shobj-conf.orig 2009-10-28 14:20:21.000000000 +0100 |
michael@428 | 1292 | +++ support/shobj-conf 2012-06-27 10:31:02.000000000 +0200 |
michael@428 | 1293 | @@ -157,7 +157,7 @@ |
michael@428 | 1294 | ;; |
michael@428 | 1295 | |
michael@428 | 1296 | # Darwin/MacOS X |
michael@428 | 1297 | -darwin[89]*|darwin10*) |
michael@428 | 1298 | +darwin[89]*|darwin1[012]*) |
michael@428 | 1299 | SHOBJ_STATUS=supported |
michael@428 | 1300 | SHLIB_STATUS=supported |
michael@428 | 1301 | |
michael@428 | 1302 | @@ -186,7 +186,7 @@ |
michael@428 | 1303 | SHLIB_LIBSUFF='dylib' |
michael@428 | 1304 | |
michael@428 | 1305 | case "${host_os}" in |
michael@428 | 1306 | - darwin[789]*|darwin10*) SHOBJ_LDFLAGS='' |
michael@428 | 1307 | + darwin[789]*|darwin1[012]*) SHOBJ_LDFLAGS='' |
michael@428 | 1308 | SHLIB_XLDFLAGS='-dynamiclib -arch_only `/usr/bin/arch` -install_name $(libdir)/$@ -current_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -compatibility_version $(SHLIB_MAJOR) -v' |
michael@428 | 1309 | ;; |
michael@428 | 1310 | *) SHOBJ_LDFLAGS='-dynamic' |
michael@428 | 1311 | Index: tests/shopt.right |
michael@428 | 1312 | --- tests/shopt.right.orig 2010-07-03 05:36:30.000000000 +0200 |
michael@428 | 1313 | +++ tests/shopt.right 2012-06-27 10:31:03.000000000 +0200 |
michael@428 | 1314 | @@ -12,6 +12,7 @@ |
michael@428 | 1315 | shopt -u compat32 |
michael@428 | 1316 | shopt -u compat40 |
michael@428 | 1317 | shopt -u compat41 |
michael@428 | 1318 | +shopt -u direxpand |
michael@428 | 1319 | shopt -u dirspell |
michael@428 | 1320 | shopt -u dotglob |
michael@428 | 1321 | shopt -u execfail |
michael@428 | 1322 | @@ -68,6 +69,7 @@ |
michael@428 | 1323 | shopt -u compat32 |
michael@428 | 1324 | shopt -u compat40 |
michael@428 | 1325 | shopt -u compat41 |
michael@428 | 1326 | +shopt -u direxpand |
michael@428 | 1327 | shopt -u dirspell |
michael@428 | 1328 | shopt -u dotglob |
michael@428 | 1329 | shopt -u execfail |
michael@428 | 1330 | @@ -101,6 +103,7 @@ |
michael@428 | 1331 | compat32 off |
michael@428 | 1332 | compat40 off |
michael@428 | 1333 | compat41 off |
michael@428 | 1334 | +direxpand off |
michael@428 | 1335 | dirspell off |
michael@428 | 1336 | dotglob off |
michael@428 | 1337 | execfail off |
michael@428 | 1338 | Index: variables.c |
michael@428 | 1339 | --- variables.c.orig 2011-01-25 02:07:48.000000000 +0100 |
michael@428 | 1340 | +++ variables.c 2012-06-27 10:31:02.000000000 +0200 |
michael@428 | 1341 | @@ -3653,6 +3653,22 @@ |
michael@428 | 1342 | return n; |
michael@428 | 1343 | } |
michael@428 | 1344 | |
michael@428 | 1345 | +int |
michael@428 | 1346 | +chkexport (name) |
michael@428 | 1347 | + char *name; |
michael@428 | 1348 | +{ |
michael@428 | 1349 | + SHELL_VAR *v; |
michael@428 | 1350 | + |
michael@428 | 1351 | + v = find_variable (name); |
michael@428 | 1352 | + if (v && exported_p (v)) |
michael@428 | 1353 | + { |
michael@428 | 1354 | + array_needs_making = 1; |
michael@428 | 1355 | + maybe_make_export_env (); |
michael@428 | 1356 | + return 1; |
michael@428 | 1357 | + } |
michael@428 | 1358 | + return 0; |
michael@428 | 1359 | +} |
michael@428 | 1360 | + |
michael@428 | 1361 | void |
michael@428 | 1362 | maybe_make_export_env () |
michael@428 | 1363 | { |
michael@428 | 1364 | @@ -4214,7 +4230,7 @@ |
michael@428 | 1365 | { "TEXTDOMAIN", sv_locale }, |
michael@428 | 1366 | { "TEXTDOMAINDIR", sv_locale }, |
michael@428 | 1367 | |
michael@428 | 1368 | -#if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE) |
michael@428 | 1369 | +#if defined (HAVE_TZSET) |
michael@428 | 1370 | { "TZ", sv_tz }, |
michael@428 | 1371 | #endif |
michael@428 | 1372 | |
michael@428 | 1373 | @@ -4558,12 +4574,13 @@ |
michael@428 | 1374 | } |
michael@428 | 1375 | #endif /* HISTORY */ |
michael@428 | 1376 | |
michael@428 | 1377 | -#if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE) |
michael@428 | 1378 | +#if defined (HAVE_TZSET) |
michael@428 | 1379 | void |
michael@428 | 1380 | sv_tz (name) |
michael@428 | 1381 | char *name; |
michael@428 | 1382 | { |
michael@428 | 1383 | - tzset (); |
michael@428 | 1384 | + if (chkexport (name)) |
michael@428 | 1385 | + tzset (); |
michael@428 | 1386 | } |
michael@428 | 1387 | #endif |
michael@428 | 1388 | |
michael@428 | 1389 | Index: variables.h |
michael@428 | 1390 | --- variables.h.orig 2010-12-03 02:22:01.000000000 +0100 |
michael@428 | 1391 | +++ variables.h 2012-06-27 10:31:02.000000000 +0200 |
michael@428 | 1392 | @@ -313,6 +313,7 @@ |
michael@428 | 1393 | |
michael@428 | 1394 | extern void sort_variables __P((SHELL_VAR **)); |
michael@428 | 1395 | |
michael@428 | 1396 | +extern int chkexport __P((char *)); |
michael@428 | 1397 | extern void maybe_make_export_env __P((void)); |
michael@428 | 1398 | extern void update_export_env_inplace __P((char *, int, char *)); |
michael@428 | 1399 | extern void put_command_name_into_env __P((char *)); |
michael@428 | 1400 | Index: y.tab.c |
michael@428 | 1401 | --- y.tab.c.orig 2011-01-04 15:57:56.000000000 +0100 |
michael@428 | 1402 | +++ y.tab.c 2012-06-27 10:31:03.000000000 +0200 |
michael@428 | 1403 | @@ -4811,7 +4811,7 @@ |
michael@428 | 1404 | We do this only if it is time to do so. Notice that only here |
michael@428 | 1405 | is the mail alarm reset; nothing takes place in check_mail () |
michael@428 | 1406 | except the checking of mail. Please don't change this. */ |
michael@428 | 1407 | - if (prompt_is_ps1 && time_to_check_mail ()) |
michael@428 | 1408 | + if (prompt_is_ps1 && parse_and_execute_level == 0 && time_to_check_mail ()) |
michael@428 | 1409 | { |
michael@428 | 1410 | check_mail (); |
michael@428 | 1411 | reset_mail_timer (); |
michael@428 | 1412 | @@ -6154,6 +6154,7 @@ |
michael@428 | 1413 | int flags; |
michael@428 | 1414 | { |
michael@428 | 1415 | sh_parser_state_t ps; |
michael@428 | 1416 | + sh_input_line_state_t ls; |
michael@428 | 1417 | int orig_ind, nc, sflags; |
michael@428 | 1418 | char *ret, *s, *ep, *ostring; |
michael@428 | 1419 | |
michael@428 | 1420 | @@ -6161,10 +6162,12 @@ |
michael@428 | 1421 | orig_ind = *indp; |
michael@428 | 1422 | ostring = string; |
michael@428 | 1423 | |
michael@428 | 1424 | +/*itrace("xparse_dolparen: size = %d shell_input_line = `%s'", shell_input_line_size, shell_input_line);*/ |
michael@428 | 1425 | sflags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOFREE; |
michael@428 | 1426 | if (flags & SX_NOLONGJMP) |
michael@428 | 1427 | sflags |= SEVAL_NOLONGJMP; |
michael@428 | 1428 | save_parser_state (&ps); |
michael@428 | 1429 | + save_input_line_state (&ls); |
michael@428 | 1430 | |
michael@428 | 1431 | /*(*/ |
michael@428 | 1432 | parser_state |= PST_CMDSUBST|PST_EOFTOKEN; /* allow instant ')' */ /*(*/ |
michael@428 | 1433 | @@ -6173,6 +6176,8 @@ |
michael@428 | 1434 | |
michael@428 | 1435 | restore_parser_state (&ps); |
michael@428 | 1436 | reset_parser (); |
michael@428 | 1437 | + /* reset_parser clears shell_input_line and associated variables */ |
michael@428 | 1438 | + restore_input_line_state (&ls); |
michael@428 | 1439 | if (interactive) |
michael@428 | 1440 | token_to_read = 0; |
michael@428 | 1441 | |
michael@428 | 1442 | @@ -7447,6 +7452,9 @@ |
michael@428 | 1443 | case 'A': |
michael@428 | 1444 | /* Make the current time/date into a string. */ |
michael@428 | 1445 | (void) time (&the_time); |
michael@428 | 1446 | +#if defined (HAVE_TZSET) |
michael@428 | 1447 | + sv_tz ("TZ"); /* XXX -- just make sure */ |
michael@428 | 1448 | +#endif |
michael@428 | 1449 | tm = localtime (&the_time); |
michael@428 | 1450 | |
michael@428 | 1451 | if (c == 'd') |
michael@428 | 1452 | @@ -8217,6 +8225,12 @@ |
michael@428 | 1453 | ps->expand_aliases = expand_aliases; |
michael@428 | 1454 | ps->echo_input_at_read = echo_input_at_read; |
michael@428 | 1455 | |
michael@428 | 1456 | + ps->token = token; |
michael@428 | 1457 | + ps->token_buffer_size = token_buffer_size; |
michael@428 | 1458 | + /* Force reallocation on next call to read_token_word */ |
michael@428 | 1459 | + token = 0; |
michael@428 | 1460 | + token_buffer_size = 0; |
michael@428 | 1461 | + |
michael@428 | 1462 | return (ps); |
michael@428 | 1463 | } |
michael@428 | 1464 | |
michael@428 | 1465 | @@ -8258,6 +8272,42 @@ |
michael@428 | 1466 | |
michael@428 | 1467 | expand_aliases = ps->expand_aliases; |
michael@428 | 1468 | echo_input_at_read = ps->echo_input_at_read; |
michael@428 | 1469 | + |
michael@428 | 1470 | + FREE (token); |
michael@428 | 1471 | + token = ps->token; |
michael@428 | 1472 | + token_buffer_size = ps->token_buffer_size; |
michael@428 | 1473 | +} |
michael@428 | 1474 | + |
michael@428 | 1475 | +sh_input_line_state_t * |
michael@428 | 1476 | +save_input_line_state (ls) |
michael@428 | 1477 | + sh_input_line_state_t *ls; |
michael@428 | 1478 | +{ |
michael@428 | 1479 | + if (ls == 0) |
michael@428 | 1480 | + ls = (sh_input_line_state_t *)xmalloc (sizeof (sh_input_line_state_t)); |
michael@428 | 1481 | + if (ls == 0) |
michael@428 | 1482 | + return ((sh_input_line_state_t *)NULL); |
michael@428 | 1483 | + |
michael@428 | 1484 | + ls->input_line = shell_input_line; |
michael@428 | 1485 | + ls->input_line_size = shell_input_line_size; |
michael@428 | 1486 | + ls->input_line_len = shell_input_line_len; |
michael@428 | 1487 | + ls->input_line_index = shell_input_line_index; |
michael@428 | 1488 | + |
michael@428 | 1489 | + /* force reallocation */ |
michael@428 | 1490 | + shell_input_line = 0; |
michael@428 | 1491 | + shell_input_line_size = shell_input_line_len = shell_input_line_index = 0; |
michael@428 | 1492 | +} |
michael@428 | 1493 | + |
michael@428 | 1494 | +void |
michael@428 | 1495 | +restore_input_line_state (ls) |
michael@428 | 1496 | + sh_input_line_state_t *ls; |
michael@428 | 1497 | +{ |
michael@428 | 1498 | + FREE (shell_input_line); |
michael@428 | 1499 | + shell_input_line = ls->input_line; |
michael@428 | 1500 | + shell_input_line_size = ls->input_line_size; |
michael@428 | 1501 | + shell_input_line_len = ls->input_line_len; |
michael@428 | 1502 | + shell_input_line_index = ls->input_line_index; |
michael@428 | 1503 | + |
michael@428 | 1504 | + set_line_mbstate (); |
michael@428 | 1505 | } |
michael@428 | 1506 | |
michael@428 | 1507 | /************************************************ |