diff --git a/CHANGES b/CHANGES index 23c043e2..bc41c5e7 100644 --- a/CHANGES +++ b/CHANGES @@ -238,6 +238,15 @@ yyy. When `test' is supplied four or more arguments, treat an argument that zzz. There is no `compat50' shopt option. Changes to the shell compatibility level should use the BASH_COMPAT variable. +aaaa. Redirection failures with compound commands are now treated as errors + that cause the shell to exit if `errexit' is enabled. + +bbbb. Redirection failure error messages no longer expand the word in the + redirection again. + +cccc. History expansion is no longer performed while parsing a here-document + inside a command substitution. + 2. Changes to Readline a. There are a number of fixes that were found as the result of fuzzing with @@ -292,6 +301,9 @@ p. Readline only calls chown(2) on a newly-written history file if it really q. Readline now behaves better when operate-and-get-next is used when the history list is `full': when there are already $HISTSIZE entries. +r. Fixed a bug that could cause vi redo (`.') of a replace command not to work + correctly in the C or POSIX locale. + 3. New Features in Bash a. `bind -x' now supports different bindings for different editing modes and @@ -415,6 +427,9 @@ mm. The associative array implementation can now dynamically increase the nn. HISTFILE is now readonly in a restricted shell. +oo. The bash malloc now returns memory that is 16-byte aligned on 64-bit + systems. + 4. New Features in Readline a. If a second consecutive completion attempt produces matches where the first diff --git a/CHANGES-5.1 b/CHANGES-5.1 index 0e7a55a2..6673ad48 100644 --- a/CHANGES-5.1 +++ b/CHANGES-5.1 @@ -238,6 +238,15 @@ yyy. When `test' is supplied four or more arguments, treat an argument that zzz. There is no `compat50' shopt option. Changes to the shell compatibility level should use the BASH_COMPAT variable. +aaaa. Redirection failures with compound commands are now treated as errors + that cause the shell to exit if `errexit' is enabled. + +bbbb. Redirection failure error messages no longer expand the word in the + redirection again. + +cccc. History expansion is no longer performed while parsing a here-document + inside a command substitution. + 2. Changes to Readline a. There are a number of fixes that were found as the result of fuzzing with @@ -292,6 +301,9 @@ p. Readline only calls chown(2) on a newly-written history file if it really q. Readline now behaves better when operate-and-get-next is used when the history list is `full': when there are already $HISTSIZE entries. +r. Fixed a bug that could cause vi redo (`.') of a replace command not to work + correctly in the C or POSIX locale. + 3. New Features in Bash a. `bind -x' now supports different bindings for different editing modes and @@ -415,6 +427,9 @@ mm. The associative array implementation can now dynamically increase the nn. HISTFILE is now readonly in a restricted shell. +oo. The bash malloc now returns memory that is 16-byte aligned on 64-bit + systems. + 4. New Features in Readline a. If a second consecutive completion attempt produces matches where the first diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index d23f8404..c90232c2 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -8482,3 +8482,38 @@ redir.c if appropriate. Free FN in any case, since do_redirection_internal won't. Fix for double expansion of filename in certain redirections reported by OÄuz + + 6/4 + --- +parse.y + - parse_comsub: while we're reading a here-document, don't perform any + history expansion (set history_expansion_inhibited). Fixes issue + reported by "ladyrick" + +general.h,parse.y + - __P -> PARAMS + +shell.c + - shellstart: struct timeval used to initialize shell starting time; + shell_start_time now initialized from shellstart.tv_sec + +variables.c + - assign_seconds: reset shellstart to set shell starting time + +pcomplete.c + - include posixtime.h instead of + +lib/sh/{ufuncs,uconvert}.c + - include posixtime.h instead of the inline conditional includes + +aclocal.m4 + - BASH_STRUCT_TIMEVAL: convert to use AC_COMPILE_IFELSE instead of the + deprecated AC_HEADER_EGREP + +posixtime.h + - struct timeval: if HAVE_TIMEVAL is not defined, provide a replacement + definition + +lib/sh/gettimeofday.c + - gettimeofday: replacement function, so we don't have to use + HAVE_GETTIMEOFDAY in the rest of the code diff --git a/MANIFEST b/MANIFEST index 7a945e05..2bc9fa4b 100644 --- a/MANIFEST +++ b/MANIFEST @@ -405,6 +405,7 @@ lib/sh/fnxform.c f lib/sh/fpurge.c f lib/sh/getcwd.c f lib/sh/getenv.c f +lib/sh/gettimeofday.c f lib/sh/inet_aton.c f lib/sh/input_avail.c f lib/sh/itos.c f @@ -1135,6 +1136,7 @@ tests/histexp3.sub f tests/histexp4.sub f tests/histexp5.sub f tests/histexp6.sub f +tests/histexp7.sub f tests/histexp.right f tests/history.tests f tests/history.right f diff --git a/Makefile.in b/Makefile.in index f9e99fba..3a3ec754 100644 --- a/Makefile.in +++ b/Makefile.in @@ -231,7 +231,8 @@ SHLIB_SOURCE = ${SH_LIBSRC}/clktck.c ${SH_LIBSRC}/getcwd.c \ ${SH_LIBSRC}/input_avail.c ${SH_LIBSRC}/mbscasecmp.c \ ${SH_LIBSRC}/fnxform.c ${SH_LIBSRC}/unicode.c \ ${SH_LIBSRC}/wcswidth.c ${SH_LIBSRC}/wcsnwidth.c \ - ${SH_LIBSRC}/shmbchar.c ${SH_LIBSRC}/utf8.c ${SH_LIBSRC}/random.c + ${SH_LIBSRC}/shmbchar.c ${SH_LIBSRC}/utf8.c \ + ${SH_LIBSRC}/random.c ${SH_LIBSRC}/gettimeofday.c SHLIB_LIB = -lsh SHLIB_LIBNAME = libsh.a diff --git a/NEWS b/NEWS index 19f6d9fd..bc2392f4 100644 --- a/NEWS +++ b/NEWS @@ -125,6 +125,9 @@ mm. The associative array implementation can now dynamically increase the nn. HISTFILE is now readonly in a restricted shell. +oo. The bash malloc now returns memory that is 16-byte aligned on 64-bit + systems. + 2. New Features in Readline a. If a second consecutive completion attempt produces matches where the first diff --git a/NEWS-5.1 b/NEWS-5.1 index 8c303fa6..8a07052f 100644 --- a/NEWS-5.1 +++ b/NEWS-5.1 @@ -125,6 +125,9 @@ mm. The associative array implementation can now dynamically increase the nn. HISTFILE is now readonly in a restricted shell. +oo. The bash malloc now returns memory that is 16-byte aligned on 64-bit + systems. + 2. New Features in Readline a. If a second consecutive completion attempt produces matches where the first diff --git a/aclocal.m4 b/aclocal.m4 index a9627429..a29d26de 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1179,12 +1179,17 @@ fi AC_DEFUN(BASH_STRUCT_TIMEVAL, [AC_MSG_CHECKING(for struct timeval in sys/time.h and time.h) AC_CACHE_VAL(bash_cv_struct_timeval, -[ -AC_EGREP_HEADER(struct timeval, sys/time.h, - bash_cv_struct_timeval=yes, - AC_EGREP_HEADER(struct timeval, time.h, - bash_cv_struct_timeval=yes, - bash_cv_struct_timeval=no)) +[AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#if HAVE_SYS_TIME_H + #include + #endif + #include + ]], + [[static struct timeval x; x.tv_sec = x.tv_usec;]] + )], + bash_cv_struct_timeval=yes, + bash_cv_struct_timeval=no) ]) AC_MSG_RESULT($bash_cv_struct_timeval) if test $bash_cv_struct_timeval = yes; then diff --git a/configure b/configure index 1b4ec212..ed719853 100755 --- a/configure +++ b/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.ac for Bash 5.1, version 5.017. +# From configure.ac for Bash 5.1, version 5.018. # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for bash 5.1-alpha. # @@ -18068,32 +18068,28 @@ $as_echo_n "checking for struct timeval in sys/time.h and time.h... " >&6; } if ${bash_cv_struct_timeval+:} false; then : $as_echo_n "(cached) " >&6 else - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "struct timeval" >/dev/null 2>&1; then : - bash_cv_struct_timeval=yes -else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include +#if HAVE_SYS_TIME_H + #include + #endif + #include +int +main () +{ +static struct timeval x; x.tv_sec = x.tv_usec; + + ; + return 0; +} _ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "struct timeval" >/dev/null 2>&1; then : +if ac_fn_c_try_compile "$LINENO"; then : bash_cv_struct_timeval=yes else bash_cv_struct_timeval=no fi -rm -f conftest* - -fi -rm -f conftest* - +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi diff --git a/configure.ac b/configure.ac index 4bcdd530..9b26de4b 100644 --- a/configure.ac +++ b/configure.ac @@ -21,7 +21,7 @@ dnl Process this file with autoconf to produce a configure script. # You should have received a copy of the GNU General Public License # along with this program. If not, see . -AC_REVISION([for Bash 5.1, version 5.017])dnl +AC_REVISION([for Bash 5.1, version 5.018])dnl define(bashvers, 5.1) define(relstatus, alpha) diff --git a/execute_cmd.c b/execute_cmd.c index 0542dbc8..0ba17f6c 100644 --- a/execute_cmd.c +++ b/execute_cmd.c @@ -109,6 +109,9 @@ extern int errno; extern int command_string_index; extern char *the_printed_command; extern time_t shell_start_time; +#if defined (HAVE_GETTIMEOFDAY) +extern struct timeval shellstart; +#endif #if 0 extern char *glob_argv_flags; #endif @@ -1356,8 +1359,7 @@ time_command (command, asynchronous, pipe_in, pipe_out, fds_to_close) #if defined (HAVE_GETRUSAGE) selfb.ru_utime.tv_sec = kidsb.ru_utime.tv_sec = selfb.ru_stime.tv_sec = kidsb.ru_stime.tv_sec = 0; selfb.ru_utime.tv_usec = kidsb.ru_utime.tv_usec = selfb.ru_stime.tv_usec = kidsb.ru_stime.tv_usec = 0; - before.tv_sec = shell_start_time; - before.tv_usec = 0; + before = shellstart; #else before.tms_utime = before.tms_stime = before.tms_cutime = before.tms_cstime = 0; tbefore = shell_start_time; diff --git a/general.h b/general.h index 28b45cab..7e4db8e6 100644 --- a/general.h +++ b/general.h @@ -1,6 +1,6 @@ /* general.h -- defines that everybody likes to use. */ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2020 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -62,7 +62,7 @@ extern char *strchr (), *strrchr (); #endif #if !defined (strcpy) && (defined (HAVE_DECL_STRCPY) && !HAVE_DECL_STRCPY) -extern char *strcpy __P((char *, const char *)); +extern char *strcpy PARAMS((char *, const char *)); #endif #if !defined (savestring) @@ -205,43 +205,43 @@ typedef char **CPPFunction (); /* no longer used */ /* Shell function typedefs with prototypes */ /* `Generic' function pointer typedefs */ -typedef int sh_intfunc_t __P((int)); -typedef int sh_ivoidfunc_t __P((void)); -typedef int sh_icpfunc_t __P((char *)); -typedef int sh_icppfunc_t __P((char **)); -typedef int sh_iptrfunc_t __P((PTR_T)); +typedef int sh_intfunc_t PARAMS((int)); +typedef int sh_ivoidfunc_t PARAMS((void)); +typedef int sh_icpfunc_t PARAMS((char *)); +typedef int sh_icppfunc_t PARAMS((char **)); +typedef int sh_iptrfunc_t PARAMS((PTR_T)); -typedef void sh_voidfunc_t __P((void)); -typedef void sh_vintfunc_t __P((int)); -typedef void sh_vcpfunc_t __P((char *)); -typedef void sh_vcppfunc_t __P((char **)); -typedef void sh_vptrfunc_t __P((PTR_T)); +typedef void sh_voidfunc_t PARAMS((void)); +typedef void sh_vintfunc_t PARAMS((int)); +typedef void sh_vcpfunc_t PARAMS((char *)); +typedef void sh_vcppfunc_t PARAMS((char **)); +typedef void sh_vptrfunc_t PARAMS((PTR_T)); -typedef int sh_wdesc_func_t __P((WORD_DESC *)); -typedef int sh_wlist_func_t __P((WORD_LIST *)); +typedef int sh_wdesc_func_t PARAMS((WORD_DESC *)); +typedef int sh_wlist_func_t PARAMS((WORD_LIST *)); -typedef int sh_glist_func_t __P((GENERIC_LIST *)); +typedef int sh_glist_func_t PARAMS((GENERIC_LIST *)); -typedef char *sh_string_func_t __P((char *)); /* like savestring, et al. */ +typedef char *sh_string_func_t PARAMS((char *)); /* like savestring, et al. */ -typedef int sh_msg_func_t __P((const char *, ...)); /* printf(3)-like */ -typedef void sh_vmsg_func_t __P((const char *, ...)); /* printf(3)-like */ +typedef int sh_msg_func_t PARAMS((const char *, ...)); /* printf(3)-like */ +typedef void sh_vmsg_func_t PARAMS((const char *, ...)); /* printf(3)-like */ /* Specific function pointer typedefs. Most of these could be done with #defines. */ -typedef void sh_sv_func_t __P((char *)); /* sh_vcpfunc_t */ -typedef void sh_free_func_t __P((PTR_T)); /* sh_vptrfunc_t */ -typedef void sh_resetsig_func_t __P((int)); /* sh_vintfunc_t */ +typedef void sh_sv_func_t PARAMS((char *)); /* sh_vcpfunc_t */ +typedef void sh_free_func_t PARAMS((PTR_T)); /* sh_vptrfunc_t */ +typedef void sh_resetsig_func_t PARAMS((int)); /* sh_vintfunc_t */ -typedef int sh_ignore_func_t __P((const char *)); /* sh_icpfunc_t */ +typedef int sh_ignore_func_t PARAMS((const char *)); /* sh_icpfunc_t */ -typedef int sh_assign_func_t __P((const char *)); -typedef int sh_wassign_func_t __P((WORD_DESC *, int)); +typedef int sh_assign_func_t PARAMS((const char *)); +typedef int sh_wassign_func_t PARAMS((WORD_DESC *, int)); -typedef int sh_load_func_t __P((char *)); -typedef void sh_unload_func_t __P((char *)); +typedef int sh_load_func_t PARAMS((char *)); +typedef void sh_unload_func_t PARAMS((char *)); -typedef int sh_builtin_func_t __P((WORD_LIST *)); /* sh_wlist_func_t */ +typedef int sh_builtin_func_t PARAMS((WORD_LIST *)); /* sh_wlist_func_t */ #endif /* SH_FUNCTION_TYPEDEF */ @@ -295,77 +295,77 @@ typedef int QSFUNC (); #if 0 /* Declarations for functions defined in xmalloc.c */ -extern PTR_T xmalloc __P((size_t)); -extern PTR_T xrealloc __P((void *, size_t)); -extern void xfree __P((void *)); +extern PTR_T xmalloc PARAMS((size_t)); +extern PTR_T xrealloc PARAMS((void *, size_t)); +extern void xfree PARAMS((void *)); #endif /* Declarations for functions defined in general.c */ -extern void posix_initialize __P((int)); +extern void posix_initialize PARAMS((int)); -extern int num_posix_options __P((void)); -extern char *get_posix_options __P((char *)); -extern void set_posix_options __P((const char *)); +extern int num_posix_options PARAMS((void)); +extern char *get_posix_options PARAMS((char *)); +extern void set_posix_options PARAMS((const char *)); -extern void save_posix_options __P((void)); +extern void save_posix_options PARAMS((void)); #if defined (RLIMTYPE) -extern RLIMTYPE string_to_rlimtype __P((char *)); -extern void print_rlimtype __P((RLIMTYPE, int)); +extern RLIMTYPE string_to_rlimtype PARAMS((char *)); +extern void print_rlimtype PARAMS((RLIMTYPE, int)); #endif -extern int all_digits __P((const char *)); -extern int legal_number __P((const char *, intmax_t *)); -extern int legal_identifier __P((const char *)); -extern int importable_function_name __P((const char *, size_t)); -extern int exportable_function_name __P((const char *)); -extern int check_identifier __P((WORD_DESC *, int)); -extern int valid_nameref_value __P((const char *, int)); -extern int check_selfref __P((const char *, char *, int)); -extern int legal_alias_name __P((const char *, int)); -extern int line_isblank __P((const char *)); -extern int assignment __P((const char *, int)); +extern int all_digits PARAMS((const char *)); +extern int legal_number PARAMS((const char *, intmax_t *)); +extern int legal_identifier PARAMS((const char *)); +extern int importable_function_name PARAMS((const char *, size_t)); +extern int exportable_function_name PARAMS((const char *)); +extern int check_identifier PARAMS((WORD_DESC *, int)); +extern int valid_nameref_value PARAMS((const char *, int)); +extern int check_selfref PARAMS((const char *, char *, int)); +extern int legal_alias_name PARAMS((const char *, int)); +extern int line_isblank PARAMS((const char *)); +extern int assignment PARAMS((const char *, int)); -extern int sh_unset_nodelay_mode __P((int)); -extern int sh_setclexec __P((int)); -extern int sh_validfd __P((int)); -extern int fd_ispipe __P((int)); -extern void check_dev_tty __P((void)); -extern int move_to_high_fd __P((int, int, int)); -extern int check_binary_file __P((const char *, int)); +extern int sh_unset_nodelay_mode PARAMS((int)); +extern int sh_setclexec PARAMS((int)); +extern int sh_validfd PARAMS((int)); +extern int fd_ispipe PARAMS((int)); +extern void check_dev_tty PARAMS((void)); +extern int move_to_high_fd PARAMS((int, int, int)); +extern int check_binary_file PARAMS((const char *, int)); #ifdef _POSIXSTAT_H_ -extern int same_file __P((const char *, const char *, struct stat *, struct stat *)); +extern int same_file PARAMS((const char *, const char *, struct stat *, struct stat *)); #endif -extern int sh_openpipe __P((int *)); -extern int sh_closepipe __P((int *)); +extern int sh_openpipe PARAMS((int *)); +extern int sh_closepipe PARAMS((int *)); -extern int file_exists __P((const char *)); -extern int file_isdir __P((const char *)); -extern int file_iswdir __P((const char *)); -extern int path_dot_or_dotdot __P((const char *)); -extern int absolute_pathname __P((const char *)); -extern int absolute_program __P((const char *)); +extern int file_exists PARAMS((const char *)); +extern int file_isdir PARAMS((const char *)); +extern int file_iswdir PARAMS((const char *)); +extern int path_dot_or_dotdot PARAMS((const char *)); +extern int absolute_pathname PARAMS((const char *)); +extern int absolute_program PARAMS((const char *)); -extern char *make_absolute __P((const char *, const char *)); -extern char *base_pathname __P((char *)); -extern char *full_pathname __P((char *)); -extern char *polite_directory_format __P((char *)); -extern char *trim_pathname __P((char *, int)); -extern char *printable_filename __P((char *, int)); +extern char *make_absolute PARAMS((const char *, const char *)); +extern char *base_pathname PARAMS((char *)); +extern char *full_pathname PARAMS((char *)); +extern char *polite_directory_format PARAMS((char *)); +extern char *trim_pathname PARAMS((char *, int)); +extern char *printable_filename PARAMS((char *, int)); -extern char *extract_colon_unit __P((char *, int *)); +extern char *extract_colon_unit PARAMS((char *, int *)); -extern void tilde_initialize __P((void)); -extern char *bash_tilde_find_word __P((const char *, int, int *)); -extern char *bash_tilde_expand __P((const char *, int)); +extern void tilde_initialize PARAMS((void)); +extern char *bash_tilde_find_word PARAMS((const char *, int, int *)); +extern char *bash_tilde_expand PARAMS((const char *, int)); -extern int group_member __P((gid_t)); -extern char **get_group_list __P((int *)); -extern int *get_group_array __P((int *)); +extern int group_member PARAMS((gid_t)); +extern char **get_group_list PARAMS((int *)); +extern int *get_group_array PARAMS((int *)); -extern char *conf_standard_path __P((void)); -extern int default_columns __P((void)); +extern char *conf_standard_path PARAMS((void)); +extern int default_columns PARAMS((void)); #endif /* _GENERAL_H_ */ diff --git a/include/posixtime.h b/include/posixtime.h index 31bdddf8..a83e436b 100644 --- a/include/posixtime.h +++ b/include/posixtime.h @@ -46,4 +46,16 @@ # endif /* !CLK_TCK */ #endif /* !HAVE_SYSCONF && !_SC_CLK_TCK */ +#if !HAVE_TIMEVAL +struct timeval +{ + time_t tv_sec; + long int tv_usec; +}; +#endif + +#if !HAVE_GETTIMEOFDAY +extern int gettimeofday PARAMS((struct timeval *, void *)); +#endif + #endif /* _POSIXTIME_H_ */ diff --git a/lib/sh/Makefile.in b/lib/sh/Makefile.in index 9b1c2770..98064de5 100644 --- a/lib/sh/Makefile.in +++ b/lib/sh/Makefile.in @@ -93,7 +93,7 @@ CSOURCES = clktck.c clock.c getcwd.c getenv.c oslib.c setlinebuf.c \ wcsdup.c fpurge.c zgetline.c mbscmp.c uconvert.c ufuncs.c \ casemod.c dprintf.c input_avail.c mbscasecmp.c fnxform.c \ strchrnul.c unicode.c wcswidth.c wcsnwidth.c shmbchar.c strdup.c \ - utf8.c random.c + utf8.c random.c gettimeofday.c # The header files for this library. HSOURCES = @@ -108,7 +108,7 @@ OBJECTS = clktck.o clock.o getenv.o oslib.o setlinebuf.o strnlen.o \ fmtullong.o fmtumax.o zcatfd.o zmapfd.o winsize.o wcsdup.o \ fpurge.o zgetline.o mbscmp.o uconvert.o ufuncs.o casemod.o \ input_avail.o mbscasecmp.o fnxform.o unicode.o shmbchar.o \ - utf8.o random.o wcsnwidth.o ${LIBOBJS} + utf8.o random.o gettimeofday.o wcsnwidth.o ${LIBOBJS} SUPPORT = Makefile @@ -155,6 +155,7 @@ fnxform.o: fnxform.c fpurge.o: fpurge.c getcwd.o: getcwd.c getenv.o: getenv.c +gettimeofday.o: gettimeofday.c inet_aton.o: inet_aton.c input_avail.o: input_avail.c itos.o: itos.c @@ -234,6 +235,7 @@ fnxform.o: ${BUILD_DIR}/config.h fpurge.o: ${BUILD_DIR}/config.h getcwd.o: ${BUILD_DIR}/config.h getenv.o: ${BUILD_DIR}/config.h +gettimeofday.o: ${BUILD_DIR}/config.h inet_aton.o: ${BUILD_DIR}/config.h input_avail.o: ${BUILD_DIR}/config.h itos.o: ${BUILD_DIR}/config.h @@ -511,6 +513,7 @@ times.o: ${BASHINCDIR}/systimes.h times.o: ${BASHINCDIR}/posixtime.h timeval.o: ${BASHINCDIR}/posixtime.h +gettimeofday.o: ${BASHINCDIR}/posixtime.h tmpfile.o: ${topdir}/bashtypes.h tmpfile.o: ${BASHINCDIR}/chartypes.h diff --git a/lib/sh/gettimeofday.c b/lib/sh/gettimeofday.c new file mode 100644 index 00000000..b654c154 --- /dev/null +++ b/lib/sh/gettimeofday.c @@ -0,0 +1,35 @@ +/* gettimeofday.c - gettimeofday replacement using time() */ + +/* Copyright (C) 2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash 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. + + Bash 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 Bash. If not, see . +*/ + +#include "config.h" + +#if !defined (HAVE_GETTIMEOFDAY) + +#include "posixtime.h" + +/* A version of gettimeofday that just sets tv_sec from time(3) */ +int +gettimeofday (struct timeval *tv, void *tz) +{ + tv->tv_sec = (time_t) time ((time_t *)0); + tv->tv_usec = 0; + return 0; +} +#endif diff --git a/lib/sh/times.c b/lib/sh/times.c index 47ddf577..efaaa0dd 100644 --- a/lib/sh/times.c +++ b/lib/sh/times.c @@ -58,7 +58,7 @@ times(tms) tms->tms_cutime = CONVTCK(ru.ru_utime); tms->tms_cstime = CONVTCK(ru.ru_stime); - if (gettimeofday(&tv, (struct timezone *) 0) < 0) + if (gettimeofday(&tv, NULL) < 0) return ((clock_t)-1); rv = (clock_t)(CONVTCK(tv)); #else /* !HAVE_GETRUSAGE */ diff --git a/lib/sh/uconvert.c b/lib/sh/uconvert.c index d0453079..457552eb 100644 --- a/lib/sh/uconvert.c +++ b/lib/sh/uconvert.c @@ -23,16 +23,7 @@ #include "bashtypes.h" -#if defined (TIME_WITH_SYS_TIME) -# include -# include -#else -# if defined (HAVE_SYS_TIME_H) -# include -# else -# include -# endif -#endif +#include "posixtime.h" #if defined (HAVE_UNISTD_H) #include diff --git a/lib/sh/ufuncs.c b/lib/sh/ufuncs.c index c1251395..4dc4853b 100644 --- a/lib/sh/ufuncs.c +++ b/lib/sh/ufuncs.c @@ -1,6 +1,6 @@ /* ufuncs - sleep and alarm functions that understand fractional values */ -/* Copyright (C) 2008,2009 Free Software Foundation, Inc. +/* Copyright (C) 2008,2009-2020 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -22,16 +22,7 @@ #include "bashtypes.h" -#if defined (TIME_WITH_SYS_TIME) -# include -# include -#else -# if defined (HAVE_SYS_TIME_H) -# include -# else -# include -# endif -#endif +#include "posixtime.h" #if defined (HAVE_UNISTD_H) #include diff --git a/parse.y b/parse.y index b06809c6..4bb15029 100644 --- a/parse.y +++ b/parse.y @@ -71,7 +71,7 @@ #if defined (JOB_CONTROL) # include "jobs.h" #else -extern int cleanup_dead_jobs __P((void)); +extern int cleanup_dead_jobs PARAMS((void)); #endif /* JOB_CONTROL */ #if defined (ALIAS) @@ -131,90 +131,90 @@ extern int errno; /* **************************************************************** */ #ifdef DEBUG -static void debug_parser __P((int)); +static void debug_parser PARAMS((int)); #endif -static int yy_getc __P((void)); -static int yy_ungetc __P((int)); +static int yy_getc PARAMS((void)); +static int yy_ungetc PARAMS((int)); #if defined (READLINE) -static int yy_readline_get __P((void)); -static int yy_readline_unget __P((int)); +static int yy_readline_get PARAMS((void)); +static int yy_readline_unget PARAMS((int)); #endif -static int yy_string_get __P((void)); -static int yy_string_unget __P((int)); -static void rewind_input_string __P((void)); -static int yy_stream_get __P((void)); -static int yy_stream_unget __P((int)); +static int yy_string_get PARAMS((void)); +static int yy_string_unget PARAMS((int)); +static void rewind_input_string PARAMS((void)); +static int yy_stream_get PARAMS((void)); +static int yy_stream_unget PARAMS((int)); -static int shell_getc __P((int)); -static void shell_ungetc __P((int)); -static void discard_until __P((int)); +static int shell_getc PARAMS((int)); +static void shell_ungetc PARAMS((int)); +static void discard_until PARAMS((int)); #if defined (ALIAS) || defined (DPAREN_ARITHMETIC) -static void push_string __P((char *, int, alias_t *)); -static void pop_string __P((void)); -static void free_string_list __P((void)); +static void push_string PARAMS((char *, int, alias_t *)); +static void pop_string PARAMS((void)); +static void free_string_list PARAMS((void)); #endif -static char *read_a_line __P((int)); +static char *read_a_line PARAMS((int)); -static int reserved_word_acceptable __P((int)); -static int yylex __P((void)); +static int reserved_word_acceptable PARAMS((int)); +static int yylex PARAMS((void)); -static void push_heredoc __P((REDIRECT *)); -static char *mk_alexpansion __P((char *)); -static int alias_expand_token __P((char *)); -static int time_command_acceptable __P((void)); -static int special_case_tokens __P((char *)); -static int read_token __P((int)); -static char *parse_matched_pair __P((int, int, int, int *, int)); -static char *parse_comsub __P((int, int, int, int *, int)); +static void push_heredoc PARAMS((REDIRECT *)); +static char *mk_alexpansion PARAMS((char *)); +static int alias_expand_token PARAMS((char *)); +static int time_command_acceptable PARAMS((void)); +static int special_case_tokens PARAMS((char *)); +static int read_token PARAMS((int)); +static char *parse_matched_pair PARAMS((int, int, int, int *, int)); +static char *parse_comsub PARAMS((int, int, int, int *, int)); #if defined (ARRAY_VARS) -static char *parse_compound_assignment __P((int *)); +static char *parse_compound_assignment PARAMS((int *)); #endif #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND) -static int parse_dparen __P((int)); -static int parse_arith_cmd __P((char **, int)); +static int parse_dparen PARAMS((int)); +static int parse_arith_cmd PARAMS((char **, int)); #endif #if defined (COND_COMMAND) -static void cond_error __P((void)); -static COND_COM *cond_expr __P((void)); -static COND_COM *cond_or __P((void)); -static COND_COM *cond_and __P((void)); -static COND_COM *cond_term __P((void)); -static int cond_skip_newlines __P((void)); -static COMMAND *parse_cond_command __P((void)); +static void cond_error PARAMS((void)); +static COND_COM *cond_expr PARAMS((void)); +static COND_COM *cond_or PARAMS((void)); +static COND_COM *cond_and PARAMS((void)); +static COND_COM *cond_term PARAMS((void)); +static int cond_skip_newlines PARAMS((void)); +static COMMAND *parse_cond_command PARAMS((void)); #endif #if defined (ARRAY_VARS) -static int token_is_assignment __P((char *, int)); -static int token_is_ident __P((char *, int)); +static int token_is_assignment PARAMS((char *, int)); +static int token_is_ident PARAMS((char *, int)); #endif -static int read_token_word __P((int)); -static void discard_parser_constructs __P((int)); +static int read_token_word PARAMS((int)); +static void discard_parser_constructs PARAMS((int)); -static char *error_token_from_token __P((int)); -static char *error_token_from_text __P((void)); -static void print_offending_line __P((void)); -static void report_syntax_error __P((char *)); +static char *error_token_from_token PARAMS((int)); +static char *error_token_from_text PARAMS((void)); +static void print_offending_line PARAMS((void)); +static void report_syntax_error PARAMS((char *)); -static void handle_eof_input_unit __P((void)); -static void prompt_again __P((void)); +static void handle_eof_input_unit PARAMS((void)); +static void prompt_again PARAMS((void)); #if 0 -static void reset_readline_prompt __P((void)); +static void reset_readline_prompt PARAMS((void)); #endif -static void print_prompt __P((void)); +static void print_prompt PARAMS((void)); #if defined (HANDLE_MULTIBYTE) -static void set_line_mbstate __P((void)); +static void set_line_mbstate PARAMS((void)); static char *shell_input_line_property = NULL; static size_t shell_input_line_propsize = 0; #else # define set_line_mbstate() #endif -extern int yyerror __P((const char *)); +extern int yyerror PARAMS((const char *)); #ifdef DEBUG extern int yydebug; @@ -3905,7 +3905,7 @@ parse_comsub (qc, open, close, lenp, flags) int *lenp, flags; { int count, ch, peekc, tflags, lex_rwlen, lex_wlen, lex_firstind; - int nestlen, ttranslen, start_lineno; + int nestlen, ttranslen, start_lineno, orig_histexp; char *ret, *nestret, *ttrans, *heredelim; int retind, retsize, rflags, hdlen; @@ -3919,6 +3919,9 @@ parse_comsub (qc, open, close, lenp, flags) /*itrace("parse_comsub: qc = `%c' open = %c close = %c", qc, open, close);*/ count = 1; tflags = LEX_RESWDOK; +#if defined (BANG_HISTORY) + orig_histexp = history_expansion_inhibited; +#endif if ((flags & P_COMMAND) && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0) tflags |= LEX_CKCASE; @@ -3945,6 +3948,9 @@ comsub_readchar: if (ch == EOF) { eof_error: +#if defined (BANG_HISTORY) + history_expansion_inhibited = orig_histexp; +#endif free (ret); FREE (heredelim); parser_error (start_lineno, _("unexpected EOF while looking for matching `%c'"), close); @@ -3963,6 +3969,9 @@ eof_error: { tflags &= ~LEX_HEREDELIM; tflags |= LEX_INHEREDOC; +#if defined (BANG_HISTORY) + history_expansion_inhibited = 1; +#endif lex_firstind = retind + 1; } else if (tflags & LEX_INHEREDOC) @@ -3978,6 +3987,9 @@ eof_error: free (heredelim); heredelim = 0; lex_firstind = -1; +#if defined (BANG_HISTORY) + history_expansion_inhibited = orig_histexp; +#endif } else lex_firstind = retind + 1; @@ -4012,6 +4024,9 @@ eof_error: free (heredelim); heredelim = 0; lex_firstind = -1; +#if defined (BANG_HISTORY) + history_expansion_inhibited = orig_histexp; +#endif } } @@ -4122,6 +4137,9 @@ eof_error: tflags |= LEX_INHEREDOC; tflags &= ~LEX_HEREDELIM; lex_firstind = retind + 1; +#if defined (BANG_HISTORY) + history_expansion_inhibited = 1; +#endif } #endif else if (lex_firstind >= 0 && (tflags & LEX_PASSNEXT) == 0 && shellbreak (ch)) @@ -4141,6 +4159,9 @@ eof_error: tflags |= LEX_INHEREDOC; tflags &= ~LEX_HEREDELIM; lex_firstind = retind + 1; +#if defined (BANG_HISTORY) + history_expansion_inhibited = 1; +#endif } else lex_firstind = -1; @@ -4411,6 +4432,9 @@ eof_error: tflags &= ~LEX_WASDOL; } +#if defined (BANG_HISTORY) + history_expansion_inhibited = orig_histexp; +#endif FREE (heredelim); ret[retind] = '\0'; if (lenp) diff --git a/pcomplete.c b/pcomplete.c index 5014c21a..ab7c4bac 100644 --- a/pcomplete.c +++ b/pcomplete.c @@ -37,7 +37,7 @@ # include #endif -#include +#include "posixtime.h" #include #include "bashansi.h" diff --git a/shell.c b/shell.c index 985ad9ee..7bfce2b9 100644 --- a/shell.c +++ b/shell.c @@ -179,6 +179,7 @@ char *shell_name = (char *)NULL; /* time in seconds when the shell was started */ time_t shell_start_time; +struct timeval shellstart; /* Are we running in an emacs shell window? */ int running_under_emacs; @@ -458,7 +459,9 @@ main (argc, argv, env) shell_environment = env; set_shell_name (argv[0]); - shell_start_time = NOW; /* NOW now defined in general.h */ + + gettimeofday (&shellstart, 0); + shell_start_time = shellstart.tv_sec; /* Parse argument flags from the input line. */ diff --git a/tests/histexp.right b/tests/histexp.right index 8439de99..341252c0 100644 --- a/tests/histexp.right +++ b/tests/histexp.right @@ -240,3 +240,7 @@ echo two 1 echo two 2 for f in a b c; do echo echo two; done 3 history +a +echo !! +--between-- +echo !! diff --git a/tests/histexp.tests b/tests/histexp.tests index 218af095..91a36f23 100644 --- a/tests/histexp.tests +++ b/tests/histexp.tests @@ -155,3 +155,4 @@ ${THIS_SH} ./histexp3.sub ${THIS_SH} ./histexp4.sub ${THIS_SH} ./histexp5.sub ${THIS_SH} ./histexp6.sub +${THIS_SH} ./histexp7.sub diff --git a/tests/histexp7.sub b/tests/histexp7.sub new file mode 100644 index 00000000..8822205e --- /dev/null +++ b/tests/histexp7.sub @@ -0,0 +1,18 @@ +# make sure history expansion doesn't take place while parsing command +# substitutions + +set -o history +set -o histexpand +echo a + +echo $( cat <