From 11bf534f3628cc0a592866ee4f689beca473f548 Mon Sep 17 00:00:00 2001 From: Chet Ramey Date: Wed, 10 Mar 2021 10:35:28 -0500 Subject: [PATCH] commit bash-20210305 snapshot --- CWRU/CWRU.chlog | 21 ++ MANIFEST | 1 + doc/bash.0 | 10 +- doc/bashref.info | 297 +++++++++++++-------------- examples/shellmath/faster_e_demo.sh* | 68 ++++++ examples/shellmath/slower_e_demo.sh* | 55 +++++ include/posixtime.h | 29 +++ include/timer.h | 1 + lib/readline/posixtime.h | 1 + lib/sh/timers.c | 10 +- parse.y | 31 ++- shell.h | 3 +- tests/read.right | 8 +- tests/read.tests | 3 + tests/read2.sub | 19 +- tests/read7.sub | 55 +++++ 16 files changed, 416 insertions(+), 196 deletions(-) create mode 100755 examples/shellmath/faster_e_demo.sh* create mode 100755 examples/shellmath/slower_e_demo.sh* create mode 120000 lib/readline/posixtime.h create mode 100644 tests/read7.sub diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 6361eea5..425e8210 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -9705,3 +9705,24 @@ builtins/exec.def - exec_builtin: set last_command_exit_value before calling exit_shell so any exit trap gets the right value for $?. From Matthew Bauer via https://savannah.gnu.org/patch/?10039 + + 3/8 + --- +include/timer.h + - SHTIMER_ALRMSET: new flag, indicates that there is an active alarm + associated with this timer (falarm() was called) + +lib/sh/timers.c + - shtimer_set: set the SHTIMER_ALRMSET flag after calling falarm + - shtimer_unset: don't call falarm(0,0) unless the SHTIMER_ALRMSET flag + is set + + 3/9 + --- +include/posixtime.h + - added some BSD convenience defines if they are not present + +parse.y,shell.h + - {save,restore}_parser_state: save amd restore shell_eof_token and + pushed_string_list; change callers (e.g., xparse_dolparen) so they + don't have to manage them diff --git a/MANIFEST b/MANIFEST index 27af76b6..cdebaf60 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1313,6 +1313,7 @@ tests/read3.sub f tests/read4.sub f tests/read5.sub f tests/read6.sub f +tests/read7.sub f tests/redir.tests f tests/redir.right f tests/redir1.sub f diff --git a/doc/bash.0 b/doc/bash.0 index d3964a5e..259e225f 100644 --- a/doc/bash.0 +++ b/doc/bash.0 @@ -521,14 +521,6 @@ SSHHEELLLL GGRRAAMMMMAARR command or a compound command (see above). _N_A_M_E is a shell variable name. If _N_A_M_E is not supplied, the default name is CCOOPPRROOCC. - The recommended form to use for a coprocess is - - ccoopprroocc _N_A_M_E { _c_o_m_m_a_n_d [_r_e_d_i_r_e_c_t_i_o_n_s]; } - - This form is recommended because simple commands result in the copro- - cess always being named CCOOPPRROOCC, and it is simpler to use and more com- - plete than the other compound commands. - If _c_o_m_m_a_n_d is a compound command, _N_A_M_E is optional. The word following ccoopprroocc determines whether that word is interpreted as a variable name: it is interpreted as _N_A_M_E if it is not a reserved word that introduces @@ -6424,4 +6416,4 @@ BBUUGGSS -GNU Bash 5.1 2021 March 4 BASH(1) +GNU Bash 5.1 2021 February 28 BASH(1) diff --git a/doc/bashref.info b/doc/bashref.info index cd943692..db8191e2 100644 --- a/doc/bashref.info +++ b/doc/bashref.info @@ -2,9 +2,9 @@ This is bashref.info, produced by makeinfo version 6.7 from bashref.texi. This text is a brief description of the features that are present in the -Bash shell (version 5.1, 4 March2021). +Bash shell (version 5.1, 28 February 2021). - This is Edition 5.1, last updated 4 March2021, of 'The GNU Bash + This is Edition 5.1, last updated 28 February 2021, of 'The GNU Bash Reference Manual', for 'Bash', Version 5.1. Copyright (C) 1988-2021 Free Software Foundation, Inc. @@ -27,10 +27,10 @@ Bash Features ************* This text is a brief description of the features that are present in the -Bash shell (version 5.1, 4 March2021). The Bash home page is +Bash shell (version 5.1, 28 February 2021). The Bash home page is . - This is Edition 5.1, last updated 4 March2021, of 'The GNU Bash + This is Edition 5.1, last updated 28 February 2021, of 'The GNU Bash Reference Manual', for 'Bash', Version 5.1. Bash contains features that appear in other popular shells, and some @@ -1059,7 +1059,6 @@ had been terminated with the '&' control operator, with a two-way pipe established between the executing shell and the coprocess. The syntax for a coprocess is: - coproc [NAME] COMMAND [REDIRECTIONS] This creates a coprocess named NAME. COMMAND may be either a simple @@ -1067,26 +1066,12 @@ command (*note Simple Commands::) or a compound command (*note Compound Commands::). NAME is a shell variable name. If NAME is not supplied, the default name is 'COPROC'. - The recommended form to use for a coprocess is - - coproc NAME { COMMAND; } - -This form is recommended because simple commands result in the coprocess -always being named 'COPROC', and it is simpler to use and more complete -than the other compound commands. - - There are other forms of coprocesses: - - coproc NAME COMPOUND-COMMAND - coproc COMPOUND-COMMAND - coproc SIMPLE-COMMAND - -If COMMAND is a compound command, NAME is optional. The word following -'coproc' determines whether that word is interpreted as a variable name: -it is interpreted as NAME if it is not a reserved word that introduces a -compound command. If COMMAND is a simple command, NAME is not allowed; -this is to avoid confusion between NAME and the first word of the simple -command. + If COMMAND is a compound command, NAME is optional. The word +following 'coproc' determines whether that word is interpreted as a +variable name: it is interpreted as NAME if it is not a reserved word +that introduces a compound command. If COMMAND is a simple command, +NAME is not allowed; this is to avoid confusion between NAME and the +first word of the simple command. When the coprocess is executed, the shell creates an array variable (*note Arrays::) named NAME in the context of the executing shell. The @@ -12022,137 +12007,137 @@ D.5 Concept Index  Tag Table: -Node: Top887 -Node: Introduction2797 -Node: What is Bash?3013 -Node: What is a shell?4127 -Node: Definitions6665 -Node: Basic Shell Features9616 -Node: Shell Syntax10835 -Node: Shell Operation11861 -Node: Quoting13154 -Node: Escape Character14458 -Node: Single Quotes14943 -Node: Double Quotes15291 -Node: ANSI-C Quoting16569 -Node: Locale Translation17826 -Node: Comments18981 -Node: Shell Commands19599 -Node: Reserved Words20537 -Node: Simple Commands21293 -Node: Pipelines21947 -Node: Lists24904 -Node: Compound Commands26699 -Node: Looping Constructs27711 -Node: Conditional Constructs30206 -Node: Command Grouping41777 -Node: Coprocesses43252 -Node: GNU Parallel45915 -Node: Shell Functions50216 -Node: Shell Parameters57436 -Node: Positional Parameters61869 -Node: Special Parameters62771 -Node: Shell Expansions65995 -Node: Brace Expansion68122 -Node: Tilde Expansion70847 -Node: Shell Parameter Expansion73468 -Node: Command Substitution88597 -Node: Arithmetic Expansion89952 -Node: Process Substitution90884 -Node: Word Splitting92004 -Node: Filename Expansion93948 -Node: Pattern Matching96497 -Node: Quote Removal100487 -Node: Redirections100782 -Node: Executing Commands110356 -Node: Simple Command Expansion111026 -Node: Command Search and Execution112980 -Node: Command Execution Environment115358 -Node: Environment118344 -Node: Exit Status120007 -Node: Signals121679 -Node: Shell Scripts123646 -Node: Shell Builtin Commands126658 -Node: Bourne Shell Builtins128696 -Node: Bash Builtins149627 -Node: Modifying Shell Behavior179777 -Node: The Set Builtin180122 -Node: The Shopt Builtin190535 -Node: Special Builtins205447 -Node: Shell Variables206426 -Node: Bourne Shell Variables206863 -Node: Bash Variables208967 -Node: Bash Features241625 -Node: Invoking Bash242638 -Node: Bash Startup Files248651 -Node: Interactive Shells253754 -Node: What is an Interactive Shell?254164 -Node: Is this Shell Interactive?254813 -Node: Interactive Shell Behavior255628 -Node: Bash Conditional Expressions259141 -Node: Shell Arithmetic263718 -Node: Aliases266662 -Node: Arrays269275 -Node: The Directory Stack275284 -Node: Directory Stack Builtins276068 -Node: Controlling the Prompt279036 -Node: The Restricted Shell281984 -Node: Bash POSIX Mode284578 -Node: Shell Compatibility Mode295851 -Node: Job Control302507 -Node: Job Control Basics302967 -Node: Job Control Builtins307969 -Node: Job Control Variables313369 -Node: Command Line Editing314525 -Node: Introduction and Notation316196 -Node: Readline Interaction317819 -Node: Readline Bare Essentials319010 -Node: Readline Movement Commands320793 -Node: Readline Killing Commands321753 -Node: Readline Arguments323671 -Node: Searching324715 -Node: Readline Init File326901 -Node: Readline Init File Syntax328160 -Node: Conditional Init Constructs348698 -Node: Sample Init File352894 -Node: Bindable Readline Commands356018 -Node: Commands For Moving357222 -Node: Commands For History359273 -Node: Commands For Text364066 -Node: Commands For Killing367715 -Node: Numeric Arguments370748 -Node: Commands For Completion371887 -Node: Keyboard Macros376078 -Node: Miscellaneous Commands376765 -Node: Readline vi Mode382449 -Node: Programmable Completion383356 -Node: Programmable Completion Builtins391136 -Node: A Programmable Completion Example401831 -Node: Using History Interactively407078 -Node: Bash History Facilities407762 -Node: Bash History Builtins410767 -Node: History Interaction415775 -Node: Event Designators419395 -Node: Word Designators420749 -Node: Modifiers422509 -Node: Installing Bash424320 -Node: Basic Installation425457 -Node: Compilers and Options428715 -Node: Compiling For Multiple Architectures429456 -Node: Installation Names431149 -Node: Specifying the System Type431967 -Node: Sharing Defaults432683 -Node: Operation Controls433356 -Node: Optional Features434314 -Node: Reporting Bugs445114 -Node: Major Differences From The Bourne Shell446308 -Node: GNU Free Documentation License463158 -Node: Indexes488335 -Node: Builtin Index488789 -Node: Reserved Word Index495616 -Node: Variable Index498064 -Node: Function Index513961 -Node: Concept Index527471 +Node: Top897 +Node: Introduction2817 +Node: What is Bash?3033 +Node: What is a shell?4147 +Node: Definitions6685 +Node: Basic Shell Features9636 +Node: Shell Syntax10855 +Node: Shell Operation11881 +Node: Quoting13174 +Node: Escape Character14478 +Node: Single Quotes14963 +Node: Double Quotes15311 +Node: ANSI-C Quoting16589 +Node: Locale Translation17846 +Node: Comments19001 +Node: Shell Commands19619 +Node: Reserved Words20557 +Node: Simple Commands21313 +Node: Pipelines21967 +Node: Lists24924 +Node: Compound Commands26719 +Node: Looping Constructs27731 +Node: Conditional Constructs30226 +Node: Command Grouping41797 +Node: Coprocesses43272 +Node: GNU Parallel45542 +Node: Shell Functions49843 +Node: Shell Parameters57063 +Node: Positional Parameters61496 +Node: Special Parameters62398 +Node: Shell Expansions65622 +Node: Brace Expansion67749 +Node: Tilde Expansion70474 +Node: Shell Parameter Expansion73095 +Node: Command Substitution88224 +Node: Arithmetic Expansion89579 +Node: Process Substitution90511 +Node: Word Splitting91631 +Node: Filename Expansion93575 +Node: Pattern Matching96124 +Node: Quote Removal100114 +Node: Redirections100409 +Node: Executing Commands109983 +Node: Simple Command Expansion110653 +Node: Command Search and Execution112607 +Node: Command Execution Environment114985 +Node: Environment117971 +Node: Exit Status119634 +Node: Signals121306 +Node: Shell Scripts123273 +Node: Shell Builtin Commands126285 +Node: Bourne Shell Builtins128323 +Node: Bash Builtins149254 +Node: Modifying Shell Behavior179404 +Node: The Set Builtin179749 +Node: The Shopt Builtin190162 +Node: Special Builtins205074 +Node: Shell Variables206053 +Node: Bourne Shell Variables206490 +Node: Bash Variables208594 +Node: Bash Features241252 +Node: Invoking Bash242265 +Node: Bash Startup Files248278 +Node: Interactive Shells253381 +Node: What is an Interactive Shell?253791 +Node: Is this Shell Interactive?254440 +Node: Interactive Shell Behavior255255 +Node: Bash Conditional Expressions258768 +Node: Shell Arithmetic263345 +Node: Aliases266289 +Node: Arrays268902 +Node: The Directory Stack274911 +Node: Directory Stack Builtins275695 +Node: Controlling the Prompt278663 +Node: The Restricted Shell281611 +Node: Bash POSIX Mode284205 +Node: Shell Compatibility Mode295478 +Node: Job Control302134 +Node: Job Control Basics302594 +Node: Job Control Builtins307596 +Node: Job Control Variables312996 +Node: Command Line Editing314152 +Node: Introduction and Notation315823 +Node: Readline Interaction317446 +Node: Readline Bare Essentials318637 +Node: Readline Movement Commands320420 +Node: Readline Killing Commands321380 +Node: Readline Arguments323298 +Node: Searching324342 +Node: Readline Init File326528 +Node: Readline Init File Syntax327787 +Node: Conditional Init Constructs348325 +Node: Sample Init File352521 +Node: Bindable Readline Commands355645 +Node: Commands For Moving356849 +Node: Commands For History358900 +Node: Commands For Text363693 +Node: Commands For Killing367342 +Node: Numeric Arguments370375 +Node: Commands For Completion371514 +Node: Keyboard Macros375705 +Node: Miscellaneous Commands376392 +Node: Readline vi Mode382076 +Node: Programmable Completion382983 +Node: Programmable Completion Builtins390763 +Node: A Programmable Completion Example401458 +Node: Using History Interactively406705 +Node: Bash History Facilities407389 +Node: Bash History Builtins410394 +Node: History Interaction415402 +Node: Event Designators419022 +Node: Word Designators420376 +Node: Modifiers422136 +Node: Installing Bash423947 +Node: Basic Installation425084 +Node: Compilers and Options428342 +Node: Compiling For Multiple Architectures429083 +Node: Installation Names430776 +Node: Specifying the System Type431594 +Node: Sharing Defaults432310 +Node: Operation Controls432983 +Node: Optional Features433941 +Node: Reporting Bugs444741 +Node: Major Differences From The Bourne Shell445935 +Node: GNU Free Documentation License462785 +Node: Indexes487962 +Node: Builtin Index488416 +Node: Reserved Word Index495243 +Node: Variable Index497691 +Node: Function Index513588 +Node: Concept Index527098  End Tag Table diff --git a/examples/shellmath/faster_e_demo.sh* b/examples/shellmath/faster_e_demo.sh* new file mode 100755 index 00000000..84558a2e --- /dev/null +++ b/examples/shellmath/faster_e_demo.sh* @@ -0,0 +1,68 @@ +#!/usr/bin/env bash + +############################################################################### +# This script performs the same task as "slower_e_demo.sh" but with a major +# performance optimization. The speedup is especially noticeable on GNU +# emulation layers for Windows such as Cygwin and minGW, where the overhead +# of subshelling is quite significant. +# +# The speedup uses global storage space to simulate pass-and-return by +# reference so that you can capture the side effects of a function call without +# writing to stdout and wrapping the call in a subshell. How to use: +# +# Turn on "__shellmath_isOptimized" as shown below. +# Then instead of invoking "mySum = $(_shellmath_add $x $y)", +# call "_shellmath_add $x $y; _shellmath_getReturnValue mySum". +############################################################################### + +source shellmath.sh + +# Setting the '-t' flag will cause the script to time the algorithm +if [[ "$1" == '-t' ]]; then + do_timing=${__shellmath_true} + shift +fi + +if [[ $# -ne 1 ]]; then + echo "USAGE: ${BASH_SOURCE##*/} [-t] *N*" + echo " Approximates 'e' using the N-th order Maclaurin polynomial" + echo " (i.e. the Taylor polynomial centered at 0)." + echo " Specify the '-t' flag to time the main algorithm." + exit 0 +elif [[ ! "$1" =~ ^[0-9]+$ ]]; then + echo "Illegal argument. Whole numbers only, please." + exit 1 +fi + +__shellmath_isOptimized=${__shellmath_true} + + +function run_algorithm() +{ + # Initialize + n=0; N=$1; zero_factorial=1 + + # Initialize "e" to its zeroth-order term + _shellmath_divide 1 $zero_factorial + _shellmath_getReturnValue term + e=$term + + # Compute successive terms T(n) := T(n-1)/n and accumulate into e + for ((n=1; n<=N; n++)); do + _shellmath_divide "$term" "$n" + _shellmath_getReturnValue term + _shellmath_add "$e" "$term" + _shellmath_getReturnValue e + done + + echo "e = $e" +} + +if (( do_timing == __shellmath_true )); then + time run_algorithm "$1" +else + run_algorithm "$1" +fi + +exit 0 + diff --git a/examples/shellmath/slower_e_demo.sh* b/examples/shellmath/slower_e_demo.sh* new file mode 100755 index 00000000..d8fc9314 --- /dev/null +++ b/examples/shellmath/slower_e_demo.sh* @@ -0,0 +1,55 @@ +#!/usr/bin/env bash + +############################################################################### +# This script illustrates the use of the shellmath APIs to perform +# decimal calculations. Here we approximate the mathematical constant 'e' +# using its Maclaurin polynomials (i.e. its Taylor polynomials centered at 0). +############################################################################### + +source shellmath.sh + +# Setting the '-t' flag will cause the script to time the algorithm +if [[ "$1" == '-t' ]]; then + do_timing=${__shellmath_true} + shift +fi + +if [[ $# -ne 1 ]]; then + echo "USAGE: ${BASH_SOURCE##*/} [-t] *N*" + echo " Approximates 'e' using the N-th order Maclaurin polynomial" + echo " (i.e. the Taylor polynomial centered at 0)." + echo " Specify the '-t' flag to time the main algorithm." + exit 0 +elif [[ ! "$1" =~ ^[0-9]+$ ]]; then + echo "Illegal argument. Whole numbers only, please." + exit 1 +fi + + +function run_algorithm() +{ + # Initialize + n=0; N=$1; zero_factorial=1 + + # Initialize e to the zeroth-order term + term=$(_shellmath_divide 1 $zero_factorial) + e=$term + + # Compute successive terms T(n) := T(n-1)/n and accumulate into e + for ((n=1; n<=N; n++)); do + term=$(_shellmath_divide "$term" "$n") + e=$(_shellmath_add "$e" "$term") + done + + echo "e = $e" +} + + +if (( do_timing == __shellmath_true )); then + time run_algorithm "$1" +else + run_algorithm "$1" +fi + +exit 0 + diff --git a/include/posixtime.h b/include/posixtime.h index a83e436b..d60ece37 100644 --- a/include/posixtime.h +++ b/include/posixtime.h @@ -58,4 +58,33 @@ struct timeval extern int gettimeofday PARAMS((struct timeval *, void *)); #endif +/* These exist on BSD systems, at least. */ +#if !defined (timerclear) +# define timerclear(tvp) do { (tvp)->tv_sec = 0; (tvp)->tv_usec = 0; } while (0) +#endif +#if !defined (timerisset) +# define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) +#endif +#if !defined (timercmp) +# define timercmp(a, b, CMP) \ + (((a)->tv_sec == (b)->tv_sec) ? ((a)->tv_usec CMP (b)->tv_usec) \ + : ((a)->tv_sec CMP (b)->tv_sec)) +#endif + +/* These are non-standard. */ +#if !defined (timerunset) +# define timerunset(tvp) ((tvp)->tv_sec == 0 && (tvp)->tv_usec == 0) +#endif +#if !defined (timerset) +# define timerset(tvp, s, u) do { tvp->tv_sec = s; tvp->tv_usec = u; } while (0) +#endif + +#ifndef TIMEVAL_TO_TIMESPEC +# define TIMEVAL_TO_TIMESPEC(tv, ts) \ + do { \ + (ts)->tv_sec = (tv)->tv_sec; \ + (ts)->tv_nsec = (tv)->tv_usec * 1000; \ + } while (0) +#endif + #endif /* _POSIXTIME_H_ */ diff --git a/include/timer.h b/include/timer.h index e42aabe5..27794756 100644 --- a/include/timer.h +++ b/include/timer.h @@ -46,6 +46,7 @@ typedef struct _shtimer #define SHTIMER_LONGJMP 0x04 #define SHTIMER_SIGSET 0x100 +#define SHTIMER_ALRMSET 0x200 extern sh_timer *shtimer_alloc (void); extern void shtimer_flush (sh_timer *); diff --git a/lib/readline/posixtime.h b/lib/readline/posixtime.h new file mode 120000 index 00000000..51628a2a --- /dev/null +++ b/lib/readline/posixtime.h @@ -0,0 +1 @@ +../../include/posixtime.h \ No newline at end of file diff --git a/lib/sh/timers.c b/lib/sh/timers.c index af2f1556..69b754c9 100644 --- a/lib/sh/timers.c +++ b/lib/sh/timers.c @@ -106,14 +106,13 @@ shtimer_set (sh_timer *t, time_t sec, long usec) t->old_handler = set_signal_handler (SIGALRM, t->alrm_handler); t->flags |= SHTIMER_SIGSET; falarm (t->tmout.tv_sec = sec, t->tmout.tv_usec = usec); + t->flags |= SHTIMER_ALRMSET; return; } if (gettimeofday (&now, 0) < 0) - { - now.tv_sec = 0; - now.tv_usec = 0; - } + timerclear (&now); + t->tmout.tv_sec = now.tv_sec + sec; t->tmout.tv_usec = now.tv_usec + usec; if (t->tmout.tv_usec > USEC_PER_SEC) @@ -132,7 +131,8 @@ shtimer_unset (sh_timer *t) if (t->flags & SHTIMER_ALARM) { t->alrmflag = 0; - falarm (0, 0); + if (t->flags & SHTIMER_ALRMSET) + falarm (0, 0); if (t->old_handler && (t->flags & SHTIMER_SIGSET)) { set_signal_handler (SIGALRM, t->old_handler); diff --git a/parse.y b/parse.y index cc66f810..70564241 100644 --- a/parse.y +++ b/parse.y @@ -4059,9 +4059,9 @@ eof_error: change the LEX_INHEREDOC to LEX_QUOTEDDOC here and uncomment the next clause below. Note that to make this work completely, we need to make additional changes to allow xparse_dolparen to work right when the - command substitution is parsed, because read_secondary_line doesn't know - to recursively parse through command substitutions embedded in here- - documents */ + command substitution is parsed, because read_secondary_line doesn't + know to recursively parse through command substitutions embedded in + here-documents */ if (tflags & (LEX_INCOMMENT|LEX_INHEREDOC)) { /* Add this character. */ @@ -4552,11 +4552,8 @@ xparse_dolparen (base, string, indp, flags) { sh_parser_state_t ps; sh_input_line_state_t ls; - int orig_ind, nc, sflags, orig_eof_token, start_lineno; + int orig_ind, nc, sflags, start_lineno; char *ret, *ep, *ostring; -#if defined (ALIAS) || defined (DPAREN_ARITHMETIC) - STRING_SAVER *saved_pushed_strings; -#endif /*debug_parser(1);*/ orig_ind = *indp; @@ -4579,12 +4576,10 @@ xparse_dolparen (base, string, indp, flags) sflags |= SEVAL_NOLONGJMP; save_parser_state (&ps); save_input_line_state (&ls); - orig_eof_token = shell_eof_token; + #if defined (ALIAS) || defined (DPAREN_ARITHMETIC) - saved_pushed_strings = pushed_string_list; /* separate parsing context */ pushed_string_list = (STRING_SAVER *)NULL; #endif - /*(*/ parser_state |= PST_CMDSUBST|PST_EOFTOKEN; /* allow instant ')' */ /*(*/ shell_eof_token = ')'; @@ -4601,14 +4596,8 @@ xparse_dolparen (base, string, indp, flags) /* reset_parser() clears shell_input_line and associated variables, including parser_state, so we want to reset things, then restore what we need. */ restore_input_line_state (&ls); - - shell_eof_token = orig_eof_token; restore_parser_state (&ps); -#if defined (ALIAS) || defined (DPAREN_ARITHMETIC) - pushed_string_list = saved_pushed_strings; -#endif - token_to_read = 0; /* If parse_string returns < 0, we need to jump to top level with the @@ -6792,6 +6781,11 @@ save_parser_state (ps) else memcpy (ps->redir_stack, redir_stack, sizeof (redir_stack[0]) * HEREDOC_MAX); +#if defined (ALIAS) || defined (DPAREN_ARITHMETIC) + ps->pushed_strings = pushed_string_list; +#endif + + ps->eof_token = shell_eof_token; ps->token = token; ps->token_buffer_size = token_buffer_size; /* Force reallocation on next call to read_token_word */ @@ -6854,9 +6848,14 @@ restore_parser_state (ps) memcpy (redir_stack, ps->redir_stack, sizeof (redir_stack[0]) * HEREDOC_MAX); #endif +#if defined (ALIAS) || defined (DPAREN_ARITHMETIC) + pushed_string_list = (STRING_SAVER *)ps->pushed_strings; +#endif + FREE (token); token = ps->token; token_buffer_size = ps->token_buffer_size; + shell_eof_token = ps->eof_token; } sh_input_line_state_t * diff --git a/shell.h b/shell.h index a9a3d1e7..06efc946 100644 --- a/shell.h +++ b/shell.h @@ -167,13 +167,13 @@ extern struct user_info current_user; typedef struct _sh_parser_state_t { - /* parsing state */ int parser_state; int *token_state; char *token; int token_buffer_size; + int eof_token; /* input line state -- line number saved elsewhere */ int input_line_terminator; @@ -206,6 +206,7 @@ typedef struct _sh_parser_state_t int here_doc_first_line; /* structures affecting the parser */ + void *pushed_strings; REDIRECT *redir_stack[HEREDOC_MAX]; } sh_parser_state_t; diff --git a/tests/read.right b/tests/read.right index 11440837..f1610608 100644 --- a/tests/read.right +++ b/tests/read.right @@ -34,10 +34,12 @@ a = xyz a = -xyz 123- a = abc timeout 1: ok - +unset or null 1 timeout 2: ok - -./read2.sub: line 36: read: -3: invalid timeout specification +unset or null 2 +timeout 3: ok +unset or null 3 +./read2.sub: line 43: read: -3: invalid timeout specification 1 abcde diff --git a/tests/read.tests b/tests/read.tests index 7384f05f..5efae20b 100644 --- a/tests/read.tests +++ b/tests/read.tests @@ -109,3 +109,6 @@ ${THIS_SH} ./read5.sub # test behavior of read -t 0 ${THIS_SH} ./read6.sub + +# test behavior of readline timeouts +# ${THIS_SH} ./read7.sub diff --git a/tests/read2.sub b/tests/read2.sub index 41698e46..8c6f5306 100644 --- a/tests/read2.sub +++ b/tests/read2.sub @@ -13,25 +13,32 @@ # a=4 -read -t 2 a < /dev/tty +read -t 1 a < /dev/tty estat=$? if [ $estat -gt 128 ]; then echo timeout 1: ok else echo $estat fi +echo ${a:-unset or null 1} -echo $a - -sleep 5 | read -t 1 a +read -t 0.000001 a < /dev/tty estat=$? if [ $estat -gt 128 ]; then echo timeout 2: ok else echo $estat fi +echo ${a:-unset or null 2} -echo $a +sleep 1 | read -t 0.25 a +estat=$? +if [ $estat -gt 128 ]; then + echo timeout 3: ok +else + echo $estat +fi +echo ${a:-unset or null 3} read -t -3 a < /dev/tty echo $? @@ -40,6 +47,6 @@ echo $a # the above should all time out echo abcde | { - read -t 2 a + read -t 0.5 a echo $a } diff --git a/tests/read7.sub b/tests/read7.sub new file mode 100644 index 00000000..3410d9ff --- /dev/null +++ b/tests/read7.sub @@ -0,0 +1,55 @@ +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# test behavior of native readline timeouts + +read -t 0.001 -e var +estat=$? +if [ $estat -gt 128 ]; then + echo timeout 1: ok +else + echo $estat +fi +echo ${var:-unset or null 1} + +read -e -t 0.1 var +estat=$? +if [ $estat -gt 128 ]; then + echo timeout 2: ok +else + echo $estat +fi +echo ${var:-unset or null 2} + +read -e -t 1 var < /dev/tty +estat=$? +if [ $estat -gt 128 ]; then + echo timeout 3: ok +else + echo $estat +fi +echo ${var:-unset or null 3} + +sleep 2 | read -t 1 -e a +estat=$? +if [ $estat -gt 128 ]; then + echo timeout 4: ok +else + echo $estat +fi + +# the above should all time out +echo abcde | { + read -e -t 2 a + echo $a +}