reset_parser already freed it and we don't want to try and restore
it in restore_parser_state.
From a report by Nathan Mills <the.true.nathan.mills@gmail.com>
+
+ 1/10
+ ----
+builtins/hash.def, builtins/ulimit.def
+ - add some calls to sh_chkwrite where there is builtin output
+
+lib/sh/eaccess.c
+ - sh_stat: use strcpy/strcpy when constructing pbuf instead of
+ strcpy/strcat
+
+lib/sh/tmpfile.c
+ - sh_mktmpname,sh_mktmpfd,sh_mktmpdir: use snprintf (filename, PATH_MAX, ...)
+ instead of sprintf (filename, ...)
+
+ 1/11
+ ----
+configure.ac
+ - unconditionally AC_DEFINE(PGRP_PIPE), to prevent the problem with a
+ pipeline and a DEBUG trap containing an external command described
+ in https://lists.gnu.org/archive/html/bug-bash/2024-01/msg00037.html
+
+ 1/12
+ ----
+jobs.c
+ - wait_for_any_job: if we're executing a funsub/varsub, do the wait
+ even if the jobs list is frozen, but don't remove the job from the
+ table or change its notification status
+ Report from Oguz <oguzismailuysal@gmail.com>
+
+subst.c
+ - uw_unbind_variable: unset the first instance of the named variable,
+ don't follow namerefs. This is for REPLY in a varsub if it's made
+ a nameref.
+ Report from Oguz <oguzismailuysal@gmail.com>
+
+shell.c
+ - main: call compat_init() so the linker drags in the old compatibility
+ functions from lib/sh/compat.c. Primarily for use by existing loadable
+ builtins
+
+parse.y
+ - parse_compound_assignment: handle error case (wl == &parse_string_error)
+ before restoring the parser state from ps
+ Report from Grisha Levit <grishalevit@gmail.com>
if (list == 0 && (delete || list_targets))
{
sh_needarg (delete ? "-d" : "-t");
- return (EXECUTION_FAILURE);
+ return (sh_chkwrite (EXECUTION_FAILURE));
}
/* It's an error to specify a pathname to hash to, but no name to hash. */
free (target);
}
- return (all_found ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
+ return (sh_chkwrite (all_found ? EXECUTION_SUCCESS : EXECUTION_FAILURE));
}
if (ulimit_internal (cmdlist[c].cmd, cmdlist[c].arg, mode, ncmd > 1) == EXECUTION_FAILURE)
return (EXECUTION_FAILURE);
- return (EXECUTION_SUCCESS);
+ return (sh_chkwrite (EXECUTION_SUCCESS));
}
static int
#! /bin/sh
-# From configure.ac for Bash 5.3, version 5.059.
+# From configure.ac for Bash 5.3, version 5.060.
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.71 for bash 5.3-devel.
#
VM page cache was not coherent with the file system buffer cache
like early versions of FreeBSD and possibly contemporary NetBSD.)
For shared mappings, we should conversely verify that changes get
- propagated back to all the places they're supposed to be.
-
- Grep wants private fixed already mapped.
- The main things grep needs to know about mmap are:
- * does it exist and is it safe to write into the mmap'd area
- * how to use it (BSD variants) */
+ propagated back to all the places they're supposed to be. */
#include <fcntl.h>
#include <sys/mman.h>
-/* This mess was copied from the GNU getpagesize.h. */
-#ifndef HAVE_GETPAGESIZE
+#ifndef getpagesize
# ifdef _SC_PAGESIZE
-# define getpagesize() sysconf(_SC_PAGESIZE)
-# else /* no _SC_PAGESIZE */
+# define getpagesize() sysconf (_SC_PAGESIZE)
+# elif defined _SC_PAGE_SIZE
+# define getpagesize() sysconf (_SC_PAGE_SIZE)
+# elif HAVE_GETPAGESIZE
+int getpagesize ();
+# else
# ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
# ifdef EXEC_PAGESIZE
# else /* no HAVE_SYS_PARAM_H */
# define getpagesize() 8192 /* punt totally */
# endif /* no HAVE_SYS_PARAM_H */
-# endif /* no _SC_PAGESIZE */
-
-#endif /* no HAVE_GETPAGESIZE */
+# endif
+#endif
int
main (void)
{
char *data, *data2, *data3;
const char *cdata2;
- int i, pagesize;
+ long i, pagesize;
int fd, fd2;
pagesize = getpagesize ();
LIBS=$save_LIBS
test $gl_pthread_api = yes && break
done
- echo "$as_me:9061: gl_pthread_api=$gl_pthread_api" >&5
- echo "$as_me:9062: LIBPTHREAD=$LIBPTHREAD" >&5
+ echo "$as_me:9058: gl_pthread_api=$gl_pthread_api" >&5
+ echo "$as_me:9059: LIBPTHREAD=$LIBPTHREAD" >&5
gl_pthread_in_glibc=no
# On Linux with glibc >= 2.34, libc contains the fully functional
;;
esac
- echo "$as_me:9088: gl_pthread_in_glibc=$gl_pthread_in_glibc" >&5
+ echo "$as_me:9085: gl_pthread_in_glibc=$gl_pthread_in_glibc" >&5
# Test for libpthread by looking for pthread_kill. (Not pthread_self,
# since it is defined as a macro on OSF/1.)
fi
fi
- echo "$as_me:9242: LIBPMULTITHREAD=$LIBPMULTITHREAD" >&5
+ echo "$as_me:9239: LIBPMULTITHREAD=$LIBPMULTITHREAD" >&5
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether POSIX threads API is available" >&5
printf %s "checking whether POSIX threads API is available... " >&6; }
LIBS=$save_LIBS
test $gl_pthread_api = yes && break
done
- echo "$as_me:9470: gl_pthread_api=$gl_pthread_api" >&5
- echo "$as_me:9471: LIBPTHREAD=$LIBPTHREAD" >&5
+ echo "$as_me:9467: gl_pthread_api=$gl_pthread_api" >&5
+ echo "$as_me:9468: LIBPTHREAD=$LIBPTHREAD" >&5
gl_pthread_in_glibc=no
# On Linux with glibc >= 2.34, libc contains the fully functional
;;
esac
- echo "$as_me:9497: gl_pthread_in_glibc=$gl_pthread_in_glibc" >&5
+ echo "$as_me:9494: gl_pthread_in_glibc=$gl_pthread_in_glibc" >&5
# Test for libpthread by looking for pthread_kill. (Not pthread_self,
# since it is defined as a macro on OSF/1.)
fi
fi
- echo "$as_me:9651: LIBPMULTITHREAD=$LIBPMULTITHREAD" >&5
+ echo "$as_me:9648: LIBPMULTITHREAD=$LIBPMULTITHREAD" >&5
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether POSIX threads API is available" >&5
printf %s "checking whether POSIX threads API is available... " >&6; }
VM page cache was not coherent with the file system buffer cache
like early versions of FreeBSD and possibly contemporary NetBSD.)
For shared mappings, we should conversely verify that changes get
- propagated back to all the places they're supposed to be.
-
- Grep wants private fixed already mapped.
- The main things grep needs to know about mmap are:
- * does it exist and is it safe to write into the mmap'd area
- * how to use it (BSD variants) */
+ propagated back to all the places they're supposed to be. */
#include <fcntl.h>
#include <sys/mman.h>
-/* This mess was copied from the GNU getpagesize.h. */
-#ifndef HAVE_GETPAGESIZE
+#ifndef getpagesize
# ifdef _SC_PAGESIZE
-# define getpagesize() sysconf(_SC_PAGESIZE)
-# else /* no _SC_PAGESIZE */
+# define getpagesize() sysconf (_SC_PAGESIZE)
+# elif defined _SC_PAGE_SIZE
+# define getpagesize() sysconf (_SC_PAGE_SIZE)
+# elif HAVE_GETPAGESIZE
+int getpagesize ();
+# else
# ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
# ifdef EXEC_PAGESIZE
# else /* no HAVE_SYS_PARAM_H */
# define getpagesize() 8192 /* punt totally */
# endif /* no HAVE_SYS_PARAM_H */
-# endif /* no _SC_PAGESIZE */
-
-#endif /* no HAVE_GETPAGESIZE */
+# endif
+#endif
int
main (void)
{
char *data, *data2, *data3;
const char *cdata2;
- int i, pagesize;
+ long i, pagesize;
int fd, fd2;
pagesize = getpagesize ();
fi
-
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pgrps need synchronization" >&5
-printf %s "checking whether pgrps need synchronization... " >&6; }
-if test ${bash_cv_pgrp_pipe+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
- if test "$cross_compiling" = yes
-then :
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cannot check pgrp synchronization if cross compiling -- defaulting to no" >&5
-printf "%s\n" "$as_me: WARNING: cannot check pgrp synchronization if cross compiling -- defaulting to no" >&2;}
- bash_cv_pgrp_pipe=no
-
-else $as_nop
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-#ifdef HAVE_SYS_WAIT_H
-# include <sys/wait.h>
-#endif
-#include <stdlib.h>
-int
-main()
-{
-# ifdef GETPGRP_VOID
-# define getpgID() getpgrp()
-# else
-# define getpgID() getpgrp(0)
-# define setpgid(x,y) setpgrp(x,y)
-# endif
- int pid1, pid2, fds[2];
- int status;
- char ok;
-
- switch (pid1 = fork()) {
- case -1:
- exit(1);
- case 0:
- setpgid(0, getpid());
- exit(0);
- }
- setpgid(pid1, pid1);
-
- sleep(2); /* let first child die */
-
- if (pipe(fds) < 0)
- exit(2);
-
- switch (pid2 = fork()) {
- case -1:
- exit(3);
- case 0:
- setpgid(0, pid1);
- ok = getpgID() == pid1;
- write(fds[1], &ok, 1);
- exit(0);
- }
- setpgid(pid2, pid1);
-
- close(fds[1]);
- if (read(fds[0], &ok, 1) != 1)
- exit(4);
- wait(&status);
- wait(&status);
- exit(ok ? 0 : 5);
-}
-
-_ACEOF
-if ac_fn_c_try_run "$LINENO"
-then :
- bash_cv_pgrp_pipe=no
-else $as_nop
- bash_cv_pgrp_pipe=yes
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
- conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $bash_cv_pgrp_pipe" >&5
-printf "%s\n" "$bash_cv_pgrp_pipe" >&6; }
-if test $bash_cv_pgrp_pipe = yes; then
-printf "%s\n" "#define PGRP_PIPE 1" >>confdefs.h
-
-fi
-
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for type of signal functions" >&5
printf %s "checking for type of signal functions... " >&6; }
if test ${bash_cv_signal_vintage+y}
fi
+printf "%s\n" "#define PGRP_PIPE 1" >>confdefs.h
+
+
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sys_errlist and sys_nerr" >&5
printf %s "checking for sys_errlist and sys_nerr... " >&6; }
if test ${bash_cv_sys_errlist+y}
dnl
dnl Process this file with autoconf to produce a configure script.
-# Copyright (C) 1987-2023 Free Software Foundation, Inc.
+# Copyright (C) 1987-2024 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-AC_REVISION([for Bash 5.3, version 5.059])dnl
+AC_REVISION([for Bash 5.3, version 5.060])dnl
define(bashvers, 5.3)
define(relstatus, devel)
dnl behavior of system calls and library functions
BASH_FUNC_DUP2_CLOEXEC_CHECK
-BASH_SYS_PGRP_SYNC
BASH_SYS_SIGNAL_VINTAGE
+dnl https://lists.gnu.org/archive/html/bug-bash/2024-01/msg00047.html
+dnl BASH_SYS_PGRP_SYNC
+AC_DEFINE(PGRP_PIPE)
+
dnl checking for the presence of certain library symbols
BASH_SYS_ERRLIST
BASH_SYS_SIGLIST
extern void print_clock_t (FILE *, clock_t);
#endif
+/* Declarations for functions defined in lib/sh/compat.c */
+extern int compat_init (void);
+
/* Declarations for functions defined in lib/sh/dprintf.c */
#if !defined (HAVE_DPRINTF)
extern void dprintf (int, const char *, ...) __attribute__((__format__ (printf, 2, 3)));
int i, r;
sigset_t set, oset;
- if (jobs_list_frozen)
+ /* Allow funsubs to run this, but don't remove jobs from the jobs table. */
+ if (jobs_list_frozen && executing_funsub == 0)
return -1;
/* First see if there are any unnotified dead jobs that we can report on */
ps->pid = pid;
ps->status = r;
}
- notify_of_job_status (); /* XXX */
- delete_job (i, 0);
+ if (jobs_list_frozen == 0) /* must be running a funsub to get here */
+ {
+ notify_of_job_status (); /* XXX */
+ delete_job (i, 0);
+ }
#if defined (COPROCESS_SUPPORT)
coproc_reap ();
#endif
effectively a no-op. */
pbuf = xrealloc (pbuf, sizeof (DEV_FD_PREFIX) + strlen (path + 8));
strcpy (pbuf, DEV_FD_PREFIX);
- strcat (pbuf, path + 8);
+ strcpy (pbuf + sizeof (DEV_FD_PREFIX) - 1, path + 8);
return (stat (pbuf, finfo));
#endif /* !HAVE_DEV_FD */
}
if (flags & MT_TEMPLATE)
strcpy (filename, nameroot);
else
- sprintf (filename, "%s/%s.XXXXXX", tdir, lroot);
+ snprintf (filename, PATH_MAX, "%s/%s.XXXXXX", tdir, lroot);
if (mktemp (filename) == 0)
{
free (filename);
(unsigned long) time ((time_t *)0) ^
(unsigned long) dollar_dollar_pid ^
x;
- sprintf (filename, "%s/%s-%lu", tdir, lroot, filenum);
+ snprintf (filename, PATH_MAX, "%s/%s-%lu", tdir, lroot, filenum);
if (tmpnamelen > 0 && tmpnamelen < 32) /* XXX */
filename[tdlen + 1 + tmpnamelen] = '\0';
# ifdef HAVE_LSTAT
if (flags & MT_TEMPLATE)
strcpy (filename, nameroot);
else
- sprintf (filename, "%s/%s.XXXXXX", tdir, lroot);
+ snprintf (filename, PATH_MAX, "%s/%s.XXXXXX", tdir, lroot);
fd = mkstemp (filename);
if ((flags & MT_UNLINK) && tmpunlink (filename) < 0)
{
(unsigned long) time ((time_t *)0) ^
(unsigned long) dollar_dollar_pid ^
x;
- sprintf (filename, "%s/%s-%lu", tdir, lroot, filenum);
+ snprintf (filename, PATH_MAX, "%s/%s-%lu", tdir, lroot, filenum);
if (tmpnamelen > 0 && tmpnamelen < 32) /* XXX */
filename[tdlen + 1 + tmpnamelen] = '\0';
fd = open (filename, BASEOPENFLAGS | ((flags & MT_READWRITE) ? O_RDWR : O_WRONLY), 0600);
if (flags & MT_TEMPLATE)
strcpy (filename, nameroot);
else
- sprintf (filename, "%s/%s.XXXXXX", tdir, lroot);
+ snprintf (filename, PATH_MAX, "%s/%s.XXXXXX", tdir, lroot);
dirname = mkdtemp (filename);
if (dirname == 0)
{
wl = make_word_list (yylval.word, wl);
}
- /* Check whether or not an alias got popped out from underneath us and
- fix up after restore_parser_state. */
- if (ea && ss && ss != pushed_string_list)
- {
- restore_pushed_strings = 1;
- ss = pushed_string_list;
- }
- restore_parser_state (&ps);
- if (restore_pushed_strings)
- pushed_string_list = ss;
-
if (wl == &parse_string_error)
{
set_exit_status (EXECUTION_FAILURE);
last_read_token = current_token = '\n'; /* XXX */
+ /* This will eventually call reset_parser */
if (interactive_shell == 0 && posixly_correct)
jump_to_top_level (FORCE_EOF);
else
}
}
+ /* Check whether or not an alias got popped out from underneath us and
+ fix up after restore_parser_state. */
+ if (ea && ss && ss != pushed_string_list)
+ {
+ restore_pushed_strings = 1;
+ ss = pushed_string_list;
+ /* Don't bother with restoring the pushed string list from ps if we're
+ just going to overwrite it. */
+ ps.pushed_strings = NULL;
+ }
+ restore_parser_state (&ps);
+ if (restore_pushed_strings)
+ pushed_string_list = ss;
+
if (wl)
{
rl = REVERSE_LIST (wl, WORD_LIST *);
gnu_error_format = 1;
}
+ compat_init ();
+
top_level_arg_index = arg_index;
old_errexit_flag = exit_immediately_on_error;
static void
uw_unbind_variable (void *name)
{
- unbind_variable (name);
+ unbind_variable_noref (name);
}
static void
+bash: -c: line 1: unexpected EOF while looking for matching `)'
AAA
bash5: line 1: `invalid-name': not a valid identifier
in
case x in x) if ((true ) ); then :; fi ;; esac
case x in x) if ((true ) ); then :; fi esac
+# problem with bash-5.2
+${THIS_SH} -c '((X=([))]' bash
+
# this has to be in a separate file to get desired EOF behavior
${THIS_SH} ./parser1.sub