commit
d997708b2c
@ -0,0 +1,2 @@
|
|||||||
|
a799460be16c01aeab492b9aa88f5eb7f35c1b9b SOURCES/bash-5.2.tar.gz
|
||||||
|
993ce9aa151dd3b3cb7b2f8eb6ff05f548cbba7f SOURCES/bash-5.2.tar.gz.sig
|
@ -0,0 +1,2 @@
|
|||||||
|
SOURCES/bash-5.2.tar.gz
|
||||||
|
SOURCES/bash-5.2.tar.gz.sig
|
@ -0,0 +1,12 @@
|
|||||||
|
diff -up bash-3.2/config-top.h.profile bash-3.2/config-top.h
|
||||||
|
--- bash-3.2/config-top.h.profile 2008-07-17 13:35:39.000000000 +0200
|
||||||
|
+++ bash-3.2/config-top.h 2008-07-17 13:42:18.000000000 +0200
|
||||||
|
@@ -26,6 +26,8 @@
|
||||||
|
what POSIX.2 specifies. */
|
||||||
|
#define CONTINUE_AFTER_KILL_ERROR
|
||||||
|
|
||||||
|
+#define NON_INTERACTIVE_LOGIN_SHELLS
|
||||||
|
+
|
||||||
|
/* Define BREAK_COMPLAINS if you want the non-standard, but useful
|
||||||
|
error messages about `break' and `continue' out of context. */
|
||||||
|
#define BREAK_COMPLAINS
|
@ -0,0 +1,215 @@
|
|||||||
|
diff --git a/config.h.in b/config.h.in
|
||||||
|
index ab316d4..11d1d68 100644
|
||||||
|
--- a/config.h.in
|
||||||
|
+++ b/config.h.in
|
||||||
|
@@ -775,6 +775,9 @@
|
||||||
|
/* Define if you have the pselect function. */
|
||||||
|
#undef HAVE_PSELECT
|
||||||
|
|
||||||
|
+/* Define if you have the pread function. */
|
||||||
|
+#undef HAVE_PREAD
|
||||||
|
+
|
||||||
|
/* Define if you have the putenv function. */
|
||||||
|
#undef HAVE_PUTENV
|
||||||
|
|
||||||
|
@@ -981,6 +984,9 @@
|
||||||
|
/* Define if you have the <dlfcn.h> header file. */
|
||||||
|
#undef HAVE_DLFCN_H
|
||||||
|
|
||||||
|
+/* Define if you have the <elf.h> header file. */
|
||||||
|
+#undef HAVE_ELF_H
|
||||||
|
+
|
||||||
|
/* Define if you have the <grp.h> header file. */
|
||||||
|
#undef HAVE_GRP_H
|
||||||
|
|
||||||
|
diff --git a/configure.ac b/configure.ac
|
||||||
|
index 2fe3e7d..f1b7f1b 100644
|
||||||
|
--- a/configure.ac
|
||||||
|
+++ b/configure.ac
|
||||||
|
@@ -827,7 +827,7 @@ dnl checks for system calls
|
||||||
|
AC_CHECK_FUNCS(dup2 eaccess fcntl getdtablesize getentropy getgroups \
|
||||||
|
gethostname getpagesize getpeername getrandom getrlimit \
|
||||||
|
getrusage gettimeofday kill killpg lstat pselect readlink \
|
||||||
|
- select setdtablesize setitimer tcgetpgrp uname ulimit waitpid)
|
||||||
|
+ select setdtablesize setitimer tcgetpgrp uname ulimit waitpid pread)
|
||||||
|
AC_REPLACE_FUNCS(rename)
|
||||||
|
|
||||||
|
dnl checks for c library functions
|
||||||
|
diff --git a/execute_cmd.c b/execute_cmd.c
|
||||||
|
index d2a0dd7..d2555ad 100644
|
||||||
|
--- a/execute_cmd.c
|
||||||
|
+++ b/execute_cmd.c
|
||||||
|
@@ -41,6 +41,10 @@
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#ifdef HAVE_ELF_H
|
||||||
|
+# include <elf.h>
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#include "posixtime.h"
|
||||||
|
|
||||||
|
#if defined (HAVE_SYS_RESOURCE_H) && !defined (RLIMTYPE)
|
||||||
|
@@ -5832,6 +5836,14 @@ shell_execve (command, args, env)
|
||||||
|
{
|
||||||
|
/* The file has the execute bits set, but the kernel refuses to
|
||||||
|
run it for some reason. See why. */
|
||||||
|
+#if defined (HAVE_HASH_BANG_EXEC) || defined (HAVE_ELF_H)
|
||||||
|
+ int fd = open (command, O_RDONLY);
|
||||||
|
+
|
||||||
|
+ if (fd >= 0)
|
||||||
|
+ sample_len = read (fd, sample, sizeof (sample));
|
||||||
|
+ else
|
||||||
|
+ sample_len = -1;
|
||||||
|
+#endif
|
||||||
|
#if defined (HAVE_HASH_BANG_EXEC)
|
||||||
|
READ_SAMPLE_BUF (command, sample, sample_len);
|
||||||
|
if (sample_len > 0)
|
||||||
|
@@ -5841,6 +5853,7 @@ shell_execve (command, args, env)
|
||||||
|
char *interp;
|
||||||
|
int ilen;
|
||||||
|
|
||||||
|
+ close (fd);
|
||||||
|
interp = getinterp (sample, sample_len, (int *)NULL);
|
||||||
|
ilen = strlen (interp);
|
||||||
|
errno = i;
|
||||||
|
@@ -5856,7 +5869,138 @@ shell_execve (command, args, env)
|
||||||
|
return (EX_NOEXEC);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
- errno = i;
|
||||||
|
+#if defined (HAVE_ELF_H)
|
||||||
|
+ if (i == ENOENT
|
||||||
|
+ && sample_len > EI_NIDENT
|
||||||
|
+ && memcmp (sample, ELFMAG, SELFMAG) == 0)
|
||||||
|
+ {
|
||||||
|
+ off_t offset = -1;
|
||||||
|
+
|
||||||
|
+ /* It is an ELF file. Now determine whether it is dynamically
|
||||||
|
+ linked and if yes, get the offset of the interpreter
|
||||||
|
+ string. */
|
||||||
|
+ if (sample[EI_CLASS] == ELFCLASS32
|
||||||
|
+ && sample_len > sizeof (Elf32_Ehdr))
|
||||||
|
+ {
|
||||||
|
+ Elf32_Ehdr ehdr;
|
||||||
|
+ Elf32_Phdr *phdr;
|
||||||
|
+ int nphdr;
|
||||||
|
+
|
||||||
|
+ /* We have to copy the data since the sample buffer
|
||||||
|
+ might not be aligned correctly to be accessed as
|
||||||
|
+ an Elf32_Ehdr struct. */
|
||||||
|
+ memcpy (&ehdr, sample, sizeof (Elf32_Ehdr));
|
||||||
|
+
|
||||||
|
+ nphdr = ehdr.e_phnum;
|
||||||
|
+ phdr = (Elf32_Phdr *) malloc (nphdr * ehdr.e_phentsize);
|
||||||
|
+ if (phdr != NULL)
|
||||||
|
+ {
|
||||||
|
+#ifdef HAVE_PREAD
|
||||||
|
+ sample_len = pread (fd, phdr, nphdr * ehdr.e_phentsize,
|
||||||
|
+ ehdr.e_phoff);
|
||||||
|
+#else
|
||||||
|
+ if (lseek (fd, ehdr.e_phoff, SEEK_SET) != -1)
|
||||||
|
+ sample_len = read (fd, phdr,
|
||||||
|
+ nphdr * ehdr.e_phentsize);
|
||||||
|
+ else
|
||||||
|
+ sample_len = -1;
|
||||||
|
+#endif
|
||||||
|
+ if (sample_len == nphdr * ehdr.e_phentsize)
|
||||||
|
+ while (nphdr-- > 0)
|
||||||
|
+ if (phdr[nphdr].p_type == PT_INTERP)
|
||||||
|
+ {
|
||||||
|
+ offset = phdr[nphdr].p_offset;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ free (phdr);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ else if (sample[EI_CLASS] == ELFCLASS64
|
||||||
|
+ && sample_len > sizeof (Elf64_Ehdr))
|
||||||
|
+ {
|
||||||
|
+ Elf64_Ehdr ehdr;
|
||||||
|
+ Elf64_Phdr *phdr;
|
||||||
|
+ int nphdr;
|
||||||
|
+
|
||||||
|
+ /* We have to copy the data since the sample buffer
|
||||||
|
+ might not be aligned correctly to be accessed as
|
||||||
|
+ an Elf64_Ehdr struct. */
|
||||||
|
+ memcpy (&ehdr, sample, sizeof (Elf64_Ehdr));
|
||||||
|
+
|
||||||
|
+ nphdr = ehdr.e_phnum;
|
||||||
|
+ phdr = (Elf64_Phdr *) malloc (nphdr * ehdr.e_phentsize);
|
||||||
|
+ if (phdr != NULL)
|
||||||
|
+ {
|
||||||
|
+#ifdef HAVE_PREAD
|
||||||
|
+ sample_len = pread (fd, phdr, nphdr * ehdr.e_phentsize,
|
||||||
|
+ ehdr.e_phoff);
|
||||||
|
+#else
|
||||||
|
+ if (lseek (fd, ehdr.e_phoff, SEEK_SET) != -1)
|
||||||
|
+ sample_len = read (fd, phdr,
|
||||||
|
+ nphdr * ehdr.e_phentsize);
|
||||||
|
+ else
|
||||||
|
+ sample_len = -1;
|
||||||
|
+#endif
|
||||||
|
+ if (sample_len == nphdr * ehdr.e_phentsize)
|
||||||
|
+ while (nphdr-- > 0)
|
||||||
|
+ if (phdr[nphdr].p_type == PT_INTERP)
|
||||||
|
+ {
|
||||||
|
+ offset = phdr[nphdr].p_offset;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ free (phdr);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (offset != -1)
|
||||||
|
+ {
|
||||||
|
+ size_t maxlen = 0;
|
||||||
|
+ size_t actlen = 0;
|
||||||
|
+ char *interp = NULL;
|
||||||
|
+
|
||||||
|
+ do
|
||||||
|
+ {
|
||||||
|
+ if (actlen == maxlen)
|
||||||
|
+ {
|
||||||
|
+ char *newinterp = realloc (interp, maxlen += 200);
|
||||||
|
+ if (newinterp == NULL)
|
||||||
|
+ {
|
||||||
|
+ actlen = 0;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ interp = newinterp;
|
||||||
|
+
|
||||||
|
+#ifdef HAVE_PREAD
|
||||||
|
+ actlen = pread (fd, interp, maxlen, offset);
|
||||||
|
+#else
|
||||||
|
+ if (lseek (fd, offset, SEEK_SET) != -1)
|
||||||
|
+ actlen = read (fd, interp, maxlen);
|
||||||
|
+ else
|
||||||
|
+ actlen = -1;
|
||||||
|
+#endif
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ while (actlen > 0 && memchr (interp, '\0', actlen) == NULL);
|
||||||
|
+
|
||||||
|
+ if (actlen > 0)
|
||||||
|
+ {
|
||||||
|
+ close (fd);
|
||||||
|
+ errno = i;
|
||||||
|
+ sys_error ("%s: %s: bad ELF interpreter", command,
|
||||||
|
+ interp);
|
||||||
|
+ free (interp);
|
||||||
|
+ return (EX_NOEXEC);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ free (interp);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+#if defined (HAVE_HASH_BANG_EXEC) || defined (HAVE_ELF_H)
|
||||||
|
+ close (fd);
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ errno = i;
|
||||||
|
file_error (command);
|
||||||
|
}
|
||||||
|
return (last_command_exit_value);
|
@ -0,0 +1,10 @@
|
|||||||
|
--- bash-2.05b/builtins/Makefile.in.debuginfo 2003-03-25 17:25:21.000000000 +0000
|
||||||
|
+++ bash-2.05b/builtins/Makefile.in 2003-03-25 17:25:49.000000000 +0000
|
||||||
|
@@ -93,7 +93,6 @@
|
||||||
|
$(RM) $@
|
||||||
|
./$(MKBUILTINS) $(DIRECTDEFINE) $<
|
||||||
|
$(CC) -c $(CCFLAGS) $*.c || ( $(RM) $*.c ; exit 1 )
|
||||||
|
- $(RM) $*.c
|
||||||
|
|
||||||
|
# How to make a .c file from a .def file.
|
||||||
|
.def.c:
|
@ -0,0 +1,12 @@
|
|||||||
|
diff --git a/aclocal.m4 b/aclocal.m4
|
||||||
|
--- a/aclocal.m4
|
||||||
|
+++ b/aclocal.m4
|
||||||
|
@@ -1324,7 +1324,7 @@ main()
|
||||||
|
wait(&status);
|
||||||
|
exit(ok ? 0 : 5);
|
||||||
|
}
|
||||||
|
-]])], [bash_cv_pgrp_pipe=no], [bash_cv_pgrp_pipe=yes],
|
||||||
|
+]])], [bash_cv_pgrp_pipe=yes], [bash_cv_pgrp_pipe=yes],
|
||||||
|
[AC_MSG_WARN(cannot check pgrp synchronization if cross compiling -- defaulting to no)
|
||||||
|
bash_cv_pgrp_pipe=no]
|
||||||
|
)])
|
@ -0,0 +1,13 @@
|
|||||||
|
diff --git a/config-top.h b/config-top.h
|
||||||
|
index e5cc147..f5e0a52 100644
|
||||||
|
--- a/config-top.h
|
||||||
|
+++ b/config-top.h
|
||||||
|
@@ -106,7 +106,7 @@
|
||||||
|
sshd and source the .bashrc if so (like the rshd behavior). This checks
|
||||||
|
for the presence of SSH_CLIENT or SSH2_CLIENT in the initial environment,
|
||||||
|
which can be fooled under certain not-uncommon circumstances. */
|
||||||
|
-/* #define SSH_SOURCE_BASHRC */
|
||||||
|
+#define SSH_SOURCE_BASHRC
|
||||||
|
|
||||||
|
/* Define if you want the case-toggling operators (~[~]) and the
|
||||||
|
`capcase' variable attribute (declare -c). */
|
@ -0,0 +1,154 @@
|
|||||||
|
diff -up bash-4.0/execute_cmd.c.nobits bash-4.0/execute_cmd.c
|
||||||
|
--- bash-4.0/execute_cmd.c.nobits 2009-08-11 11:53:38.000000000 +0200
|
||||||
|
+++ bash-4.0/execute_cmd.c 2009-08-14 16:18:18.000000000 +0200
|
||||||
|
@@ -4747,6 +4747,7 @@ shell_execve (command, args, env)
|
||||||
|
&& memcmp (sample, ELFMAG, SELFMAG) == 0)
|
||||||
|
{
|
||||||
|
off_t offset = -1;
|
||||||
|
+ int dynamic_nobits = 0;
|
||||||
|
|
||||||
|
/* It is an ELF file. Now determine whether it is dynamically
|
||||||
|
linked and if yes, get the offset of the interpreter
|
||||||
|
@@ -4756,13 +4757,61 @@ shell_execve (command, args, env)
|
||||||
|
{
|
||||||
|
Elf32_Ehdr ehdr;
|
||||||
|
Elf32_Phdr *phdr;
|
||||||
|
- int nphdr;
|
||||||
|
+ Elf32_Shdr *shdr;
|
||||||
|
+ int nphdr, nshdr;
|
||||||
|
|
||||||
|
/* We have to copy the data since the sample buffer
|
||||||
|
might not be aligned correctly to be accessed as
|
||||||
|
an Elf32_Ehdr struct. */
|
||||||
|
memcpy (&ehdr, sample, sizeof (Elf32_Ehdr));
|
||||||
|
|
||||||
|
+ nshdr = ehdr.e_shnum;
|
||||||
|
+ shdr = (Elf32_Shdr *) malloc (nshdr * ehdr.e_shentsize);
|
||||||
|
+
|
||||||
|
+ if (shdr != NULL)
|
||||||
|
+ {
|
||||||
|
+#ifdef HAVE_PREAD
|
||||||
|
+ sample_len = pread (fd, shdr, nshdr * ehdr.e_shentsize,
|
||||||
|
+ ehdr.e_shoff);
|
||||||
|
+#else
|
||||||
|
+ if (lseek (fd, ehdr.e_shoff, SEEK_SET) != -1)
|
||||||
|
+ sample_len = read (fd, shdr,
|
||||||
|
+ nshdr * ehdr.e_shentsize);
|
||||||
|
+ else
|
||||||
|
+ sample_len = -1;
|
||||||
|
+#endif
|
||||||
|
+ if (sample_len == nshdr * ehdr.e_shentsize)
|
||||||
|
+ {
|
||||||
|
+ char *strings = (char *) malloc (shdr[ehdr.e_shstrndx].sh_size);
|
||||||
|
+ if (strings != NULL)
|
||||||
|
+ {
|
||||||
|
+#ifdef HAVE_PREAD
|
||||||
|
+ sample_len = pread (fd, strings,
|
||||||
|
+ shdr[ehdr.e_shstrndx].sh_size,
|
||||||
|
+ shdr[ehdr.e_shstrndx].sh_offset);
|
||||||
|
+#else
|
||||||
|
+ if (lseek (fd, shdr[ehdr.e_shstrndx].sh_offset,
|
||||||
|
+ SEEK_SET) != -1)
|
||||||
|
+ sample_len = read (fd, strings,
|
||||||
|
+ shdr[ehdr.e_shstrndx].sh_size);
|
||||||
|
+ else
|
||||||
|
+ sample_len = -1;
|
||||||
|
+#endif
|
||||||
|
+ if (sample_len == shdr[ehdr.e_shstrndx].sh_size)
|
||||||
|
+ while (nshdr-- > 0)
|
||||||
|
+ if (strcmp (strings + shdr[nshdr].sh_name,
|
||||||
|
+ ".interp") == 0 &&
|
||||||
|
+ shdr[nshdr].sh_type == SHT_NOBITS)
|
||||||
|
+ {
|
||||||
|
+ dynamic_nobits++;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ free (strings);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ free (shdr);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
nphdr = ehdr.e_phnum;
|
||||||
|
phdr = (Elf32_Phdr *) malloc (nphdr * ehdr.e_phentsize);
|
||||||
|
if (phdr != NULL)
|
||||||
|
@@ -4792,13 +4841,60 @@ shell_execve (command, args, env)
|
||||||
|
{
|
||||||
|
Elf64_Ehdr ehdr;
|
||||||
|
Elf64_Phdr *phdr;
|
||||||
|
- int nphdr;
|
||||||
|
+ Elf64_Shdr *shdr;
|
||||||
|
+ int nphdr, nshdr;
|
||||||
|
|
||||||
|
/* We have to copy the data since the sample buffer
|
||||||
|
might not be aligned correctly to be accessed as
|
||||||
|
an Elf64_Ehdr struct. */
|
||||||
|
memcpy (&ehdr, sample, sizeof (Elf64_Ehdr));
|
||||||
|
|
||||||
|
+ nshdr = ehdr.e_shnum;
|
||||||
|
+ shdr = (Elf64_Shdr *) malloc (nshdr * ehdr.e_shentsize);
|
||||||
|
+ if (shdr != NULL)
|
||||||
|
+ {
|
||||||
|
+#ifdef HAVE_PREAD
|
||||||
|
+ sample_len = pread (fd, shdr, nshdr * ehdr.e_shentsize,
|
||||||
|
+ ehdr.e_shoff);
|
||||||
|
+#else
|
||||||
|
+ if (lseek (fd, ehdr.e_shoff, SEEK_SET) != -1)
|
||||||
|
+ sample_len = read (fd, shdr,
|
||||||
|
+ nshdr * ehdr.e_shentsize);
|
||||||
|
+ else
|
||||||
|
+ sample_len = -1;
|
||||||
|
+#endif
|
||||||
|
+ if (sample_len == nshdr * ehdr.e_shentsize)
|
||||||
|
+ {
|
||||||
|
+ char *strings = (char *) malloc (shdr[ehdr.e_shstrndx].sh_size);
|
||||||
|
+ if (strings != NULL)
|
||||||
|
+ {
|
||||||
|
+#ifdef HAVE_PREAD
|
||||||
|
+ sample_len = pread (fd, strings,
|
||||||
|
+ shdr[ehdr.e_shstrndx].sh_size,
|
||||||
|
+ shdr[ehdr.e_shstrndx].sh_offset);
|
||||||
|
+#else
|
||||||
|
+ if (lseek (fd, shdr[ehdr.e_shstrndx].sh_offset,
|
||||||
|
+ SEEK_SET) != -1)
|
||||||
|
+ sample_len = read (fd, strings,
|
||||||
|
+ shdr[ehdr.e_shstrndx].sh_size);
|
||||||
|
+ else
|
||||||
|
+ sample_len = -1;
|
||||||
|
+#endif
|
||||||
|
+ if (sample_len == shdr[ehdr.e_shstrndx].sh_size)
|
||||||
|
+ while (nshdr-- > 0)
|
||||||
|
+ if (strcmp (strings + shdr[nshdr].sh_name,
|
||||||
|
+ ".interp") == 0 &&
|
||||||
|
+ shdr[nshdr].sh_type == SHT_NOBITS)
|
||||||
|
+ {
|
||||||
|
+ dynamic_nobits++;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ free (strings);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ free (shdr);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
nphdr = ehdr.e_phnum;
|
||||||
|
phdr = (Elf64_Phdr *) malloc (nphdr * ehdr.e_phentsize);
|
||||||
|
if (phdr != NULL)
|
||||||
|
@@ -4858,8 +4954,15 @@ shell_execve (command, args, env)
|
||||||
|
{
|
||||||
|
close (fd);
|
||||||
|
errno = i;
|
||||||
|
- sys_error ("%s: %s: bad ELF interpreter", command,
|
||||||
|
- interp);
|
||||||
|
+ if (dynamic_nobits > 0)
|
||||||
|
+ {
|
||||||
|
+ sys_error ("%s: bad ELF interpreter", command);
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ sys_error ("%s: %s: bad ELF interpreter", command,
|
||||||
|
+ interp);
|
||||||
|
+ }
|
||||||
|
free (interp);
|
||||||
|
return (EX_NOEXEC);
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
diff -up bash-4.1/config-top.h.broken_pipe bash-4.1/config-top.h
|
||||||
|
--- bash-4.1/config-top.h.broken_pipe 2011-01-06 18:01:30.000000000 +0100
|
||||||
|
+++ bash-4.1/config-top.h 2011-01-06 18:02:14.000000000 +0100
|
||||||
|
@@ -51,7 +51,7 @@
|
||||||
|
/* Define DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS if you don't want builtins
|
||||||
|
like `echo' and `printf' to report errors when output does not succeed
|
||||||
|
due to EPIPE. */
|
||||||
|
-/* #define DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS */
|
||||||
|
+#define DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS
|
||||||
|
|
||||||
|
/* The default value of the PATH variable. */
|
||||||
|
#ifndef DEFAULT_PATH_VALUE
|
@ -0,0 +1,24 @@
|
|||||||
|
diff --git a/examples/loadables/Makefile.in b/examples/loadables/Makefile.in
|
||||||
|
--- a/examples/loadables/Makefile.in
|
||||||
|
+++ b/examples/loadables/Makefile.in
|
||||||
|
@@ -59,7 +59,7 @@ host_cpu = @host_cpu@
|
||||||
|
host_vendor = @host_vendor@
|
||||||
|
|
||||||
|
STYLE_CFLAGS = @STYLE_CFLAGS@
|
||||||
|
-CFLAGS = @CFLAGS@
|
||||||
|
++CFLAGS = -O2 -g
|
||||||
|
LOCAL_CFLAGS = @LOCAL_CFLAGS@
|
||||||
|
DEFS = @DEFS@
|
||||||
|
LOCAL_DEFS = @LOCAL_DEFS@
|
||||||
|
diff --git a/examples/loadables/perl/Makefile.in b/examples/loadables/perl/Makefile.in
|
||||||
|
--- a/examples/loadables/perl/Makefile.in
|
||||||
|
+++ b/examples/loadables/perl/Makefile.in
|
||||||
|
@@ -42,7 +42,7 @@ SHELL = @MAKE_SHELL@
|
||||||
|
|
||||||
|
PERL5 = perl5
|
||||||
|
|
||||||
|
-CFLAGS = @CFLAGS@
|
||||||
|
+CFLAGS = -O2 -g
|
||||||
|
|
||||||
|
#
|
||||||
|
# These values are generated for configure by ${topdir}/support/shobj-conf.
|
@ -0,0 +1,103 @@
|
|||||||
|
diff --git a/execute_cmd.c b/execute_cmd.c
|
||||||
|
index a988400..412128c 100644
|
||||||
|
--- a/execute_cmd.c
|
||||||
|
+++ b/execute_cmd.c
|
||||||
|
@@ -5760,7 +5760,7 @@ shell_execve (command, args, env)
|
||||||
|
Elf32_Ehdr ehdr;
|
||||||
|
Elf32_Phdr *phdr;
|
||||||
|
Elf32_Shdr *shdr;
|
||||||
|
- int nphdr, nshdr;
|
||||||
|
+ Elf32_Half nphdr, nshdr;
|
||||||
|
|
||||||
|
/* We have to copy the data since the sample buffer
|
||||||
|
might not be aligned correctly to be accessed as
|
||||||
|
@@ -5768,12 +5768,12 @@ shell_execve (command, args, env)
|
||||||
|
memcpy (&ehdr, sample, sizeof (Elf32_Ehdr));
|
||||||
|
|
||||||
|
nshdr = ehdr.e_shnum;
|
||||||
|
- shdr = (Elf32_Shdr *) malloc (nshdr * ehdr.e_shentsize);
|
||||||
|
+ shdr = (Elf32_Shdr *) malloc ((size_t)nshdr * (size_t)ehdr.e_shentsize);
|
||||||
|
|
||||||
|
if (shdr != NULL)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_PREAD
|
||||||
|
- sample_len = pread (fd, shdr, nshdr * ehdr.e_shentsize,
|
||||||
|
+ sample_len = pread (fd, shdr, (size_t)nshdr * (size_t)ehdr.e_shentsize,
|
||||||
|
ehdr.e_shoff);
|
||||||
|
#else
|
||||||
|
if (lseek (fd, ehdr.e_shoff, SEEK_SET) != -1)
|
||||||
|
@@ -5815,11 +5815,11 @@ shell_execve (command, args, env)
|
||||||
|
}
|
||||||
|
|
||||||
|
nphdr = ehdr.e_phnum;
|
||||||
|
- phdr = (Elf32_Phdr *) malloc (nphdr * ehdr.e_phentsize);
|
||||||
|
+ phdr = (Elf32_Phdr *) malloc ((size_t)nphdr * (size_t)ehdr.e_phentsize);
|
||||||
|
if (phdr != NULL)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_PREAD
|
||||||
|
- sample_len = pread (fd, phdr, nphdr * ehdr.e_phentsize,
|
||||||
|
+ sample_len = pread (fd, phdr, (size_t)nphdr * (size_t)ehdr.e_phentsize,
|
||||||
|
ehdr.e_phoff);
|
||||||
|
#else
|
||||||
|
if (lseek (fd, ehdr.e_phoff, SEEK_SET) != -1)
|
||||||
|
@@ -5844,7 +5844,7 @@ shell_execve (command, args, env)
|
||||||
|
Elf64_Ehdr ehdr;
|
||||||
|
Elf64_Phdr *phdr;
|
||||||
|
Elf64_Shdr *shdr;
|
||||||
|
- int nphdr, nshdr;
|
||||||
|
+ Elf32_Half nphdr, nshdr;
|
||||||
|
|
||||||
|
/* We have to copy the data since the sample buffer
|
||||||
|
might not be aligned correctly to be accessed as
|
||||||
|
@@ -5852,11 +5852,11 @@ shell_execve (command, args, env)
|
||||||
|
memcpy (&ehdr, sample, sizeof (Elf64_Ehdr));
|
||||||
|
|
||||||
|
nshdr = ehdr.e_shnum;
|
||||||
|
- shdr = (Elf64_Shdr *) malloc (nshdr * ehdr.e_shentsize);
|
||||||
|
+ shdr = (Elf64_Shdr *) malloc ((size_t)nshdr * (size_t)ehdr.e_shentsize);
|
||||||
|
if (shdr != NULL)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_PREAD
|
||||||
|
- sample_len = pread (fd, shdr, nshdr * ehdr.e_shentsize,
|
||||||
|
+ sample_len = pread (fd, shdr, (size_t)nshdr * (size_t)ehdr.e_shentsize,
|
||||||
|
ehdr.e_shoff);
|
||||||
|
#else
|
||||||
|
if (lseek (fd, ehdr.e_shoff, SEEK_SET) != -1)
|
||||||
|
@@ -5898,11 +5898,11 @@ shell_execve (command, args, env)
|
||||||
|
}
|
||||||
|
|
||||||
|
nphdr = ehdr.e_phnum;
|
||||||
|
- phdr = (Elf64_Phdr *) malloc (nphdr * ehdr.e_phentsize);
|
||||||
|
+ phdr = (Elf64_Phdr *) malloc ((size_t)nphdr * (size_t)ehdr.e_phentsize);
|
||||||
|
if (phdr != NULL)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_PREAD
|
||||||
|
- sample_len = pread (fd, phdr, nphdr * ehdr.e_phentsize,
|
||||||
|
+ sample_len = pread (fd, phdr, (size_t)nphdr * (size_t)ehdr.e_phentsize,
|
||||||
|
ehdr.e_phoff);
|
||||||
|
#else
|
||||||
|
if (lseek (fd, ehdr.e_phoff, SEEK_SET) != -1)
|
||||||
|
@@ -5924,8 +5924,8 @@ shell_execve (command, args, env)
|
||||||
|
|
||||||
|
if (offset != -1)
|
||||||
|
{
|
||||||
|
- size_t maxlen = 0;
|
||||||
|
- size_t actlen = 0;
|
||||||
|
+ ssize_t maxlen = 0;
|
||||||
|
+ ssize_t actlen = 0;
|
||||||
|
char *interp = NULL;
|
||||||
|
|
||||||
|
do
|
||||||
|
@@ -5974,7 +5974,8 @@ shell_execve (command, args, env)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined (HAVE_HASH_BANG_EXEC) || defined (HAVE_ELF_H)
|
||||||
|
- close (fd);
|
||||||
|
+ if (fd >= 0)
|
||||||
|
+ close (fd);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
errno = i;
|
||||||
|
--
|
||||||
|
2.17.2
|
||||||
|
|
@ -0,0 +1,12 @@
|
|||||||
|
diff -up bash-4.1/doc/bash.1.manpage_trap bash-4.1/doc/bash.1
|
||||||
|
--- bash-4.1/doc/bash.1.manpage_trap 2012-08-28 10:06:00.561999092 +0200
|
||||||
|
+++ bash-4.1/doc/bash.1 2012-08-28 10:06:24.225304505 +0200
|
||||||
|
@@ -9251,7 +9251,7 @@ being inverted via
|
||||||
|
These are the same conditions obeyed by the \fBerrexit\fP (\fB\-e\fP) option.
|
||||||
|
.if t .sp 0.5
|
||||||
|
.if n .sp 1
|
||||||
|
-Signals ignored upon entry to the shell cannot be trapped or reset.
|
||||||
|
+Signals ignored upon entry to the shell cannot be trapped, reset or listed.
|
||||||
|
Trapped signals that are not being ignored are reset to their original
|
||||||
|
values in a subshell or subshell environment when one is created.
|
||||||
|
The return status is false if any
|
@ -0,0 +1,41 @@
|
|||||||
|
diff --git a/config-top.h b/config-top.h
|
||||||
|
index 026d4a4..cb0e002 100644
|
||||||
|
--- a/config-top.h
|
||||||
|
+++ b/config-top.h
|
||||||
|
@@ -92,7 +92,7 @@
|
||||||
|
/* #define SYS_BASHRC "/etc/bash.bashrc" */
|
||||||
|
|
||||||
|
/* System-wide .bash_logout for login shells. */
|
||||||
|
-/* #define SYS_BASH_LOGOUT "/etc/bash.bash_logout" */
|
||||||
|
+#define SYS_BASH_LOGOUT "/etc/bash.bash_logout"
|
||||||
|
|
||||||
|
/* Define this to make non-interactive shells begun with argv[0][0] == '-'
|
||||||
|
run the startup files when not in posix mode. */
|
||||||
|
diff --git a/doc/bash.1 b/doc/bash.1
|
||||||
|
index 04ce845..bfde55e 100644
|
||||||
|
--- a/doc/bash.1
|
||||||
|
+++ b/doc/bash.1
|
||||||
|
@@ -335,8 +335,8 @@ option may be used when the shell is started to inhibit this behavior.
|
||||||
|
When an interactive login shell exits,
|
||||||
|
or a non-interactive login shell executes the \fBexit\fP builtin command,
|
||||||
|
.B bash
|
||||||
|
-reads and executes commands from the file \fI~/.bash_logout\fP, if it
|
||||||
|
-exists.
|
||||||
|
+reads and executes commands from the files \fI~/.bash_logout\fP
|
||||||
|
+and \fI/etc/bash.bash_logout\fP, if the files exists.
|
||||||
|
.PP
|
||||||
|
When an interactive shell that is not a login shell is started,
|
||||||
|
.B bash
|
||||||
|
@@ -10558,6 +10558,9 @@ The \fBbash\fP executable
|
||||||
|
.FN /etc/profile
|
||||||
|
The systemwide initialization file, executed for login shells
|
||||||
|
.TP
|
||||||
|
+.FN /etc/bash.bash_logout
|
||||||
|
+The systemwide login shell cleanup file, executed when a login shell exits
|
||||||
|
+.TP
|
||||||
|
.FN ~/.bash_profile
|
||||||
|
The personal initialization file, executed for login shells
|
||||||
|
.TP
|
||||||
|
--
|
||||||
|
2.9.3
|
||||||
|
|
@ -0,0 +1,14 @@
|
|||||||
|
diff -up bash-4.2/variables.h.size_type bash-4.2/variables.h
|
||||||
|
--- bash-4.2/variables.h.size_type 2012-11-29 10:33:25.109036844 +0100
|
||||||
|
+++ bash-4.2/variables.h 2012-11-29 10:46:12.718530162 +0100
|
||||||
|
@@ -95,8 +95,8 @@ typedef struct variable {
|
||||||
|
|
||||||
|
typedef struct _vlist {
|
||||||
|
SHELL_VAR **list;
|
||||||
|
- int list_size; /* allocated size */
|
||||||
|
- int list_len; /* current number of entries */
|
||||||
|
+ size_t list_size; /* allocated size */
|
||||||
|
+ size_t list_len; /* current number of entries */
|
||||||
|
} VARLIST;
|
||||||
|
|
||||||
|
/* The various attributes that a given variable can have. */
|
@ -0,0 +1,12 @@
|
|||||||
|
diff --git a/lib/readline/rlconf.h b/lib/readline/rlconf.h
|
||||||
|
--- a/lib/readline/rlconf.h
|
||||||
|
+++ b/lib/readline/rlconf.h
|
||||||
|
@@ -64,7 +64,7 @@
|
||||||
|
|
||||||
|
/* Define this if you want to enable code that talks to the Linux kernel
|
||||||
|
tty auditing system. */
|
||||||
|
-/* #define ENABLE_TTY_AUDIT_SUPPORT */
|
||||||
|
+#define ENABLE_TTY_AUDIT_SUPPORT
|
||||||
|
|
||||||
|
/* Defaults for the various editing mode indicators, inserted at the beginning
|
||||||
|
of the last (maybe only) line of the prompt if show-mode-in-prompt is on */
|
@ -0,0 +1,15 @@
|
|||||||
|
diff --git a/doc/bash.1 b/doc/bash.1
|
||||||
|
index 6e8aebb..e846e68 100644
|
||||||
|
--- a/doc/bash.1
|
||||||
|
+++ b/doc/bash.1
|
||||||
|
@@ -10333,6 +10333,7 @@ and
|
||||||
|
which are in 512-byte increments.
|
||||||
|
The return status is 0 unless an invalid option or argument is supplied,
|
||||||
|
or an error occurs while setting a new limit.
|
||||||
|
+In POSIX Mode 512-byte blocks are used for the `-c' and `-f' options.
|
||||||
|
.RE
|
||||||
|
.TP
|
||||||
|
\fBumask\fP [\fB\-p\fP] [\fB\-S\fP] [\fImode\fP]
|
||||||
|
--
|
||||||
|
2.9.3
|
||||||
|
|
@ -0,0 +1,13 @@
|
|||||||
|
diff --git a/locale.c b/locale.c
|
||||||
|
index 17ccc58..a6c07a3 100644
|
||||||
|
--- a/locale.c
|
||||||
|
+++ b/locale.c
|
||||||
|
@@ -78,8 +78,6 @@ set_default_locale ()
|
||||||
|
{
|
||||||
|
#if defined (HAVE_SETLOCALE)
|
||||||
|
default_locale = setlocale (LC_ALL, "");
|
||||||
|
- if (default_locale)
|
||||||
|
- default_locale = savestring (default_locale);
|
||||||
|
#else
|
||||||
|
default_locale = savestring ("C");
|
||||||
|
#endif /* HAVE_SETLOCALE */
|
@ -0,0 +1,42 @@
|
|||||||
|
diff --git a/parse.y b/parse.y
|
||||||
|
--- a/parse.y
|
||||||
|
+++ b/parse.y
|
||||||
|
@@ -4255,7 +4255,8 @@ xparse_dolparen (base, string, indp, flags)
|
||||||
|
|
||||||
|
save_parser_state (&ps);
|
||||||
|
save_input_line_state (&ls);
|
||||||
|
-
|
||||||
|
+ /* avoid echoing every substitution again */
|
||||||
|
+ echo_input_at_read = 0;
|
||||||
|
#if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
|
||||||
|
pushed_string_list = (STRING_SAVER *)NULL;
|
||||||
|
#endif
|
||||||
|
diff --git a/subst.c b/subst.c
|
||||||
|
--- a/subst.c
|
||||||
|
+++ b/subst.c
|
||||||
|
@@ -10222,6 +10222,7 @@ param_expand (string, sindex, quoted, expanded_something,
|
||||||
|
WORD_LIST *list, *l;
|
||||||
|
WORD_DESC *tdesc, *ret;
|
||||||
|
int tflag, nullarg;
|
||||||
|
+ int old_echo_input;
|
||||||
|
|
||||||
|
/*itrace("param_expand: `%s' pflags = %d", string+*sindex, pflags);*/
|
||||||
|
zindex = *sindex;
|
||||||
|
@@ -10614,6 +10615,9 @@ arithsub:
|
||||||
|
}
|
||||||
|
|
||||||
|
comsub:
|
||||||
|
+ old_echo_input = echo_input_at_read;
|
||||||
|
+ /* avoid echoing every substitution again */
|
||||||
|
+ echo_input_at_read = 0;
|
||||||
|
if (pflags & PF_NOCOMSUB)
|
||||||
|
/* we need zindex+1 because string[zindex] == RPAREN */
|
||||||
|
temp1 = substring (string, *sindex, zindex+1);
|
||||||
|
@@ -10626,6 +10630,7 @@ comsub:
|
||||||
|
}
|
||||||
|
FREE (temp);
|
||||||
|
temp = temp1;
|
||||||
|
+ echo_input_at_read = old_echo_input;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Do POSIX.2d9-style arithmetic substitution. This will probably go
|
@ -0,0 +1,15 @@
|
|||||||
|
diff --git a/Makefile.in b/Makefile.in
|
||||||
|
index a1f9483..24c646a 100644
|
||||||
|
--- a/Makefile.in
|
||||||
|
+++ b/Makefile.in
|
||||||
|
@@ -800,7 +800,6 @@ install: .made installdirs
|
||||||
|
infodir=$(infodir) htmldir=$(htmldir) DESTDIR=$(DESTDIR) $@ )
|
||||||
|
-( cd $(DEFDIR) ; $(MAKE) $(MFLAGS) DESTDIR=$(DESTDIR) $@ )
|
||||||
|
-( cd $(PO_DIR) ; $(MAKE) $(MFLAGS) DESTDIR=$(DESTDIR) $@ )
|
||||||
|
- -( cd $(LOADABLES_DIR) && $(MAKE) $(MFLAGS) DESTDIR=$(DESTDIR) $@ )
|
||||||
|
|
||||||
|
install-strip:
|
||||||
|
$(MAKE) $(MFLAGS) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' \
|
||||||
|
--
|
||||||
|
2.9.3
|
||||||
|
|
@ -0,0 +1,13 @@
|
|||||||
|
diff --git a/doc/bash.1 b/doc/bash.1
|
||||||
|
--- a/doc/bash.1
|
||||||
|
+++ b/doc/bash.1
|
||||||
|
@@ -10726,6 +10726,9 @@ If set, the shell automatically closes file descriptors assigned using the
|
||||||
|
.el above)
|
||||||
|
instead of leaving them open when the command completes.
|
||||||
|
.TP 8
|
||||||
|
+.B syslog_history
|
||||||
|
+If set, command history is logged to syslog.
|
||||||
|
+.TP 8
|
||||||
|
.B xpg_echo
|
||||||
|
If set, the \fBecho\fP builtin expands backslash-escape sequences
|
||||||
|
by default.
|
@ -0,0 +1,24 @@
|
|||||||
|
diff --git a/patchlevel.h b/patchlevel.h
|
||||||
|
--- a/patchlevel.h
|
||||||
|
+++ b/patchlevel.h
|
||||||
|
@@ -25,6 +25,6 @@
|
||||||
|
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
|
||||||
|
looks for to find the patch level (for the sccs version string). */
|
||||||
|
|
||||||
|
-#define PATCHLEVEL 0
|
||||||
|
+#define PATCHLEVEL 1
|
||||||
|
|
||||||
|
#endif /* _PATCHLEVEL_H_ */
|
||||||
|
diff --git a/subst.c b/subst.c
|
||||||
|
index d9feabca..93b91606 100644
|
||||||
|
--- a/subst.c
|
||||||
|
+++ b/subst.c
|
||||||
|
@@ -10857,7 +10857,7 @@ expand_array_subscript (string, sindex, quoted, flags)
|
||||||
|
exp = substring (string, si+1, ni);
|
||||||
|
t = expand_subscript_string (exp, quoted & ~(Q_ARITH|Q_DOUBLE_QUOTES));
|
||||||
|
free (exp);
|
||||||
|
- exp = sh_backslash_quote (t, abstab, 0);
|
||||||
|
+ exp = t ? sh_backslash_quote (t, abstab, 0) : savestring ("");
|
||||||
|
free (t);
|
||||||
|
|
||||||
|
slen = STRLEN (exp);
|
@ -0,0 +1,41 @@
|
|||||||
|
diff --git a/general.c b/general.c
|
||||||
|
--- a/general.c
|
||||||
|
+++ b/general.c
|
||||||
|
@@ -683,21 +683,20 @@ check_binary_file (sample, sample_len)
|
||||||
|
int sample_len;
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
+ int nline;
|
||||||
|
unsigned char c;
|
||||||
|
|
||||||
|
if (sample_len >= 4 && sample[0] == 0x7f && sample[1] == 'E' && sample[2] == 'L' && sample[3] == 'F')
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* Generally we check the first line for NULs. If the first line looks like
|
||||||
|
- a `#!' interpreter specifier, we just look for NULs anywhere in the
|
||||||
|
- buffer. */
|
||||||
|
- if (sample[0] == '#' && sample[1] == '!')
|
||||||
|
- return (memchr (sample, '\0', sample_len) != NULL);
|
||||||
|
+ a `#!' interpreter specifier, we look for NULs in the first two lines. */
|
||||||
|
+ nline = (sample[0] == '#' && sample[1] == '!') ? 2 : 1;
|
||||||
|
|
||||||
|
for (i = 0; i < sample_len; i++)
|
||||||
|
{
|
||||||
|
c = sample[i];
|
||||||
|
- if (c == '\n')
|
||||||
|
+ if (c == '\n' && --nline == 0)
|
||||||
|
return (0);
|
||||||
|
if (c == '\0')
|
||||||
|
return (1);
|
||||||
|
diff --git a/patchlevel.h b/patchlevel.h
|
||||||
|
index e59027ac..9ddc79f7 100644
|
||||||
|
--- a/patchlevel.h
|
||||||
|
+++ b/patchlevel.h
|
||||||
|
@@ -25,6 +25,6 @@
|
||||||
|
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
|
||||||
|
looks for to find the patch level (for the sccs version string). */
|
||||||
|
|
||||||
|
-#define PATCHLEVEL 9
|
||||||
|
+#define PATCHLEVEL 10
|
||||||
|
|
||||||
|
#endif /* _PATCHLEVEL_H_ */
|
@ -0,0 +1,25 @@
|
|||||||
|
diff --git a/builtins/read.def b/builtins/read.def
|
||||||
|
--- a/builtins/read.def
|
||||||
|
+++ b/builtins/read.def
|
||||||
|
@@ -167,6 +167,9 @@ reset_timeout ()
|
||||||
|
/* Cancel alarm before restoring signal handler. */
|
||||||
|
if (read_timeout)
|
||||||
|
shtimer_clear (read_timeout);
|
||||||
|
+#if defined (READLINE)
|
||||||
|
+ rl_clear_timeout ();
|
||||||
|
+#endif
|
||||||
|
read_timeout = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/patchlevel.h b/patchlevel.h
|
||||||
|
index 9ddc79f7..9ff902a0 100644
|
||||||
|
--- a/patchlevel.h
|
||||||
|
+++ b/patchlevel.h
|
||||||
|
@@ -25,6 +25,6 @@
|
||||||
|
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
|
||||||
|
looks for to find the patch level (for the sccs version string). */
|
||||||
|
|
||||||
|
-#define PATCHLEVEL 10
|
||||||
|
+#define PATCHLEVEL 11
|
||||||
|
|
||||||
|
#endif /* _PATCHLEVEL_H_ */
|
@ -0,0 +1,268 @@
|
|||||||
|
diff --git a/builtins/common.h b/builtins/common.h
|
||||||
|
--- a/builtins/common.h
|
||||||
|
+++ b/builtins/common.h
|
||||||
|
@@ -257,6 +257,10 @@ extern int print_shift_error;
|
||||||
|
extern int expand_once_flag;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#if defined (EXTENDED_GLOB)
|
||||||
|
+extern int extglob_flag;
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
extern int expaliases_flag;
|
||||||
|
|
||||||
|
/* variables from source.def */
|
||||||
|
diff --git a/builtins/shopt.def b/builtins/shopt.def
|
||||||
|
--- a/builtins/shopt.def
|
||||||
|
+++ b/builtins/shopt.def
|
||||||
|
@@ -149,6 +149,11 @@ static int shopt_set_complete_direxpand PARAMS((char *, int));
|
||||||
|
static int set_assoc_expand PARAMS((char *, int));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#if defined (EXTENDED_GLOB)
|
||||||
|
+int extglob_flag = EXTGLOB_DEFAULT;
|
||||||
|
+static int shopt_set_extglob PARAMS((char *, int));
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
int expaliases_flag = 0;
|
||||||
|
static int shopt_set_expaliases PARAMS((char *, int));
|
||||||
|
|
||||||
|
@@ -206,7 +211,7 @@ static struct {
|
||||||
|
{ "extdebug", &debugging_mode, shopt_set_debug_mode },
|
||||||
|
#endif
|
||||||
|
#if defined (EXTENDED_GLOB)
|
||||||
|
- { "extglob", &extended_glob, (shopt_set_func_t *)NULL },
|
||||||
|
+ { "extglob", &extglob_flag, shopt_set_extglob },
|
||||||
|
#endif
|
||||||
|
{ "extquote", &extended_quote, (shopt_set_func_t *)NULL },
|
||||||
|
{ "failglob", &fail_glob_expansion, (shopt_set_func_t *)NULL },
|
||||||
|
@@ -377,7 +382,7 @@ reset_shopt_options ()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (EXTENDED_GLOB)
|
||||||
|
- extended_glob = EXTGLOB_DEFAULT;
|
||||||
|
+ extended_glob = extglob_flag = EXTGLOB_DEFAULT;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (ARRAY_VARS)
|
||||||
|
@@ -643,6 +648,17 @@ shopt_set_expaliases (option_name, mode)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#if defined (EXTENDED_GLOB)
|
||||||
|
+static int
|
||||||
|
+shopt_set_extglob (option_name, mode)
|
||||||
|
+ char *option_name;
|
||||||
|
+ int mode;
|
||||||
|
+{
|
||||||
|
+ extended_glob = extglob_flag;
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#if defined (READLINE)
|
||||||
|
static int
|
||||||
|
shopt_enable_hostname_completion (option_name, mode)
|
||||||
|
diff --git a/execute_cmd.c b/execute_cmd.c
|
||||||
|
--- a/execute_cmd.c
|
||||||
|
+++ b/execute_cmd.c
|
||||||
|
@@ -3990,13 +3990,11 @@ execute_cond_node (cond)
|
||||||
|
else
|
||||||
|
#endif /* COND_REGEXP */
|
||||||
|
{
|
||||||
|
- int oe;
|
||||||
|
- oe = extended_glob;
|
||||||
|
extended_glob = 1;
|
||||||
|
result = binary_test (cond->op->word, arg1, arg2, TEST_PATMATCH|TEST_ARITHEXP|TEST_LOCALE)
|
||||||
|
? EXECUTION_SUCCESS
|
||||||
|
: EXECUTION_FAILURE;
|
||||||
|
- extended_glob = oe;
|
||||||
|
+ extended_glob = extglob_flag;
|
||||||
|
}
|
||||||
|
if (arg1 != nullstr)
|
||||||
|
free (arg1);
|
||||||
|
diff --git a/parse.y b/parse.y
|
||||||
|
--- a/parse.y
|
||||||
|
+++ b/parse.y
|
||||||
|
@@ -125,7 +125,7 @@ do { \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#if defined (EXTENDED_GLOB)
|
||||||
|
-extern int extended_glob;
|
||||||
|
+extern int extended_glob, extglob_flag;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (TRANSLATABLE_STRINGS)
|
||||||
|
@@ -3304,7 +3304,7 @@ reset_parser ()
|
||||||
|
#if defined (EXTENDED_GLOB)
|
||||||
|
/* Reset to global value of extended glob */
|
||||||
|
if (parser_state & (PST_EXTPAT|PST_CMDSUBST))
|
||||||
|
- extended_glob = global_extglob;
|
||||||
|
+ extended_glob = extglob_flag;
|
||||||
|
#endif
|
||||||
|
if (parser_state & (PST_CMDSUBST|PST_STRING))
|
||||||
|
expand_aliases = expaliases_flag;
|
||||||
|
@@ -4124,10 +4124,10 @@ parse_comsub (qc, open, close, lenp, flags)
|
||||||
|
expand_aliases = posixly_correct != 0;
|
||||||
|
#if defined (EXTENDED_GLOB)
|
||||||
|
/* If (parser_state & PST_EXTPAT), we're parsing an extended pattern for a
|
||||||
|
- conditional command and have already set global_extglob appropriately. */
|
||||||
|
+ conditional command and have already set extended_glob appropriately. */
|
||||||
|
if (shell_compatibility_level <= 51 && was_extpat == 0)
|
||||||
|
{
|
||||||
|
- local_extglob = global_extglob = extended_glob;
|
||||||
|
+ local_extglob = extended_glob;
|
||||||
|
extended_glob = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
@@ -4235,7 +4235,7 @@ xparse_dolparen (base, string, indp, flags)
|
||||||
|
{
|
||||||
|
sh_parser_state_t ps;
|
||||||
|
sh_input_line_state_t ls;
|
||||||
|
- int orig_ind, nc, sflags, start_lineno;
|
||||||
|
+ int orig_ind, nc, sflags, start_lineno, local_extglob;
|
||||||
|
char *ret, *ep, *ostring;
|
||||||
|
|
||||||
|
/*debug_parser(1);*/
|
||||||
|
@@ -4278,7 +4278,7 @@ xparse_dolparen (base, string, indp, flags)
|
||||||
|
old value will be restored by restore_parser_state(). */
|
||||||
|
expand_aliases = 0;
|
||||||
|
#if defined (EXTENDED_GLOB)
|
||||||
|
- global_extglob = extended_glob; /* for reset_parser() */
|
||||||
|
+ local_extglob = extended_glob;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
token_to_read = DOLPAREN; /* let's trick the parser */
|
||||||
|
@@ -4296,6 +4296,9 @@ xparse_dolparen (base, string, indp, flags)
|
||||||
|
restore_input_line_state (&ls);
|
||||||
|
restore_parser_state (&ps);
|
||||||
|
|
||||||
|
+#if defined (EXTENDED_GLOB)
|
||||||
|
+ extended_glob = local_extglob;
|
||||||
|
+#endif
|
||||||
|
token_to_read = 0;
|
||||||
|
|
||||||
|
/* If parse_string returns < 0, we need to jump to top level with the
|
||||||
|
@@ -4731,12 +4734,16 @@ cond_term ()
|
||||||
|
}
|
||||||
|
|
||||||
|
/* rhs */
|
||||||
|
+#if defined (EXTENDED_GLOB)
|
||||||
|
local_extglob = extended_glob;
|
||||||
|
if (parser_state & PST_EXTPAT)
|
||||||
|
extended_glob = 1;
|
||||||
|
+#endif
|
||||||
|
tok = read_token (READ);
|
||||||
|
+#if defined (EXTENDED_GLOB)
|
||||||
|
if (parser_state & PST_EXTPAT)
|
||||||
|
extended_glob = local_extglob;
|
||||||
|
+#endif
|
||||||
|
parser_state &= ~(PST_REGEXP|PST_EXTPAT);
|
||||||
|
|
||||||
|
if (tok == WORD)
|
||||||
|
@@ -4783,7 +4790,6 @@ parse_cond_command ()
|
||||||
|
{
|
||||||
|
COND_COM *cexp;
|
||||||
|
|
||||||
|
- global_extglob = extended_glob;
|
||||||
|
cexp = cond_expr ();
|
||||||
|
return (make_cond_command (cexp));
|
||||||
|
}
|
||||||
|
diff --git a/patchlevel.h b/patchlevel.h
|
||||||
|
--- a/patchlevel.h
|
||||||
|
+++ b/patchlevel.h
|
||||||
|
@@ -25,6 +25,6 @@
|
||||||
|
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
|
||||||
|
looks for to find the patch level (for the sccs version string). */
|
||||||
|
|
||||||
|
-#define PATCHLEVEL 11
|
||||||
|
+#define PATCHLEVEL 12
|
||||||
|
|
||||||
|
#endif /* _PATCHLEVEL_H_ */
|
||||||
|
diff --git a/y.tab.c b/y.tab.c
|
||||||
|
--- a/y.tab.c
|
||||||
|
+++ b/y.tab.c
|
||||||
|
@@ -175,7 +175,7 @@ do { \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#if defined (EXTENDED_GLOB)
|
||||||
|
-extern int extended_glob;
|
||||||
|
+extern int extended_glob, extglob_flag;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (TRANSLATABLE_STRINGS)
|
||||||
|
@@ -5615,7 +5615,7 @@ reset_parser ()
|
||||||
|
#if defined (EXTENDED_GLOB)
|
||||||
|
/* Reset to global value of extended glob */
|
||||||
|
if (parser_state & (PST_EXTPAT|PST_CMDSUBST))
|
||||||
|
- extended_glob = global_extglob;
|
||||||
|
+ extended_glob = extglob_flag;
|
||||||
|
#endif
|
||||||
|
if (parser_state & (PST_CMDSUBST|PST_STRING))
|
||||||
|
expand_aliases = expaliases_flag;
|
||||||
|
@@ -6435,10 +6435,10 @@ parse_comsub (qc, open, close, lenp, flags)
|
||||||
|
expand_aliases = posixly_correct != 0;
|
||||||
|
#if defined (EXTENDED_GLOB)
|
||||||
|
/* If (parser_state & PST_EXTPAT), we're parsing an extended pattern for a
|
||||||
|
- conditional command and have already set global_extglob appropriately. */
|
||||||
|
+ conditional command and have already set extended_glob appropriately. */
|
||||||
|
if (shell_compatibility_level <= 51 && was_extpat == 0)
|
||||||
|
{
|
||||||
|
- local_extglob = global_extglob = extended_glob;
|
||||||
|
+ local_extglob = extended_glob;
|
||||||
|
extended_glob = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
@@ -6546,7 +6546,7 @@ xparse_dolparen (base, string, indp, flags)
|
||||||
|
{
|
||||||
|
sh_parser_state_t ps;
|
||||||
|
sh_input_line_state_t ls;
|
||||||
|
- int orig_ind, nc, sflags, start_lineno;
|
||||||
|
+ int orig_ind, nc, sflags, start_lineno, local_extglob;
|
||||||
|
char *ret, *ep, *ostring;
|
||||||
|
|
||||||
|
/*debug_parser(1);*/
|
||||||
|
@@ -6589,7 +6589,7 @@ xparse_dolparen (base, string, indp, flags)
|
||||||
|
old value will be restored by restore_parser_state(). */
|
||||||
|
expand_aliases = 0;
|
||||||
|
#if defined (EXTENDED_GLOB)
|
||||||
|
- global_extglob = extended_glob; /* for reset_parser() */
|
||||||
|
+ local_extglob = extended_glob;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
token_to_read = DOLPAREN; /* let's trick the parser */
|
||||||
|
@@ -6607,6 +6607,9 @@ xparse_dolparen (base, string, indp, flags)
|
||||||
|
restore_input_line_state (&ls);
|
||||||
|
restore_parser_state (&ps);
|
||||||
|
|
||||||
|
+#if defined (EXTENDED_GLOB)
|
||||||
|
+ extended_glob = local_extglob;
|
||||||
|
+#endif
|
||||||
|
token_to_read = 0;
|
||||||
|
|
||||||
|
/* If parse_string returns < 0, we need to jump to top level with the
|
||||||
|
@@ -7042,12 +7045,16 @@ cond_term ()
|
||||||
|
}
|
||||||
|
|
||||||
|
/* rhs */
|
||||||
|
+#if defined (EXTENDED_GLOB)
|
||||||
|
local_extglob = extended_glob;
|
||||||
|
if (parser_state & PST_EXTPAT)
|
||||||
|
extended_glob = 1;
|
||||||
|
+#endif
|
||||||
|
tok = read_token (READ);
|
||||||
|
+#if defined (EXTENDED_GLOB)
|
||||||
|
if (parser_state & PST_EXTPAT)
|
||||||
|
extended_glob = local_extglob;
|
||||||
|
+#endif
|
||||||
|
parser_state &= ~(PST_REGEXP|PST_EXTPAT);
|
||||||
|
|
||||||
|
if (tok == WORD)
|
||||||
|
@@ -7094,7 +7101,6 @@ parse_cond_command ()
|
||||||
|
{
|
||||||
|
COND_COM *cexp;
|
||||||
|
|
||||||
|
- global_extglob = extended_glob;
|
||||||
|
cexp = cond_expr ();
|
||||||
|
return (make_cond_command (cexp));
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
diff --git a/patchlevel.h b/patchlevel.h
|
||||||
|
--- a/patchlevel.h
|
||||||
|
+++ b/patchlevel.h
|
||||||
|
@@ -25,6 +25,6 @@
|
||||||
|
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
|
||||||
|
looks for to find the patch level (for the sccs version string). */
|
||||||
|
|
||||||
|
-#define PATCHLEVEL 12
|
||||||
|
+#define PATCHLEVEL 13
|
||||||
|
|
||||||
|
#endif /* _PATCHLEVEL_H_ */
|
||||||
|
diff --git a/subst.c b/subst.c
|
||||||
|
--- a/subst.c
|
||||||
|
+++ b/subst.c
|
||||||
|
@@ -7497,8 +7497,6 @@ expand_arrayref:
|
||||||
|
? quote_string (temp)
|
||||||
|
: quote_escapes (temp);
|
||||||
|
rflags |= W_ARRAYIND;
|
||||||
|
- if (estatep)
|
||||||
|
- *estatep = es; /* structure copy */
|
||||||
|
}
|
||||||
|
/* Note that array[*] and array[@] expanded to a quoted null string by
|
||||||
|
returning the W_HASQUOTEDNULL flag to the caller in addition to TEMP. */
|
||||||
|
@@ -7507,7 +7505,9 @@ expand_arrayref:
|
||||||
|
else if (es.subtype == 2 && temp && QUOTED_NULL (temp) && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
|
||||||
|
rflags |= W_HASQUOTEDNULL;
|
||||||
|
|
||||||
|
- if (estatep == 0)
|
||||||
|
+ if (estatep)
|
||||||
|
+ *estatep = es; /* structure copy */
|
||||||
|
+ else
|
||||||
|
flush_eltstate (&es);
|
||||||
|
}
|
||||||
|
#endif
|
@ -0,0 +1,93 @@
|
|||||||
|
diff --git a/execute_cmd.c b/execute_cmd.c
|
||||||
|
--- a/execute_cmd.c
|
||||||
|
+++ b/execute_cmd.c
|
||||||
|
@@ -3624,6 +3624,7 @@ execute_case_command (case_command)
|
||||||
|
free (pattern);
|
||||||
|
|
||||||
|
dispose_words (es);
|
||||||
|
+ QUIT;
|
||||||
|
|
||||||
|
if (match)
|
||||||
|
{
|
||||||
|
diff --git a/patchlevel.h b/patchlevel.h
|
||||||
|
--- a/patchlevel.h
|
||||||
|
+++ b/patchlevel.h
|
||||||
|
@@ -25,6 +25,6 @@
|
||||||
|
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
|
||||||
|
looks for to find the patch level (for the sccs version string). */
|
||||||
|
|
||||||
|
-#define PATCHLEVEL 13
|
||||||
|
+#define PATCHLEVEL 14
|
||||||
|
|
||||||
|
#endif /* _PATCHLEVEL_H_ */
|
||||||
|
diff --git a/sig.c b/sig.c
|
||||||
|
--- a/sig.c
|
||||||
|
+++ b/sig.c
|
||||||
|
@@ -94,6 +94,7 @@ static SigHandler *old_winch = (SigHandler *)SIG_DFL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void initialize_shell_signals PARAMS((void));
|
||||||
|
+static void kill_shell PARAMS((int));
|
||||||
|
|
||||||
|
void
|
||||||
|
initialize_signals (reinit)
|
||||||
|
@@ -486,6 +487,8 @@ restore_sigmask ()
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int handling_termsig = 0;
|
||||||
|
+
|
||||||
|
sighandler
|
||||||
|
termsig_sighandler (sig)
|
||||||
|
int sig;
|
||||||
|
@@ -532,6 +535,14 @@ termsig_sighandler (sig)
|
||||||
|
sig == terminating_signal)
|
||||||
|
terminate_immediately = 1;
|
||||||
|
|
||||||
|
+ /* If we are currently handling a terminating signal, we have a couple of
|
||||||
|
+ choices here. We can ignore this second terminating signal and let the
|
||||||
|
+ shell exit from the first one, or we can exit immediately by killing
|
||||||
|
+ the shell with this signal. This code implements the latter; to implement
|
||||||
|
+ the former, replace the kill_shell(sig) with return. */
|
||||||
|
+ if (handling_termsig)
|
||||||
|
+ kill_shell (sig); /* just short-circuit now */
|
||||||
|
+
|
||||||
|
terminating_signal = sig;
|
||||||
|
|
||||||
|
if (terminate_immediately)
|
||||||
|
@@ -564,16 +575,13 @@ void
|
||||||
|
termsig_handler (sig)
|
||||||
|
int sig;
|
||||||
|
{
|
||||||
|
- static int handling_termsig = 0;
|
||||||
|
- int i, core;
|
||||||
|
- sigset_t mask;
|
||||||
|
-
|
||||||
|
/* Simple semaphore to keep this function from being executed multiple
|
||||||
|
times. Since we no longer are running as a signal handler, we don't
|
||||||
|
block multiple occurrences of the terminating signals while running. */
|
||||||
|
if (handling_termsig)
|
||||||
|
return;
|
||||||
|
- handling_termsig = 1;
|
||||||
|
+
|
||||||
|
+ handling_termsig = terminating_signal; /* for termsig_sighandler */
|
||||||
|
terminating_signal = 0; /* keep macro from re-testing true. */
|
||||||
|
|
||||||
|
/* I don't believe this condition ever tests true. */
|
||||||
|
@@ -613,6 +621,16 @@ termsig_handler (sig)
|
||||||
|
|
||||||
|
run_exit_trap (); /* XXX - run exit trap possibly in signal context? */
|
||||||
|
|
||||||
|
+ kill_shell (sig);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+kill_shell (sig)
|
||||||
|
+ int sig;
|
||||||
|
+{
|
||||||
|
+ int i, core;
|
||||||
|
+ sigset_t mask;
|
||||||
|
+
|
||||||
|
/* We don't change the set of blocked signals. If a user starts the shell
|
||||||
|
with a terminating signal blocked, we won't get here (and if by some
|
||||||
|
magic chance we do, we'll exit below). What we do is to restore the
|
@ -0,0 +1,163 @@
|
|||||||
|
diff --git a/builtins/common.h b/builtins/common.h
|
||||||
|
--- a/builtins/common.h
|
||||||
|
+++ b/builtins/common.h
|
||||||
|
@@ -51,6 +51,7 @@ do { \
|
||||||
|
#define SEVAL_FUNCDEF 0x080 /* only allow function definitions */
|
||||||
|
#define SEVAL_ONECMD 0x100 /* only allow a single command */
|
||||||
|
#define SEVAL_NOHISTEXP 0x200 /* inhibit history expansion */
|
||||||
|
+#define SEVAL_NOOPTIMIZE 0x400 /* don't try to set optimization flags */
|
||||||
|
|
||||||
|
/* Flags for describe_command, shared between type.def and command.def */
|
||||||
|
#define CDESC_ALL 0x001 /* type -a */
|
||||||
|
diff --git a/builtins/eval.def b/builtins/eval.def
|
||||||
|
--- a/builtins/eval.def
|
||||||
|
+++ b/builtins/eval.def
|
||||||
|
@@ -53,5 +53,5 @@ eval_builtin (list)
|
||||||
|
return (EX_USAGE);
|
||||||
|
list = loptend; /* skip over possible `--' */
|
||||||
|
|
||||||
|
- return (list ? evalstring (string_list (list), "eval", SEVAL_NOHIST) : EXECUTION_SUCCESS);
|
||||||
|
+ return (list ? evalstring (string_list (list), "eval", SEVAL_NOHIST|SEVAL_NOOPTIMIZE) : EXECUTION_SUCCESS);
|
||||||
|
}
|
||||||
|
diff --git a/builtins/evalstring.c b/builtins/evalstring.c
|
||||||
|
--- a/builtins/evalstring.c
|
||||||
|
+++ b/builtins/evalstring.c
|
||||||
|
@@ -132,8 +132,8 @@ optimize_connection_fork (command)
|
||||||
|
if (command->type == cm_connection &&
|
||||||
|
(command->value.Connection->connector == AND_AND || command->value.Connection->connector == OR_OR || command->value.Connection->connector == ';') &&
|
||||||
|
(command->value.Connection->second->flags & CMD_TRY_OPTIMIZING) &&
|
||||||
|
- ((startup_state == 2 && should_suppress_fork (command->value.Connection->second)) ||
|
||||||
|
- ((subshell_environment & SUBSHELL_PAREN) && should_optimize_fork (command->value.Connection->second, 0))))
|
||||||
|
+ (should_suppress_fork (command->value.Connection->second) ||
|
||||||
|
+ ((subshell_environment & SUBSHELL_PAREN) && should_optimize_fork (command->value.Connection->second, 0))))
|
||||||
|
{
|
||||||
|
command->value.Connection->second->flags |= CMD_NO_FORK;
|
||||||
|
command->value.Connection->second->value.Simple->flags |= CMD_NO_FORK;
|
||||||
|
@@ -290,6 +290,7 @@ parse_prologue (string, flags, tag)
|
||||||
|
(flags & SEVAL_NOFREE) -> don't free STRING when finished
|
||||||
|
(flags & SEVAL_RESETLINE) -> reset line_number to 1
|
||||||
|
(flags & SEVAL_NOHISTEXP) -> history_expansion_inhibited -> 1
|
||||||
|
+ (flags & SEVAL_NOOPTIMIZE) -> don't try to turn on optimizing flags
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
@@ -502,7 +503,9 @@ parse_and_execute (string, from_file, flags)
|
||||||
|
if we are at the end of the command string, the last in a
|
||||||
|
series of connection commands is
|
||||||
|
command->value.Connection->second. */
|
||||||
|
- else if (command->type == cm_connection && can_optimize_connection (command))
|
||||||
|
+ else if (command->type == cm_connection &&
|
||||||
|
+ (flags & SEVAL_NOOPTIMIZE) == 0 &&
|
||||||
|
+ can_optimize_connection (command))
|
||||||
|
{
|
||||||
|
command->value.Connection->second->flags |= CMD_TRY_OPTIMIZING;
|
||||||
|
command->value.Connection->second->value.Simple->flags |= CMD_TRY_OPTIMIZING;
|
||||||
|
diff --git a/execute_cmd.c b/execute_cmd.c
|
||||||
|
--- a/execute_cmd.c
|
||||||
|
+++ b/execute_cmd.c
|
||||||
|
@@ -1654,7 +1654,8 @@ execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close)
|
||||||
|
subshell sets an exit trap, so we set CMD_NO_FORK for simple commands
|
||||||
|
and set CMD_TRY_OPTIMIZING for simple commands on the right side of an
|
||||||
|
and-or or `;' list to test for optimizing forks when they are executed. */
|
||||||
|
- if (user_subshell && command->type == cm_subshell)
|
||||||
|
+ if (user_subshell && command->type == cm_subshell &&
|
||||||
|
+ (command->flags & (CMD_TIME_PIPELINE|CMD_INVERT_RETURN)) == 0)
|
||||||
|
optimize_subshell_command (command->value.Subshell->command);
|
||||||
|
|
||||||
|
/* Do redirections, then dispose of them before recursive call. */
|
||||||
|
diff --git a/jobs.c b/jobs.c
|
||||||
|
--- a/jobs.c
|
||||||
|
+++ b/jobs.c
|
||||||
|
@@ -4220,7 +4220,7 @@ run_sigchld_trap (nchild)
|
||||||
|
jobs_list_frozen = 1;
|
||||||
|
for (i = 0; i < nchild; i++)
|
||||||
|
{
|
||||||
|
- parse_and_execute (savestring (trap_command), "trap", SEVAL_NOHIST|SEVAL_RESETLINE);
|
||||||
|
+ parse_and_execute (savestring (trap_command), "trap", SEVAL_NOHIST|SEVAL_RESETLINE|SEVAL_NOOPTIMIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
run_unwind_frame ("SIGCHLD trap");
|
||||||
|
diff --git a/parse.y b/parse.y
|
||||||
|
--- a/parse.y
|
||||||
|
+++ b/parse.y
|
||||||
|
@@ -2827,7 +2827,7 @@ execute_variable_command (command, vname)
|
||||||
|
if (last_lastarg)
|
||||||
|
last_lastarg = savestring (last_lastarg);
|
||||||
|
|
||||||
|
- parse_and_execute (savestring (command), vname, SEVAL_NONINT|SEVAL_NOHIST);
|
||||||
|
+ parse_and_execute (savestring (command), vname, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOOPTIMIZE);
|
||||||
|
|
||||||
|
restore_parser_state (&ps);
|
||||||
|
bind_variable ("_", last_lastarg, 0);
|
||||||
|
diff --git a/patchlevel.h b/patchlevel.h
|
||||||
|
--- a/patchlevel.h
|
||||||
|
+++ b/patchlevel.h
|
||||||
|
@@ -25,6 +25,6 @@
|
||||||
|
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
|
||||||
|
looks for to find the patch level (for the sccs version string). */
|
||||||
|
|
||||||
|
-#define PATCHLEVEL 14
|
||||||
|
+#define PATCHLEVEL 15
|
||||||
|
|
||||||
|
#endif /* _PATCHLEVEL_H_ */
|
||||||
|
diff --git a/trap.c b/trap.c
|
||||||
|
--- a/trap.c
|
||||||
|
+++ b/trap.c
|
||||||
|
@@ -304,6 +304,7 @@ run_pending_traps ()
|
||||||
|
sh_parser_state_t pstate;
|
||||||
|
volatile int save_return_catch_flag, function_code;
|
||||||
|
procenv_t save_return_catch;
|
||||||
|
+ char *trap_command, *old_trap;
|
||||||
|
#if defined (ARRAY_VARS)
|
||||||
|
ARRAY *ps;
|
||||||
|
#endif
|
||||||
|
@@ -419,6 +420,9 @@ run_pending_traps ()
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
+ old_trap = trap_list[sig];
|
||||||
|
+ trap_command = savestring (old_trap);
|
||||||
|
+
|
||||||
|
save_parser_state (&pstate);
|
||||||
|
save_subst_varlist = subst_assign_varlist;
|
||||||
|
subst_assign_varlist = 0;
|
||||||
|
@@ -441,7 +445,8 @@ run_pending_traps ()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (function_code == 0)
|
||||||
|
- x = parse_and_execute (savestring (trap_list[sig]), "trap", SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE);
|
||||||
|
+ /* XXX is x always last_command_exit_value? */
|
||||||
|
+ x = parse_and_execute (trap_command, "trap", SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE|SEVAL_NOOPTIMIZE);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parse_and_execute_cleanup (sig + 1); /* XXX - could use -1 */
|
||||||
|
@@ -1002,7 +1007,7 @@ run_exit_trap ()
|
||||||
|
if (code == 0 && function_code == 0)
|
||||||
|
{
|
||||||
|
reset_parser ();
|
||||||
|
- parse_and_execute (trap_command, "exit trap", SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE);
|
||||||
|
+ parse_and_execute (trap_command, "exit trap", SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE|SEVAL_NOOPTIMIZE);
|
||||||
|
}
|
||||||
|
else if (code == ERREXIT)
|
||||||
|
retval = last_command_exit_value;
|
||||||
|
@@ -1109,7 +1114,7 @@ _run_trap_internal (sig, tag)
|
||||||
|
function_code = setjmp_nosigs (return_catch);
|
||||||
|
}
|
||||||
|
|
||||||
|
- flags = SEVAL_NONINT|SEVAL_NOHIST;
|
||||||
|
+ flags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOOPTIMIZE;
|
||||||
|
if (sig != DEBUG_TRAP && sig != RETURN_TRAP && sig != ERROR_TRAP)
|
||||||
|
flags |= SEVAL_RESETLINE;
|
||||||
|
evalnest++;
|
||||||
|
diff --git a/y.tab.c b/y.tab.c
|
||||||
|
--- a/y.tab.c
|
||||||
|
+++ b/y.tab.c
|
||||||
|
@@ -5138,7 +5138,7 @@ execute_variable_command (command, vname)
|
||||||
|
if (last_lastarg)
|
||||||
|
last_lastarg = savestring (last_lastarg);
|
||||||
|
|
||||||
|
- parse_and_execute (savestring (command), vname, SEVAL_NONINT|SEVAL_NOHIST);
|
||||||
|
+ parse_and_execute (savestring (command), vname, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOOPTIMIZE);
|
||||||
|
|
||||||
|
restore_parser_state (&ps);
|
||||||
|
bind_variable ("_", last_lastarg, 0);
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,23 @@
|
|||||||
|
diff --git a/builtins/evalfile.c b/builtins/evalfile.c
|
||||||
|
--- a/builtins/evalfile.c
|
||||||
|
+++ b/builtins/evalfile.c
|
||||||
|
@@ -266,7 +266,7 @@ file_error_and_exit:
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* set the flags to be passed to parse_and_execute */
|
||||||
|
- pflags = SEVAL_RESETLINE;
|
||||||
|
+ pflags = SEVAL_RESETLINE|SEVAL_NOOPTIMIZE;
|
||||||
|
pflags |= (flags & FEVAL_HISTORY) ? 0 : SEVAL_NOHIST;
|
||||||
|
|
||||||
|
if (flags & FEVAL_BUILTIN)
|
||||||
|
diff --git a/patchlevel.h b/patchlevel.h
|
||||||
|
--- a/patchlevel.h
|
||||||
|
+++ b/patchlevel.h
|
||||||
|
@@ -25,6 +25,6 @@
|
||||||
|
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
|
||||||
|
looks for to find the patch level (for the sccs version string). */
|
||||||
|
|
||||||
|
-#define PATCHLEVEL 16
|
||||||
|
+#define PATCHLEVEL 17
|
||||||
|
|
||||||
|
#endif /* _PATCHLEVEL_H_ */
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,38 @@
|
|||||||
|
diff --git a/jobs.c b/jobs.c
|
||||||
|
--- a/jobs.c
|
||||||
|
+++ b/jobs.c
|
||||||
|
@@ -3077,9 +3077,13 @@ if (job == NO_JOB)
|
||||||
|
/* Don't modify terminal pgrp if we are running in background or a
|
||||||
|
subshell. Make sure subst.c:command_substitute uses the same
|
||||||
|
conditions to determine whether or not it should undo this and
|
||||||
|
- give the terminal to pipeline_pgrp. */
|
||||||
|
-
|
||||||
|
+ give the terminal to pipeline_pgrp. We don't give the terminal
|
||||||
|
+ back to shell_pgrp if an async job in the background exits because
|
||||||
|
+ we never gave it to that job in the first place. An async job in
|
||||||
|
+ the foreground is one we started in the background and foregrounded
|
||||||
|
+ with `fg', and gave it the terminal. */
|
||||||
|
if ((flags & JWAIT_NOTERM) == 0 && running_in_background == 0 &&
|
||||||
|
+ (job == NO_JOB || IS_ASYNC (job) == 0 || IS_FOREGROUND (job)) &&
|
||||||
|
(subshell_environment & (SUBSHELL_ASYNC|SUBSHELL_PIPE)) == 0)
|
||||||
|
give_terminal_to (shell_pgrp, 0);
|
||||||
|
}
|
||||||
|
@@ -3623,6 +3627,7 @@ start_job (job, foreground)
|
||||||
|
{
|
||||||
|
get_tty_state ();
|
||||||
|
save_stty = shell_tty_info;
|
||||||
|
+ jobs[job]->flags &= ~J_ASYNC; /* no longer async */
|
||||||
|
/* Give the terminal to this job. */
|
||||||
|
if (IS_JOBCONTROL (job))
|
||||||
|
give_terminal_to (jobs[job]->pgrp, 0);
|
||||||
|
diff --git a/patchlevel.h b/patchlevel.h
|
||||||
|
--- a/patchlevel.h
|
||||||
|
+++ b/patchlevel.h
|
||||||
|
@@ -25,6 +25,6 @@
|
||||||
|
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
|
||||||
|
looks for to find the patch level (for the sccs version string). */
|
||||||
|
|
||||||
|
-#define PATCHLEVEL 18
|
||||||
|
+#define PATCHLEVEL 19
|
||||||
|
|
||||||
|
#endif /* _PATCHLEVEL_H_ */
|
@ -0,0 +1,25 @@
|
|||||||
|
diff --git a/lib/readline/nls.c b/lib/readline/nls.c
|
||||||
|
--- a/lib/readline/nls.c
|
||||||
|
+++ b/lib/readline/nls.c
|
||||||
|
@@ -141,6 +141,10 @@ _rl_init_locale (void)
|
||||||
|
if (lspec == 0)
|
||||||
|
lspec = "";
|
||||||
|
ret = setlocale (LC_CTYPE, lspec); /* ok, since it does not change locale */
|
||||||
|
+ if (ret == 0 || *ret == 0)
|
||||||
|
+ ret = setlocale (LC_CTYPE, (char *)NULL);
|
||||||
|
+ if (ret == 0 || *ret == 0)
|
||||||
|
+ ret = RL_DEFAULT_LOCALE;
|
||||||
|
#else
|
||||||
|
ret = (lspec == 0 || *lspec == 0) ? RL_DEFAULT_LOCALE : lspec;
|
||||||
|
#endif
|
||||||
|
diff --git a/patchlevel.h b/patchlevel.h
|
||||||
|
--- a/patchlevel.h
|
||||||
|
+++ b/patchlevel.h
|
||||||
|
@@ -25,6 +25,6 @@
|
||||||
|
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
|
||||||
|
looks for to find the patch level (for the sccs version string). */
|
||||||
|
|
||||||
|
-#define PATCHLEVEL 1
|
||||||
|
+#define PATCHLEVEL 2
|
||||||
|
|
||||||
|
#endif /* _PATCHLEVEL_H_ */
|
@ -0,0 +1,33 @@
|
|||||||
|
diff --git a/parse.y b/parse.y
|
||||||
|
--- a/parse.y
|
||||||
|
+++ b/parse.y
|
||||||
|
@@ -3150,6 +3150,7 @@ time_command_acceptable ()
|
||||||
|
case TIME: /* time time pipeline */
|
||||||
|
case TIMEOPT: /* time -p time pipeline */
|
||||||
|
case TIMEIGN: /* time -p -- ... */
|
||||||
|
+ case DOLPAREN:
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
diff --git a/patchlevel.h b/patchlevel.h
|
||||||
|
--- a/patchlevel.h
|
||||||
|
+++ b/patchlevel.h
|
||||||
|
@@ -25,6 +25,6 @@
|
||||||
|
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
|
||||||
|
looks for to find the patch level (for the sccs version string). */
|
||||||
|
|
||||||
|
-#define PATCHLEVEL 19
|
||||||
|
+#define PATCHLEVEL 20
|
||||||
|
|
||||||
|
#endif /* _PATCHLEVEL_H_ */
|
||||||
|
diff --git a/y.tab.c b/y.tab.c
|
||||||
|
--- a/y.tab.c
|
||||||
|
+++ b/y.tab.c
|
||||||
|
@@ -5465,6 +5465,7 @@ time_command_acceptable ()
|
||||||
|
case TIME: /* time time pipeline */
|
||||||
|
case TIMEOPT: /* time -p time pipeline */
|
||||||
|
case TIMEIGN: /* time -p -- ... */
|
||||||
|
+ case DOLPAREN:
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
return 0;
|
@ -0,0 +1,32 @@
|
|||||||
|
diff --git a/patchlevel.h b/patchlevel.h
|
||||||
|
--- a/patchlevel.h
|
||||||
|
+++ b/patchlevel.h
|
||||||
|
@@ -25,6 +25,6 @@
|
||||||
|
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
|
||||||
|
looks for to find the patch level (for the sccs version string). */
|
||||||
|
|
||||||
|
-#define PATCHLEVEL 20
|
||||||
|
+#define PATCHLEVEL 21
|
||||||
|
|
||||||
|
#endif /* _PATCHLEVEL_H_ */
|
||||||
|
diff --git a/subst.c b/subst.c
|
||||||
|
--- a/subst.c
|
||||||
|
+++ b/subst.c
|
||||||
|
@@ -1693,7 +1693,7 @@ extract_heredoc_dolbrace_string (string, sindex, quoted, flags)
|
||||||
|
t = extract_command_subst (string, &si, flags);
|
||||||
|
CHECK_STRING_OVERRUN (i, si, slen, c);
|
||||||
|
|
||||||
|
- tlen = si - i - 1;
|
||||||
|
+ tlen = si - i - 2;
|
||||||
|
RESIZE_MALLOCED_BUFFER (result, result_index, tlen + 4, result_size, 64);
|
||||||
|
result[result_index++] = c;
|
||||||
|
result[result_index++] = LPAREN;
|
||||||
|
@@ -1713,7 +1713,7 @@ extract_heredoc_dolbrace_string (string, sindex, quoted, flags)
|
||||||
|
t = extract_process_subst (string, (string[i] == '<' ? "<(" : ">)"), &si, flags);
|
||||||
|
CHECK_STRING_OVERRUN (i, si, slen, c);
|
||||||
|
|
||||||
|
- tlen = si - i - 1;
|
||||||
|
+ tlen = si - i - 2;
|
||||||
|
RESIZE_MALLOCED_BUFFER (result, result_index, tlen + 4, result_size, 64);
|
||||||
|
result[result_index++] = c;
|
||||||
|
result[result_index++] = LPAREN;
|
@ -0,0 +1,29 @@
|
|||||||
|
diff --git a/lib/readline/display.c b/lib/readline/display.c
|
||||||
|
--- a/lib/readline/display.c
|
||||||
|
+++ b/lib/readline/display.c
|
||||||
|
@@ -2683,11 +2683,8 @@ rl_forced_update_display (void)
|
||||||
|
register char *temp;
|
||||||
|
|
||||||
|
if (visible_line)
|
||||||
|
- {
|
||||||
|
- temp = visible_line;
|
||||||
|
- while (*temp)
|
||||||
|
- *temp++ = '\0';
|
||||||
|
- }
|
||||||
|
+ memset (visible_line, 0, line_size);
|
||||||
|
+
|
||||||
|
rl_on_new_line ();
|
||||||
|
forced_display++;
|
||||||
|
(*rl_redisplay_function) ();
|
||||||
|
diff --git a/patchlevel.h b/patchlevel.h
|
||||||
|
index 1712b108..e5e8cabd 100644
|
||||||
|
--- a/patchlevel.h
|
||||||
|
+++ b/patchlevel.h
|
||||||
|
@@ -25,6 +25,6 @@
|
||||||
|
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
|
||||||
|
looks for to find the patch level (for the sccs version string). */
|
||||||
|
|
||||||
|
-#define PATCHLEVEL 21
|
||||||
|
+#define PATCHLEVEL 22
|
||||||
|
|
||||||
|
#endif /* _PATCHLEVEL_H_ */
|
@ -0,0 +1,38 @@
|
|||||||
|
diff --git a/builtins/declare.def b/builtins/declare.def
|
||||||
|
--- a/builtins/declare.def
|
||||||
|
+++ b/builtins/declare.def
|
||||||
|
@@ -420,11 +420,19 @@ declare_internal (list, local_var)
|
||||||
|
|
||||||
|
if (local_var && variable_context && STREQ (name, "-"))
|
||||||
|
{
|
||||||
|
+ int o;
|
||||||
|
+
|
||||||
|
+ o = localvar_inherit;
|
||||||
|
+ localvar_inherit = 0;
|
||||||
|
var = make_local_variable ("-", 0);
|
||||||
|
- FREE (value_cell (var)); /* just in case */
|
||||||
|
- value = get_current_options ();
|
||||||
|
- var_setvalue (var, value);
|
||||||
|
- VSETATTR (var, att_invisible);
|
||||||
|
+ localvar_inherit = o;
|
||||||
|
+
|
||||||
|
+ if (value_cell (var) == NULL) /* no duplicate instances */
|
||||||
|
+ {
|
||||||
|
+ value = get_current_options ();
|
||||||
|
+ var_setvalue (var, value);
|
||||||
|
+ VSETATTR (var, att_invisible);
|
||||||
|
+ }
|
||||||
|
NEXT_VARIABLE ();
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/patchlevel.h b/patchlevel.h
|
||||||
|
--- a/patchlevel.h
|
||||||
|
+++ b/patchlevel.h
|
||||||
|
@@ -25,6 +25,6 @@
|
||||||
|
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
|
||||||
|
looks for to find the patch level (for the sccs version string). */
|
||||||
|
|
||||||
|
-#define PATCHLEVEL 22
|
||||||
|
+#define PATCHLEVEL 23
|
||||||
|
|
||||||
|
#endif /* _PATCHLEVEL_H_ */
|
@ -0,0 +1,56 @@
|
|||||||
|
diff --git a/arrayfunc.c b/arrayfunc.c
|
||||||
|
--- a/arrayfunc.c
|
||||||
|
+++ b/arrayfunc.c
|
||||||
|
@@ -650,7 +650,7 @@ assign_assoc_from_kvlist (var, nlist, h, flags)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
- aval = expand_subscript_string (v, 0);
|
||||||
|
+ aval = expand_assignment_string_to_string (v, 0);
|
||||||
|
if (aval == 0)
|
||||||
|
{
|
||||||
|
aval = (char *)xmalloc (1);
|
||||||
|
@@ -842,7 +842,7 @@ assign_compound_array_list (var, nlist, flags)
|
||||||
|
/* See above; we need to expand the value here */
|
||||||
|
if (assoc_p (var))
|
||||||
|
{
|
||||||
|
- val = expand_subscript_string (val, 0);
|
||||||
|
+ val = expand_assignment_string_to_string (val, 0);
|
||||||
|
if (val == 0)
|
||||||
|
{
|
||||||
|
val = (char *)xmalloc (1);
|
||||||
|
@@ -1030,7 +1030,7 @@ expand_and_quote_assoc_word (w, type)
|
||||||
|
nword[i++] = w[ind++];
|
||||||
|
nword[i++] = w[ind++];
|
||||||
|
|
||||||
|
- t = expand_subscript_string (w+ind, 0);
|
||||||
|
+ t = expand_assignment_string_to_string (w+ind, 0);
|
||||||
|
s = (t && strchr (t, CTLESC)) ? quote_escapes (t) : t;
|
||||||
|
value = sh_single_quote (s ? s : "");
|
||||||
|
if (s != t)
|
||||||
|
diff --git a/patchlevel.h b/patchlevel.h
|
||||||
|
--- a/patchlevel.h
|
||||||
|
+++ b/patchlevel.h
|
||||||
|
@@ -25,6 +25,6 @@
|
||||||
|
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
|
||||||
|
looks for to find the patch level (for the sccs version string). */
|
||||||
|
|
||||||
|
-#define PATCHLEVEL 23
|
||||||
|
+#define PATCHLEVEL 24
|
||||||
|
|
||||||
|
#endif /* _PATCHLEVEL_H_ */
|
||||||
|
diff --git a/subst.c b/subst.c
|
||||||
|
--- a/subst.c
|
||||||
|
+++ b/subst.c
|
||||||
|
@@ -10802,7 +10802,11 @@ expand_subscript_string (string, quoted)
|
||||||
|
oe = expand_no_split_dollar_star;
|
||||||
|
ret = (char *)NULL;
|
||||||
|
|
||||||
|
+#if 0
|
||||||
|
td.flags = W_NOPROCSUB|W_NOTILDE|W_NOSPLIT2; /* XXX - W_NOCOMSUB? */
|
||||||
|
+#else
|
||||||
|
+ td.flags = W_NOPROCSUB|W_NOSPLIT2; /* XXX - W_NOCOMSUB? */
|
||||||
|
+#endif
|
||||||
|
td.word = savestring (string); /* in case it's freed on error */
|
||||||
|
|
||||||
|
expand_no_split_dollar_star = 1;
|
@ -0,0 +1,24 @@
|
|||||||
|
diff --git a/execute_cmd.c b/execute_cmd.c
|
||||||
|
--- a/execute_cmd.c
|
||||||
|
+++ b/execute_cmd.c
|
||||||
|
@@ -1725,6 +1725,9 @@ execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close)
|
||||||
|
return_code = (return_code == EXECUTION_SUCCESS) ? EXECUTION_FAILURE
|
||||||
|
: EXECUTION_SUCCESS;
|
||||||
|
|
||||||
|
+ /* Check for terminating signals before we return to our caller, which we
|
||||||
|
+ expect to exit immediately anyway. */
|
||||||
|
+ CHECK_TERMSIG;
|
||||||
|
|
||||||
|
/* If we were explicitly placed in a subshell with (), we need
|
||||||
|
to do the `shell cleanup' things, such as running traps[0]. */
|
||||||
|
diff --git a/patchlevel.h b/patchlevel.h
|
||||||
|
--- a/patchlevel.h
|
||||||
|
+++ b/patchlevel.h
|
||||||
|
@@ -25,6 +25,6 @@
|
||||||
|
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
|
||||||
|
looks for to find the patch level (for the sccs version string). */
|
||||||
|
|
||||||
|
-#define PATCHLEVEL 24
|
||||||
|
+#define PATCHLEVEL 25
|
||||||
|
|
||||||
|
#endif /* _PATCHLEVEL_H_ */
|
@ -0,0 +1,23 @@
|
|||||||
|
diff --git a/lib/readline/colors.c b/lib/readline/colors.c
|
||||||
|
--- a/lib/readline/colors.c
|
||||||
|
+++ b/lib/readline/colors.c
|
||||||
|
@@ -73,7 +73,7 @@
|
||||||
|
static bool is_colored (enum indicator_no type);
|
||||||
|
static void restore_default_color (void);
|
||||||
|
|
||||||
|
-#define RL_COLOR_PREFIX_EXTENSION "readline-colored-completion-prefix"
|
||||||
|
+#define RL_COLOR_PREFIX_EXTENSION ".readline-colored-completion-prefix"
|
||||||
|
|
||||||
|
COLOR_EXT_TYPE *_rl_color_ext_list = 0;
|
||||||
|
|
||||||
|
diff --git a/patchlevel.h b/patchlevel.h
|
||||||
|
--- a/patchlevel.h
|
||||||
|
+++ b/patchlevel.h
|
||||||
|
@@ -25,6 +25,6 @@
|
||||||
|
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
|
||||||
|
looks for to find the patch level (for the sccs version string). */
|
||||||
|
|
||||||
|
-#define PATCHLEVEL 25
|
||||||
|
+#define PATCHLEVEL 26
|
||||||
|
|
||||||
|
#endif /* _PATCHLEVEL_H_ */
|
@ -0,0 +1,60 @@
|
|||||||
|
diff --git a/patchlevel.h b/patchlevel.h
|
||||||
|
--- a/patchlevel.h
|
||||||
|
+++ b/patchlevel.h
|
||||||
|
@@ -25,6 +25,6 @@
|
||||||
|
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
|
||||||
|
looks for to find the patch level (for the sccs version string). */
|
||||||
|
|
||||||
|
-#define PATCHLEVEL 2
|
||||||
|
+#define PATCHLEVEL 3
|
||||||
|
|
||||||
|
#endif /* _PATCHLEVEL_H_ */
|
||||||
|
diff --git a/print_cmd.c b/print_cmd.c
|
||||||
|
--- a/print_cmd.c
|
||||||
|
+++ b/print_cmd.c
|
||||||
|
@@ -297,10 +297,12 @@ make_command_string_internal (command)
|
||||||
|
case '\n': /* special case this */
|
||||||
|
{
|
||||||
|
char c = command->value.Connection->connector;
|
||||||
|
+ int was_newline;
|
||||||
|
|
||||||
|
s[0] = printing_comsub ? c : ';';
|
||||||
|
s[1] = '\0';
|
||||||
|
|
||||||
|
+ was_newline = deferred_heredocs == 0 && was_heredoc == 0 && c == '\n';
|
||||||
|
if (deferred_heredocs == 0)
|
||||||
|
{
|
||||||
|
if (was_heredoc == 0)
|
||||||
|
@@ -314,6 +316,8 @@ make_command_string_internal (command)
|
||||||
|
|
||||||
|
if (inside_function_def)
|
||||||
|
cprintf ("\n");
|
||||||
|
+ else if (printing_comsub && c == '\n' && was_newline == 0)
|
||||||
|
+ cprintf ("\n"); /* preserve newlines in comsubs but don't double them */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (c == ';')
|
||||||
|
@@ -1365,7 +1369,11 @@ print_function_def (func)
|
||||||
|
cmdcopy->redirects = func_redirects;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
- newline ("}");
|
||||||
|
+ {
|
||||||
|
+ /* { */
|
||||||
|
+ newline ("}");
|
||||||
|
+ was_heredoc = 0; /* not printing any here-documents now */
|
||||||
|
+ }
|
||||||
|
|
||||||
|
dispose_command (cmdcopy);
|
||||||
|
}
|
||||||
|
@@ -1442,7 +1450,10 @@ named_function_string (name, command, flags)
|
||||||
|
cmdcopy->redirects = func_redirects;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
- newline ("}");
|
||||||
|
+ { /* { */
|
||||||
|
+ newline ("}");
|
||||||
|
+ was_heredoc = 0;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
result = the_printed_command;
|
@ -0,0 +1,50 @@
|
|||||||
|
diff --git a/patchlevel.h b/patchlevel.h
|
||||||
|
--- a/patchlevel.h
|
||||||
|
+++ b/patchlevel.h
|
||||||
|
@@ -25,6 +25,6 @@
|
||||||
|
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
|
||||||
|
looks for to find the patch level (for the sccs version string). */
|
||||||
|
|
||||||
|
-#define PATCHLEVEL 3
|
||||||
|
+#define PATCHLEVEL 4
|
||||||
|
|
||||||
|
#endif /* _PATCHLEVEL_H_ */
|
||||||
|
diff --git a/subst.c b/subst.c
|
||||||
|
--- a/subst.c
|
||||||
|
+++ b/subst.c
|
||||||
|
@@ -1798,6 +1798,9 @@ extract_heredoc_dolbrace_string (string, sindex, quoted, flags)
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
+#define PARAMEXPNEST_MAX 32 // for now
|
||||||
|
+static int dbstate[PARAMEXPNEST_MAX];
|
||||||
|
+
|
||||||
|
/* Extract a parameter expansion expression within ${ and } from STRING.
|
||||||
|
Obey the Posix.2 rules for finding the ending `}': count braces while
|
||||||
|
skipping over enclosed quoted strings and command substitutions.
|
||||||
|
@@ -1828,6 +1831,8 @@ extract_dollar_brace_string (string, sindex, quoted, flags)
|
||||||
|
if (quoted == Q_HERE_DOCUMENT && dolbrace_state == DOLBRACE_QUOTE && (flags & SX_NOALLOC) == 0)
|
||||||
|
return (extract_heredoc_dolbrace_string (string, sindex, quoted, flags));
|
||||||
|
|
||||||
|
+ dbstate[0] = dolbrace_state;
|
||||||
|
+
|
||||||
|
pass_character = 0;
|
||||||
|
nesting_level = 1;
|
||||||
|
slen = strlen (string + *sindex) + *sindex;
|
||||||
|
@@ -1852,6 +1857,8 @@ extract_dollar_brace_string (string, sindex, quoted, flags)
|
||||||
|
|
||||||
|
if (string[i] == '$' && string[i+1] == LBRACE)
|
||||||
|
{
|
||||||
|
+ if (nesting_level < PARAMEXPNEST_MAX)
|
||||||
|
+ dbstate[nesting_level] = dolbrace_state;
|
||||||
|
nesting_level++;
|
||||||
|
i += 2;
|
||||||
|
if (dolbrace_state == DOLBRACE_QUOTE || dolbrace_state == DOLBRACE_WORD)
|
||||||
|
@@ -1864,6 +1871,7 @@ extract_dollar_brace_string (string, sindex, quoted, flags)
|
||||||
|
nesting_level--;
|
||||||
|
if (nesting_level == 0)
|
||||||
|
break;
|
||||||
|
+ dolbrace_state = (nesting_level < PARAMEXPNEST_MAX) ? dbstate[nesting_level] : dbstate[0]; /* Guess using initial state */
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
diff --git a/patchlevel.h b/patchlevel.h
|
||||||
|
--- a/patchlevel.h
|
||||||
|
+++ b/patchlevel.h
|
||||||
|
@@ -25,6 +25,6 @@
|
||||||
|
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
|
||||||
|
looks for to find the patch level (for the sccs version string). */
|
||||||
|
|
||||||
|
-#define PATCHLEVEL 4
|
||||||
|
+#define PATCHLEVEL 5
|
||||||
|
|
||||||
|
#endif /* _PATCHLEVEL_H_ */
|
||||||
|
diff --git a/subst.c b/subst.c
|
||||||
|
--- a/subst.c
|
||||||
|
+++ b/subst.c
|
||||||
|
@@ -8965,7 +8965,8 @@ pat_subst (string, pat, rep, mflags)
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
else if (*string == 0 && (match_pattern (string, pat, mtype, &s, &e) != 0))
|
||||||
|
- return ((mflags & MATCH_EXPREP) ? strcreplace (rep, '&', "", 2) : savestring (rep));
|
||||||
|
+ return (mflags & MATCH_EXPREP) ? strcreplace (rep, '&', "", 2)
|
||||||
|
+ : (rep ? savestring (rep) : savestring (""));
|
||||||
|
|
||||||
|
ret = (char *)xmalloc (rsize = 64);
|
||||||
|
ret[0] = '\0';
|
@ -0,0 +1,230 @@
|
|||||||
|
diff --git a/builtins/common.h b/builtins/common.h
|
||||||
|
--- a/builtins/common.h
|
||||||
|
+++ b/builtins/common.h
|
||||||
|
@@ -257,6 +257,8 @@ extern int print_shift_error;
|
||||||
|
extern int expand_once_flag;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+extern int expaliases_flag;
|
||||||
|
+
|
||||||
|
/* variables from source.def */
|
||||||
|
extern int source_searches_cwd;
|
||||||
|
extern int source_uses_path;
|
||||||
|
diff --git a/builtins/shopt.def b/builtins/shopt.def
|
||||||
|
--- a/builtins/shopt.def
|
||||||
|
+++ b/builtins/shopt.def
|
||||||
|
@@ -149,6 +149,9 @@ static int shopt_set_complete_direxpand PARAMS((char *, int));
|
||||||
|
static int set_assoc_expand PARAMS((char *, int));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+int expaliases_flag = 0;
|
||||||
|
+static int shopt_set_expaliases PARAMS((char *, int));
|
||||||
|
+
|
||||||
|
static int shopt_set_debug_mode PARAMS((char *, int));
|
||||||
|
|
||||||
|
static int shopt_login_shell;
|
||||||
|
@@ -198,7 +201,7 @@ static struct {
|
||||||
|
#endif
|
||||||
|
{ "dotglob", &glob_dot_filenames, (shopt_set_func_t *)NULL },
|
||||||
|
{ "execfail", &no_exit_on_failed_exec, (shopt_set_func_t *)NULL },
|
||||||
|
- { "expand_aliases", &expand_aliases, (shopt_set_func_t *)NULL },
|
||||||
|
+ { "expand_aliases", &expaliases_flag, shopt_set_expaliases },
|
||||||
|
#if defined (DEBUGGER)
|
||||||
|
{ "extdebug", &debugging_mode, shopt_set_debug_mode },
|
||||||
|
#endif
|
||||||
|
@@ -350,7 +353,7 @@ reset_shopt_options ()
|
||||||
|
check_window_size = CHECKWINSIZE_DEFAULT;
|
||||||
|
allow_null_glob_expansion = glob_dot_filenames = 0;
|
||||||
|
no_exit_on_failed_exec = 0;
|
||||||
|
- expand_aliases = 0;
|
||||||
|
+ expand_aliases = expaliases_flag = 0;
|
||||||
|
extended_quote = 1;
|
||||||
|
fail_glob_expansion = 0;
|
||||||
|
glob_asciirange = GLOBASCII_DEFAULT;
|
||||||
|
@@ -631,6 +634,15 @@ shopt_set_debug_mode (option_name, mode)
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int
|
||||||
|
+shopt_set_expaliases (option_name, mode)
|
||||||
|
+ char *option_name;
|
||||||
|
+ int mode;
|
||||||
|
+{
|
||||||
|
+ expand_aliases = expaliases_flag;
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
#if defined (READLINE)
|
||||||
|
static int
|
||||||
|
shopt_enable_hostname_completion (option_name, mode)
|
||||||
|
diff --git a/execute_cmd.c b/execute_cmd.c
|
||||||
|
--- a/execute_cmd.c
|
||||||
|
+++ b/execute_cmd.c
|
||||||
|
@@ -1536,7 +1536,7 @@ execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close)
|
||||||
|
expansion with `shopt -s expand_alias' to continue to expand
|
||||||
|
aliases. */
|
||||||
|
if (ois != interactive_shell)
|
||||||
|
- expand_aliases = 0;
|
||||||
|
+ expand_aliases = expaliases_flag = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Subshells are neither login nor interactive. */
|
||||||
|
diff --git a/general.c b/general.c
|
||||||
|
--- a/general.c
|
||||||
|
+++ b/general.c
|
||||||
|
@@ -91,7 +91,7 @@ static struct {
|
||||||
|
{
|
||||||
|
&interactive_comments,
|
||||||
|
&source_uses_path,
|
||||||
|
- &expand_aliases,
|
||||||
|
+ &expaliases_flag,
|
||||||
|
&inherit_errexit,
|
||||||
|
&print_shift_error,
|
||||||
|
0
|
||||||
|
@@ -106,7 +106,8 @@ posix_initialize (on)
|
||||||
|
/* Things that should be turned on when posix mode is enabled. */
|
||||||
|
if (on != 0)
|
||||||
|
{
|
||||||
|
- interactive_comments = source_uses_path = expand_aliases = 1;
|
||||||
|
+ interactive_comments = source_uses_path = 1;
|
||||||
|
+ expand_aliases = expaliases_flag = 1;
|
||||||
|
inherit_errexit = 1;
|
||||||
|
source_searches_cwd = 0;
|
||||||
|
print_shift_error = 1;
|
||||||
|
@@ -116,13 +117,14 @@ posix_initialize (on)
|
||||||
|
else if (saved_posix_vars) /* on == 0, restore saved settings */
|
||||||
|
{
|
||||||
|
set_posix_options (saved_posix_vars);
|
||||||
|
+ expand_aliases = expaliases_flag;
|
||||||
|
free (saved_posix_vars);
|
||||||
|
saved_posix_vars = 0;
|
||||||
|
}
|
||||||
|
else /* on == 0, restore a default set of settings */
|
||||||
|
{
|
||||||
|
source_searches_cwd = 1;
|
||||||
|
- expand_aliases = interactive_shell;
|
||||||
|
+ expand_aliases = expaliases_flag = interactive_shell; /* XXX */
|
||||||
|
print_shift_error = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/parse.y b/parse.y
|
||||||
|
--- a/parse.y
|
||||||
|
+++ b/parse.y
|
||||||
|
@@ -3306,6 +3306,8 @@ reset_parser ()
|
||||||
|
if (parser_state & (PST_EXTPAT|PST_CMDSUBST))
|
||||||
|
extended_glob = global_extglob;
|
||||||
|
#endif
|
||||||
|
+ if (parser_state & (PST_CMDSUBST|PST_STRING))
|
||||||
|
+ expand_aliases = expaliases_flag;
|
||||||
|
|
||||||
|
parser_state = 0;
|
||||||
|
here_doc_first_line = 0;
|
||||||
|
@@ -4388,6 +4390,7 @@ parse_string_to_command (string, flags)
|
||||||
|
if (flags & SX_COMPLETE)
|
||||||
|
parser_state |= PST_NOERROR;
|
||||||
|
|
||||||
|
+ parser_state |= PST_STRING;
|
||||||
|
expand_aliases = 0;
|
||||||
|
|
||||||
|
cmd = 0;
|
||||||
|
@@ -6401,7 +6404,7 @@ parse_string_to_word_list (s, flags, whom)
|
||||||
|
/* State flags we don't want to persist into compound assignments. */
|
||||||
|
parser_state &= ~PST_NOEXPAND; /* parse_comsub sentinel */
|
||||||
|
/* State flags we want to set for this run through the tokenizer. */
|
||||||
|
- parser_state |= PST_COMPASSIGN|PST_REPARSE;
|
||||||
|
+ parser_state |= PST_COMPASSIGN|PST_REPARSE|PST_STRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((tok = read_token (READ)) != yacc_EOF)
|
||||||
|
diff --git a/parser.h b/parser.h
|
||||||
|
--- a/parser.h
|
||||||
|
+++ b/parser.h
|
||||||
|
@@ -50,6 +50,7 @@
|
||||||
|
#define PST_ENDALIAS 0x200000 /* just finished expanding and consuming an alias */
|
||||||
|
#define PST_NOEXPAND 0x400000 /* don't expand anything in read_token_word; for command substitution */
|
||||||
|
#define PST_NOERROR 0x800000 /* don't print error messages in yyerror */
|
||||||
|
+#define PST_STRING 0x1000000 /* parsing a string to a command or word list */
|
||||||
|
|
||||||
|
/* Definition of the delimiter stack. Needed by parse.y and bashhist.c. */
|
||||||
|
struct dstack {
|
||||||
|
diff --git a/patchlevel.h b/patchlevel.h
|
||||||
|
--- a/patchlevel.h
|
||||||
|
+++ b/patchlevel.h
|
||||||
|
@@ -25,6 +25,6 @@
|
||||||
|
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
|
||||||
|
looks for to find the patch level (for the sccs version string). */
|
||||||
|
|
||||||
|
-#define PATCHLEVEL 5
|
||||||
|
+#define PATCHLEVEL 6
|
||||||
|
|
||||||
|
#endif /* _PATCHLEVEL_H_ */
|
||||||
|
diff --git a/shell.c b/shell.c
|
||||||
|
--- a/shell.c
|
||||||
|
+++ b/shell.c
|
||||||
|
@@ -1844,8 +1844,8 @@ reset_option_defaults ()
|
||||||
|
static void
|
||||||
|
init_interactive ()
|
||||||
|
{
|
||||||
|
- expand_aliases = interactive_shell = startup_state = 1;
|
||||||
|
- interactive = 1;
|
||||||
|
+ expand_aliases = expaliases_flag = 1;
|
||||||
|
+ interactive_shell = startup_state = interactive = 1;
|
||||||
|
#if defined (HISTORY)
|
||||||
|
if (enable_history_list == -1)
|
||||||
|
enable_history_list = 1; /* set default */
|
||||||
|
@@ -1865,7 +1865,7 @@ init_noninteractive ()
|
||||||
|
bash_history_reinit (0);
|
||||||
|
#endif /* HISTORY */
|
||||||
|
interactive_shell = startup_state = interactive = 0;
|
||||||
|
- expand_aliases = posixly_correct; /* XXX - was 0 not posixly_correct */
|
||||||
|
+ expand_aliases = expaliases_flag = posixly_correct; /* XXX - was 0 not posixly_correct */
|
||||||
|
no_line_editing = 1;
|
||||||
|
#if defined (JOB_CONTROL)
|
||||||
|
/* Even if the shell is not interactive, enable job control if the -i or
|
||||||
|
@@ -1882,7 +1882,7 @@ init_interactive_script ()
|
||||||
|
enable_history_list = 1;
|
||||||
|
#endif
|
||||||
|
init_noninteractive ();
|
||||||
|
- expand_aliases = interactive_shell = startup_state = 1;
|
||||||
|
+ expand_aliases = expaliases_flag = interactive_shell = startup_state = 1;
|
||||||
|
#if defined (HISTORY)
|
||||||
|
remember_on_history = enable_history_list; /* XXX */
|
||||||
|
#endif
|
||||||
|
@@ -2025,7 +2025,7 @@ shell_reinitialize ()
|
||||||
|
debugging = do_version = line_number = last_command_exit_value = 0;
|
||||||
|
forced_interactive = interactive_shell = 0;
|
||||||
|
subshell_environment = running_in_background = 0;
|
||||||
|
- expand_aliases = 0;
|
||||||
|
+ expand_aliases = expaliases_flag = 0;
|
||||||
|
bash_argv_initialized = 0;
|
||||||
|
|
||||||
|
/* XXX - should we set jobs_m_flag to 0 here? */
|
||||||
|
diff --git a/y.tab.c b/y.tab.c
|
||||||
|
--- a/y.tab.c
|
||||||
|
+++ b/y.tab.c
|
||||||
|
@@ -5617,6 +5617,8 @@ reset_parser ()
|
||||||
|
if (parser_state & (PST_EXTPAT|PST_CMDSUBST))
|
||||||
|
extended_glob = global_extglob;
|
||||||
|
#endif
|
||||||
|
+ if (parser_state & (PST_CMDSUBST|PST_STRING))
|
||||||
|
+ expand_aliases = expaliases_flag;
|
||||||
|
|
||||||
|
parser_state = 0;
|
||||||
|
here_doc_first_line = 0;
|
||||||
|
@@ -6699,6 +6701,7 @@ parse_string_to_command (string, flags)
|
||||||
|
if (flags & SX_COMPLETE)
|
||||||
|
parser_state |= PST_NOERROR;
|
||||||
|
|
||||||
|
+ parser_state |= PST_STRING;
|
||||||
|
expand_aliases = 0;
|
||||||
|
|
||||||
|
cmd = 0;
|
||||||
|
@@ -8712,7 +8715,7 @@ parse_string_to_word_list (s, flags, whom)
|
||||||
|
/* State flags we don't want to persist into compound assignments. */
|
||||||
|
parser_state &= ~PST_NOEXPAND; /* parse_comsub sentinel */
|
||||||
|
/* State flags we want to set for this run through the tokenizer. */
|
||||||
|
- parser_state |= PST_COMPASSIGN|PST_REPARSE;
|
||||||
|
+ parser_state |= PST_COMPASSIGN|PST_REPARSE|PST_STRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((tok = read_token (READ)) != yacc_EOF)
|
@ -0,0 +1,206 @@
|
|||||||
|
diff --git a/builtins/evalstring.c b/builtins/evalstring.c
|
||||||
|
--- a/builtins/evalstring.c
|
||||||
|
+++ b/builtins/evalstring.c
|
||||||
|
@@ -431,6 +431,8 @@ parse_and_execute (string, from_file, flags)
|
||||||
|
|
||||||
|
if (parse_command () == 0)
|
||||||
|
{
|
||||||
|
+ int local_expalias, local_alflag;
|
||||||
|
+
|
||||||
|
if ((flags & SEVAL_PARSEONLY) || (interactive_shell == 0 && read_but_dont_execute))
|
||||||
|
{
|
||||||
|
last_result = EXECUTION_SUCCESS;
|
||||||
|
@@ -507,6 +509,19 @@ parse_and_execute (string, from_file, flags)
|
||||||
|
}
|
||||||
|
#endif /* ONESHOT */
|
||||||
|
|
||||||
|
+ /* We play tricks in the parser and command_substitute() turning
|
||||||
|
+ expand_aliases on and off depending on which parsing pass and
|
||||||
|
+ whether or not we're in posix mode. This only matters for
|
||||||
|
+ parsing, and we let the higher layers deal with that. We just
|
||||||
|
+ want to ensure that expand_aliases is set to the appropriate
|
||||||
|
+ global value when we go to execute this command, so we save
|
||||||
|
+ and restore it around the execution (we don't restore it if
|
||||||
|
+ the global value of the flag (expaliases_flag) changes). */
|
||||||
|
+ local_expalias = expand_aliases;
|
||||||
|
+ local_alflag = expaliases_flag;
|
||||||
|
+ if (subshell_environment & SUBSHELL_COMSUB)
|
||||||
|
+ expand_aliases = expaliases_flag;
|
||||||
|
+
|
||||||
|
/* See if this is a candidate for $( <file ). */
|
||||||
|
if (startup_state == 2 &&
|
||||||
|
(subshell_environment & SUBSHELL_COMSUB) &&
|
||||||
|
@@ -524,6 +539,10 @@ parse_and_execute (string, from_file, flags)
|
||||||
|
dispose_fd_bitmap (bitmap);
|
||||||
|
discard_unwind_frame ("pe_dispose");
|
||||||
|
|
||||||
|
+ /* If the global value didn't change, we restore what we had. */
|
||||||
|
+ if ((subshell_environment & SUBSHELL_COMSUB) && local_alflag == expaliases_flag)
|
||||||
|
+ expand_aliases = local_expalias;
|
||||||
|
+
|
||||||
|
if (flags & SEVAL_ONECMD)
|
||||||
|
{
|
||||||
|
reset_parser ();
|
||||||
|
diff --git a/command.h b/command.h
|
||||||
|
--- a/command.h
|
||||||
|
+++ b/command.h
|
||||||
|
@@ -114,6 +114,7 @@ enum command_type { cm_for, cm_case, cm_while, cm_if, cm_simple, cm_select,
|
||||||
|
#define PF_COMPLETE 0x10 /* same as W_COMPLETE, sets SX_COMPLETE */
|
||||||
|
#define PF_EXPANDRHS 0x20 /* same as W_EXPANDRHS */
|
||||||
|
#define PF_ALLINDS 0x40 /* array, act as if [@] was supplied */
|
||||||
|
+#define PF_BACKQUOTE 0x80 /* differentiate `` from $() for command_substitute */
|
||||||
|
|
||||||
|
/* Possible values for subshell_environment */
|
||||||
|
#define SUBSHELL_ASYNC 0x01 /* subshell caused by `command &' */
|
||||||
|
diff --git a/parse.y b/parse.y
|
||||||
|
--- a/parse.y
|
||||||
|
+++ b/parse.y
|
||||||
|
@@ -3612,6 +3612,7 @@ tokword:
|
||||||
|
#define P_BACKQUOTE 0x0010 /* parsing a backquoted command substitution */
|
||||||
|
#define P_ARRAYSUB 0x0020 /* parsing a [...] array subscript for assignment */
|
||||||
|
#define P_DOLBRACE 0x0040 /* parsing a ${...} construct */
|
||||||
|
+#define P_ARITH 0x0080 /* parsing a $(( )) arithmetic expansion */
|
||||||
|
|
||||||
|
/* Lexical state while parsing a grouping construct or $(...). */
|
||||||
|
#define LEX_WASDOL 0x0001
|
||||||
|
@@ -3910,6 +3911,9 @@ parse_matched_pair (qc, open, close, lenp, flags)
|
||||||
|
}
|
||||||
|
else if ((flags & (P_ARRAYSUB|P_DOLBRACE)) && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
|
||||||
|
goto parse_dollar_word;
|
||||||
|
+ else if ((flags & P_ARITH) && (tflags & LEX_WASDOL) && ch == '(') /*)*/
|
||||||
|
+ /* $() inside $(( ))/$[ ] */
|
||||||
|
+ goto parse_dollar_word;
|
||||||
|
#if defined (PROCESS_SUBSTITUTION)
|
||||||
|
/* XXX - technically this should only be recognized at the start of
|
||||||
|
a word */
|
||||||
|
@@ -3940,7 +3944,7 @@ parse_dollar_word:
|
||||||
|
else if (ch == '{') /* } */
|
||||||
|
nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|P_DOLBRACE|rflags);
|
||||||
|
else if (ch == '[') /* ] */
|
||||||
|
- nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags);
|
||||||
|
+ nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags|P_ARITH);
|
||||||
|
|
||||||
|
CHECK_NESTRET_ERROR ();
|
||||||
|
APPEND_NESTRET ();
|
||||||
|
@@ -4079,7 +4083,7 @@ parse_comsub (qc, open, close, lenp, flags)
|
||||||
|
peekc = shell_getc (1);
|
||||||
|
shell_ungetc (peekc);
|
||||||
|
if (peekc == '(') /*)*/
|
||||||
|
- return (parse_matched_pair (qc, open, close, lenp, 0));
|
||||||
|
+ return (parse_matched_pair (qc, open, close, lenp, P_ARITH));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*itrace("parse_comsub: qc = `%c' open = %c close = %c", qc, open, close);*/
|
||||||
|
@@ -4500,7 +4504,7 @@ parse_arith_cmd (ep, adddq)
|
||||||
|
int ttoklen;
|
||||||
|
|
||||||
|
exp_lineno = line_number;
|
||||||
|
- ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0);
|
||||||
|
+ ttok = parse_matched_pair (0, '(', ')', &ttoklen, P_ARITH);
|
||||||
|
rval = 1;
|
||||||
|
if (ttok == &matched_pair_error)
|
||||||
|
return -1;
|
||||||
|
@@ -5015,7 +5019,7 @@ read_token_word (character)
|
||||||
|
pop_delimiter (dstack);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
- ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
|
||||||
|
+ ttok = parse_matched_pair (cd, '[', ']', &ttoklen, P_ARITH);
|
||||||
|
if (ttok == &matched_pair_error)
|
||||||
|
return -1; /* Bail immediately. */
|
||||||
|
RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 3,
|
||||||
|
diff --git a/patchlevel.h b/patchlevel.h
|
||||||
|
--- a/patchlevel.h
|
||||||
|
+++ b/patchlevel.h
|
||||||
|
@@ -25,6 +25,6 @@
|
||||||
|
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
|
||||||
|
looks for to find the patch level (for the sccs version string). */
|
||||||
|
|
||||||
|
-#define PATCHLEVEL 6
|
||||||
|
+#define PATCHLEVEL 7
|
||||||
|
|
||||||
|
#endif /* _PATCHLEVEL_H_ */
|
||||||
|
diff --git a/subst.c b/subst.c
|
||||||
|
--- a/subst.c
|
||||||
|
+++ b/subst.c
|
||||||
|
@@ -7123,8 +7123,12 @@ command_substitute (string, quoted, flags)
|
||||||
|
remove_quoted_escapes (string);
|
||||||
|
|
||||||
|
/* We want to expand aliases on this pass if we are not in posix mode
|
||||||
|
- for backwards compatibility. */
|
||||||
|
- if (expand_aliases)
|
||||||
|
+ for backwards compatibility. parse_and_execute() takes care of
|
||||||
|
+ setting expand_aliases back to the global value when executing the
|
||||||
|
+ parsed string. We only do this for $(...) command substitution,
|
||||||
|
+ since that is what parse_comsub handles; `` comsubs are processed
|
||||||
|
+ using parse.y:parse_matched_pair(). */
|
||||||
|
+ if (expand_aliases && (flags & PF_BACKQUOTE) == 0)
|
||||||
|
expand_aliases = posixly_correct == 0;
|
||||||
|
|
||||||
|
startup_state = 2; /* see if we can avoid a fork */
|
||||||
|
@@ -11292,7 +11296,7 @@ add_string:
|
||||||
|
else
|
||||||
|
{
|
||||||
|
de_backslash (temp);
|
||||||
|
- tword = command_substitute (temp, quoted, 0);
|
||||||
|
+ tword = command_substitute (temp, quoted, PF_BACKQUOTE);
|
||||||
|
temp1 = tword ? tword->word : (char *)NULL;
|
||||||
|
if (tword)
|
||||||
|
dispose_word_desc (tword);
|
||||||
|
diff --git a/y.tab.c b/y.tab.c
|
||||||
|
--- a/y.tab.c
|
||||||
|
+++ b/y.tab.c
|
||||||
|
@@ -5923,6 +5923,7 @@ tokword:
|
||||||
|
#define P_BACKQUOTE 0x0010 /* parsing a backquoted command substitution */
|
||||||
|
#define P_ARRAYSUB 0x0020 /* parsing a [...] array subscript for assignment */
|
||||||
|
#define P_DOLBRACE 0x0040 /* parsing a ${...} construct */
|
||||||
|
+#define P_ARITH 0x0080 /* parsing a $(( )) arithmetic expansion */
|
||||||
|
|
||||||
|
/* Lexical state while parsing a grouping construct or $(...). */
|
||||||
|
#define LEX_WASDOL 0x0001
|
||||||
|
@@ -6221,6 +6222,9 @@ parse_matched_pair (qc, open, close, lenp, flags)
|
||||||
|
}
|
||||||
|
else if ((flags & (P_ARRAYSUB|P_DOLBRACE)) && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
|
||||||
|
goto parse_dollar_word;
|
||||||
|
+ else if ((flags & P_ARITH) && (tflags & LEX_WASDOL) && ch == '(') /*)*/
|
||||||
|
+ /* $() inside $(( ))/$[ ] */
|
||||||
|
+ goto parse_dollar_word;
|
||||||
|
#if defined (PROCESS_SUBSTITUTION)
|
||||||
|
/* XXX - technically this should only be recognized at the start of
|
||||||
|
a word */
|
||||||
|
@@ -6251,7 +6255,7 @@ parse_dollar_word:
|
||||||
|
else if (ch == '{') /* } */
|
||||||
|
nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|P_DOLBRACE|rflags);
|
||||||
|
else if (ch == '[') /* ] */
|
||||||
|
- nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags);
|
||||||
|
+ nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags|P_ARITH);
|
||||||
|
|
||||||
|
CHECK_NESTRET_ERROR ();
|
||||||
|
APPEND_NESTRET ();
|
||||||
|
@@ -6390,7 +6394,7 @@ parse_comsub (qc, open, close, lenp, flags)
|
||||||
|
peekc = shell_getc (1);
|
||||||
|
shell_ungetc (peekc);
|
||||||
|
if (peekc == '(') /*)*/
|
||||||
|
- return (parse_matched_pair (qc, open, close, lenp, 0));
|
||||||
|
+ return (parse_matched_pair (qc, open, close, lenp, P_ARITH));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*itrace("parse_comsub: qc = `%c' open = %c close = %c", qc, open, close);*/
|
||||||
|
@@ -6811,7 +6815,7 @@ parse_arith_cmd (ep, adddq)
|
||||||
|
int ttoklen;
|
||||||
|
|
||||||
|
exp_lineno = line_number;
|
||||||
|
- ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0);
|
||||||
|
+ ttok = parse_matched_pair (0, '(', ')', &ttoklen, P_ARITH);
|
||||||
|
rval = 1;
|
||||||
|
if (ttok == &matched_pair_error)
|
||||||
|
return -1;
|
||||||
|
@@ -7326,7 +7330,7 @@ read_token_word (character)
|
||||||
|
pop_delimiter (dstack);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
- ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
|
||||||
|
+ ttok = parse_matched_pair (cd, '[', ']', &ttoklen, P_ARITH);
|
||||||
|
if (ttok == &matched_pair_error)
|
||||||
|
return -1; /* Bail immediately. */
|
||||||
|
RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 3,
|
@ -0,0 +1,34 @@
|
|||||||
|
diff --git a/patchlevel.h b/patchlevel.h
|
||||||
|
--- a/patchlevel.h
|
||||||
|
+++ b/patchlevel.h
|
||||||
|
@@ -25,6 +25,6 @@
|
||||||
|
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
|
||||||
|
looks for to find the patch level (for the sccs version string). */
|
||||||
|
|
||||||
|
-#define PATCHLEVEL 7
|
||||||
|
+#define PATCHLEVEL 8
|
||||||
|
|
||||||
|
#endif /* _PATCHLEVEL_H_ */
|
||||||
|
diff --git a/subst.c b/subst.c
|
||||||
|
--- a/subst.c
|
||||||
|
+++ b/subst.c
|
||||||
|
@@ -3819,6 +3819,10 @@ pos_params (string, start, end, quoted, pflags)
|
||||||
|
#define EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC || s == '~')
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+/* We don't perform process substitution in arithmetic expressions, so don't
|
||||||
|
+ bother checking for it. */
|
||||||
|
+#define ARITH_EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC || s == '~')
|
||||||
|
+
|
||||||
|
/* If there are any characters in STRING that require full expansion,
|
||||||
|
then call FUNC to expand STRING; otherwise just perform quote
|
||||||
|
removal if necessary. This returns a new string. */
|
||||||
|
@@ -4028,7 +4032,7 @@ expand_arith_string (string, quoted)
|
||||||
|
i = saw_quote = 0;
|
||||||
|
while (string[i])
|
||||||
|
{
|
||||||
|
- if (EXP_CHAR (string[i]))
|
||||||
|
+ if (ARITH_EXP_CHAR (string[i]))
|
||||||
|
break;
|
||||||
|
else if (string[i] == '\'' || string[i] == '\\' || string[i] == '"')
|
||||||
|
saw_quote = string[i];
|
@ -0,0 +1,23 @@
|
|||||||
|
diff --git a/expr.c b/expr.c
|
||||||
|
--- a/expr.c
|
||||||
|
+++ b/expr.c
|
||||||
|
@@ -1168,6 +1168,8 @@ expr_streval (tok, e, lvalue)
|
||||||
|
/* [[[[[ */
|
||||||
|
#if defined (ARRAY_VARS)
|
||||||
|
aflag = tflag; /* use a different variable for now */
|
||||||
|
+ if (shell_compatibility_level > 51)
|
||||||
|
+ aflag |= AV_ATSTARKEYS;
|
||||||
|
v = (e == ']') ? array_variable_part (tok, tflag, (char **)0, (int *)0) : find_variable (tok);
|
||||||
|
#else
|
||||||
|
v = find_variable (tok);
|
||||||
|
diff --git a/patchlevel.h b/patchlevel.h
|
||||||
|
--- a/patchlevel.h
|
||||||
|
+++ b/patchlevel.h
|
||||||
|
@@ -25,6 +25,6 @@
|
||||||
|
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
|
||||||
|
looks for to find the patch level (for the sccs version string). */
|
||||||
|
|
||||||
|
-#define PATCHLEVEL 8
|
||||||
|
+#define PATCHLEVEL 9
|
||||||
|
|
||||||
|
#endif /* _PATCHLEVEL_H_ */
|
@ -0,0 +1,20 @@
|
|||||||
|
Another C compatibility issue: char ** and char * are distinct types,
|
||||||
|
and strtold expects the former for its second argument.
|
||||||
|
|
||||||
|
Submitted upstream:
|
||||||
|
|
||||||
|
<https://lists.gnu.org/archive/html/bug-bash/2023-11/msg00104.html>
|
||||||
|
|
||||||
|
diff --git a/configure.ac b/configure.ac
|
||||||
|
index 6defea0835fe8877..955c1149a8141e19 100644
|
||||||
|
--- a/configure.ac
|
||||||
|
+++ b/configure.ac
|
||||||
|
@@ -885,7 +885,7 @@ AC_CHECK_DECLS([strtold], [
|
||||||
|
[AC_COMPILE_IFELSE(
|
||||||
|
[AC_LANG_PROGRAM(
|
||||||
|
[[#include <stdlib.h>]],
|
||||||
|
- [[long double r; char *foo, bar; r = strtold(foo, &bar);]]
|
||||||
|
+ [[long double r; char *foo, *bar; r = strtold(foo, &bar);]]
|
||||||
|
)],
|
||||||
|
[bash_cv_strtold_broken=no],[bash_cv_strtold_broken=yes])
|
||||||
|
]
|
@ -0,0 +1,21 @@
|
|||||||
|
Avoid an implicit declaration of dup2 in its configure probe. This
|
||||||
|
prevents build issues with future compilers.
|
||||||
|
|
||||||
|
Already reported upstream:
|
||||||
|
|
||||||
|
<https://lists.gnu.org/archive/html/bug-bash/2023-02/msg00000.html>
|
||||||
|
|
||||||
|
diff --git a/aclocal.m4 b/aclocal.m4
|
||||||
|
index 6162f6eb9ef90754..5cbbe96d7158197a 100644
|
||||||
|
--- a/aclocal.m4
|
||||||
|
+++ b/aclocal.m4
|
||||||
|
@@ -238,6 +238,9 @@ AC_CACHE_VAL(bash_cv_dup2_broken,
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
+#ifdef HAVE_UNISTD_H
|
||||||
|
+# include <unistd.h>
|
||||||
|
+#endif /* HAVE_UNISTD_H */
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
@ -0,0 +1,307 @@
|
|||||||
|
diff --git a/builtins.h b/builtins.h
|
||||||
|
--- a/builtins.h
|
||||||
|
+++ b/builtins.h
|
||||||
|
@@ -46,6 +46,7 @@
|
||||||
|
#define POSIX_BUILTIN 0x20 /* This builtins is special in the Posix command search order. */
|
||||||
|
#define LOCALVAR_BUILTIN 0x40 /* This builtin creates local variables */
|
||||||
|
#define ARRAYREF_BUILTIN 0x80 /* This builtin takes array references as arguments */
|
||||||
|
+#define REQUIRES_BUILTIN 0x100 /* This builtin requires other files. */
|
||||||
|
|
||||||
|
#define BASE_INDENT 4
|
||||||
|
|
||||||
|
diff --git a/builtins/mkbuiltins.c b/builtins/mkbuiltins.c
|
||||||
|
--- a/builtins/mkbuiltins.c
|
||||||
|
+++ b/builtins/mkbuiltins.c
|
||||||
|
@@ -69,11 +69,16 @@ extern char *strcpy ();
|
||||||
|
#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
|
||||||
|
|
||||||
|
/* Flag values that builtins can have. */
|
||||||
|
+/* These flags are for the C code generator,
|
||||||
|
+ the C which is produced (./builtin.c)
|
||||||
|
+ includes the flags definitions found
|
||||||
|
+ in ../builtins.h */
|
||||||
|
#define BUILTIN_FLAG_SPECIAL 0x01
|
||||||
|
#define BUILTIN_FLAG_ASSIGNMENT 0x02
|
||||||
|
#define BUILTIN_FLAG_LOCALVAR 0x04
|
||||||
|
#define BUILTIN_FLAG_POSIX_BUILTIN 0x08
|
||||||
|
#define BUILTIN_FLAG_ARRAYREF_ARG 0x10
|
||||||
|
+#define BUILTIN_FLAG_REQUIRES 0x20
|
||||||
|
|
||||||
|
#define BASE_INDENT 4
|
||||||
|
|
||||||
|
@@ -189,13 +194,21 @@ char *arrayvar_builtins[] =
|
||||||
|
"typeset", "unset", "wait", /*]*/
|
||||||
|
(char *)NULL
|
||||||
|
};
|
||||||
|
-
|
||||||
|
+
|
||||||
|
+/* The builtin commands that cause requirements on other files. */
|
||||||
|
+static char *requires_builtins[] =
|
||||||
|
+{
|
||||||
|
+ ".", "command", "exec", "source", "inlib",
|
||||||
|
+ (char *)NULL
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
/* Forward declarations. */
|
||||||
|
static int is_special_builtin ();
|
||||||
|
static int is_assignment_builtin ();
|
||||||
|
static int is_localvar_builtin ();
|
||||||
|
static int is_posix_builtin ();
|
||||||
|
static int is_arrayvar_builtin ();
|
||||||
|
+static int is_requires_builtin ();
|
||||||
|
|
||||||
|
#if !defined (HAVE_RENAME)
|
||||||
|
static int rename ();
|
||||||
|
@@ -856,6 +869,8 @@ builtin_handler (self, defs, arg)
|
||||||
|
new->flags |= BUILTIN_FLAG_POSIX_BUILTIN;
|
||||||
|
if (is_arrayvar_builtin (name))
|
||||||
|
new->flags |= BUILTIN_FLAG_ARRAYREF_ARG;
|
||||||
|
+ if (is_requires_builtin (name))
|
||||||
|
+ new->flags |= BUILTIN_FLAG_REQUIRES;
|
||||||
|
|
||||||
|
array_add ((char *)new, defs->builtins);
|
||||||
|
building_builtin = 1;
|
||||||
|
@@ -1275,13 +1290,14 @@ write_builtins (defs, structfile, externfile)
|
||||||
|
else
|
||||||
|
fprintf (structfile, "(sh_builtin_func_t *)0x0, ");
|
||||||
|
|
||||||
|
- fprintf (structfile, "%s%s%s%s%s%s, %s_doc,\n",
|
||||||
|
+ fprintf (structfile, "%s%s%s%s%s%s%s, %s_doc,\n",
|
||||||
|
"BUILTIN_ENABLED | STATIC_BUILTIN",
|
||||||
|
(builtin->flags & BUILTIN_FLAG_SPECIAL) ? " | SPECIAL_BUILTIN" : "",
|
||||||
|
(builtin->flags & BUILTIN_FLAG_ASSIGNMENT) ? " | ASSIGNMENT_BUILTIN" : "",
|
||||||
|
(builtin->flags & BUILTIN_FLAG_LOCALVAR) ? " | LOCALVAR_BUILTIN" : "",
|
||||||
|
(builtin->flags & BUILTIN_FLAG_POSIX_BUILTIN) ? " | POSIX_BUILTIN" : "",
|
||||||
|
(builtin->flags & BUILTIN_FLAG_ARRAYREF_ARG) ? " | ARRAYREF_BUILTIN" : "",
|
||||||
|
+ (builtin->flags & BUILTIN_FLAG_REQUIRES) ? " | REQUIRES_BUILTIN" : "",
|
||||||
|
document_name (builtin));
|
||||||
|
|
||||||
|
/* Don't translate short document summaries that are identical
|
||||||
|
@@ -1678,6 +1694,13 @@ is_arrayvar_builtin (name)
|
||||||
|
return (_find_in_table (name, arrayvar_builtins));
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int
|
||||||
|
+is_requires_builtin (name)
|
||||||
|
+ char *name;
|
||||||
|
+{
|
||||||
|
+ return (_find_in_table (name, requires_builtins));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
#if !defined (HAVE_RENAME)
|
||||||
|
static int
|
||||||
|
rename (from, to)
|
||||||
|
diff --git a/doc/bash.1 b/doc/bash.1
|
||||||
|
--- a/doc/bash.1
|
||||||
|
+++ b/doc/bash.1
|
||||||
|
@@ -239,6 +239,14 @@ The shell becomes restricted (see
|
||||||
|
.B "RESTRICTED SHELL"
|
||||||
|
below).
|
||||||
|
.TP
|
||||||
|
+.B \-\-rpm-requires
|
||||||
|
+Produce the list of files that are required for the
|
||||||
|
+shell script to run. This implies '-n' and is subject
|
||||||
|
+to the same limitations as compile time error checking checking;
|
||||||
|
+Command substitutions, Conditional expressions and
|
||||||
|
+.BR eval
|
||||||
|
+builtin are not parsed so some dependencies may be missed.
|
||||||
|
+.TP
|
||||||
|
.B \-\-verbose
|
||||||
|
Equivalent to \fB\-v\fP.
|
||||||
|
.TP
|
||||||
|
diff --git a/doc/bashref.texi b/doc/bashref.texi
|
||||||
|
--- a/doc/bashref.texi
|
||||||
|
+++ b/doc/bashref.texi
|
||||||
|
@@ -6927,6 +6927,13 @@ standard. @xref{Bash POSIX Mode}, for a description of the Bash
|
||||||
|
@item --restricted
|
||||||
|
Make the shell a restricted shell (@pxref{The Restricted Shell}).
|
||||||
|
|
||||||
|
+@item --rpm-requires
|
||||||
|
+Produce the list of files that are required for the
|
||||||
|
+shell script to run. This implies '-n' and is subject
|
||||||
|
+to the same limitations as compile time error checking checking;
|
||||||
|
+Command substitutions, Conditional expressions and @command{eval}
|
||||||
|
+are not parsed so some dependencies may be missed.
|
||||||
|
+
|
||||||
|
@item --verbose
|
||||||
|
Equivalent to @option{-v}. Print shell input lines as they're read.
|
||||||
|
|
||||||
|
diff --git a/eval.c b/eval.c
|
||||||
|
--- a/eval.c
|
||||||
|
+++ b/eval.c
|
||||||
|
@@ -138,7 +138,8 @@ reader_loop ()
|
||||||
|
|
||||||
|
if (read_command () == 0)
|
||||||
|
{
|
||||||
|
- if (interactive_shell == 0 && read_but_dont_execute)
|
||||||
|
+
|
||||||
|
+ if (interactive_shell == 0 && (read_but_dont_execute && !rpm_requires))
|
||||||
|
{
|
||||||
|
set_exit_status (last_command_exit_value);
|
||||||
|
dispose_command (global_command);
|
||||||
|
diff --git a/execute_cmd.c b/execute_cmd.c
|
||||||
|
--- a/execute_cmd.c
|
||||||
|
+++ b/execute_cmd.c
|
||||||
|
@@ -561,6 +561,8 @@ async_redirect_stdin ()
|
||||||
|
|
||||||
|
#define DESCRIBE_PID(pid) do { if (interactive) describe_pid (pid); } while (0)
|
||||||
|
|
||||||
|
+extern int rpm_requires;
|
||||||
|
+
|
||||||
|
/* Execute the command passed in COMMAND, perhaps doing it asynchronously.
|
||||||
|
COMMAND is exactly what read_command () places into GLOBAL_COMMAND.
|
||||||
|
ASYNCHRONOUS, if non-zero, says to do this command in the background.
|
||||||
|
@@ -592,7 +594,13 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
|
||||||
|
|
||||||
|
if (breaking || continuing)
|
||||||
|
return (last_command_exit_value);
|
||||||
|
- if (read_but_dont_execute)
|
||||||
|
+ if (command == 0 || (read_but_dont_execute && !rpm_requires))
|
||||||
|
+ return (EXECUTION_SUCCESS);
|
||||||
|
+ if (rpm_requires && command->type == cm_function_def)
|
||||||
|
+ return last_command_exit_value =
|
||||||
|
+ execute_intern_function (command->value.Function_def->name,
|
||||||
|
+ command->value.Function_def);
|
||||||
|
+ if (read_but_dont_execute)
|
||||||
|
return (last_command_exit_value);
|
||||||
|
if (command == 0)
|
||||||
|
return (EXECUTION_SUCCESS);
|
||||||
|
@@ -2883,7 +2891,7 @@ execute_for_command (for_command)
|
||||||
|
save_line_number = line_number;
|
||||||
|
if (check_identifier (for_command->name, 1) == 0)
|
||||||
|
{
|
||||||
|
- if (posixly_correct && interactive_shell == 0)
|
||||||
|
+ if (posixly_correct && interactive_shell == 0 && rpm_requires == 0)
|
||||||
|
{
|
||||||
|
last_command_exit_value = EX_BADUSAGE;
|
||||||
|
jump_to_top_level (ERREXIT);
|
||||||
|
diff --git a/execute_cmd.h b/execute_cmd.h
|
||||||
|
--- a/execute_cmd.h
|
||||||
|
+++ b/execute_cmd.h
|
||||||
|
@@ -22,6 +22,9 @@
|
||||||
|
#define _EXECUTE_CMD_H_
|
||||||
|
|
||||||
|
#include "stdc.h"
|
||||||
|
+#include "variables.h"
|
||||||
|
+#include "command.h"
|
||||||
|
+
|
||||||
|
|
||||||
|
#if defined (ARRAY_VARS)
|
||||||
|
struct func_array_state
|
||||||
|
diff --git a/make_cmd.c b/make_cmd.c
|
||||||
|
--- a/make_cmd.c
|
||||||
|
+++ b/make_cmd.c
|
||||||
|
@@ -35,6 +35,8 @@
|
||||||
|
#include "bashintl.h"
|
||||||
|
|
||||||
|
#include "shell.h"
|
||||||
|
+#include "builtins.h"
|
||||||
|
+#include "builtins/common.h"
|
||||||
|
#include "execute_cmd.h"
|
||||||
|
#include "parser.h"
|
||||||
|
#include "flags.h"
|
||||||
|
@@ -839,6 +841,30 @@ make_coproc_command (name, command)
|
||||||
|
return (make_command (cm_coproc, (SIMPLE_COM *)temp));
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void
|
||||||
|
+output_requirement (deptype, filename)
|
||||||
|
+const char *deptype;
|
||||||
|
+char *filename;
|
||||||
|
+{
|
||||||
|
+ static char *alphabet_set = "abcdefghijklmnopqrstuvwxyz"
|
||||||
|
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
+
|
||||||
|
+ if (strchr(filename, '$') || (filename[0] != '/' && strchr(filename, '/')))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ if the executable is called via variable substitution we can
|
||||||
|
+ not dermine what it is at compile time.
|
||||||
|
+
|
||||||
|
+ if the executable consists only of characters not in the
|
||||||
|
+ alphabet we do not consider it a dependency just an artifact
|
||||||
|
+ of shell parsing (ex "exec < ${infile}").
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ if (strpbrk(filename, alphabet_set))
|
||||||
|
+ printf ("%s(%s)\n", deptype, filename);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* Reverse the word list and redirection list in the simple command
|
||||||
|
has just been parsed. It seems simpler to do this here the one
|
||||||
|
time then by any other method that I can think of. */
|
||||||
|
@@ -856,6 +882,28 @@ clean_simple_command (command)
|
||||||
|
REVERSE_LIST (command->value.Simple->redirects, REDIRECT *);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (rpm_requires && command->value.Simple->words)
|
||||||
|
+ {
|
||||||
|
+ char *cmd0;
|
||||||
|
+ char *cmd1;
|
||||||
|
+ struct builtin *b;
|
||||||
|
+
|
||||||
|
+ cmd0 = command->value.Simple->words->word->word;
|
||||||
|
+ b = builtin_address_internal (cmd0, 0);
|
||||||
|
+ cmd1 = 0;
|
||||||
|
+ if (command->value.Simple->words->next)
|
||||||
|
+ cmd1 = command->value.Simple->words->next->word->word;
|
||||||
|
+
|
||||||
|
+ if (b) {
|
||||||
|
+ if ( (b->flags & REQUIRES_BUILTIN) && cmd1)
|
||||||
|
+ output_requirement ("executable", cmd1);
|
||||||
|
+ } else {
|
||||||
|
+ if (!assignment(cmd0, 0))
|
||||||
|
+ output_requirement (find_function(cmd0) ? "function" : "executable", cmd0);
|
||||||
|
+ }
|
||||||
|
+ } /*rpm_requires*/
|
||||||
|
+
|
||||||
|
+
|
||||||
|
parser_state &= ~PST_REDIRLIST;
|
||||||
|
return (command);
|
||||||
|
}
|
||||||
|
diff --git a/shell.c b/shell.c
|
||||||
|
--- a/shell.c
|
||||||
|
+++ b/shell.c
|
||||||
|
@@ -196,6 +196,9 @@ int have_devfd = 0;
|
||||||
|
/* The name of the .(shell)rc file. */
|
||||||
|
static char *bashrc_file = DEFAULT_BASHRC;
|
||||||
|
|
||||||
|
+/* Non-zero if we are finding the scripts requirements. */
|
||||||
|
+int rpm_requires;
|
||||||
|
+
|
||||||
|
/* Non-zero means to act more like the Bourne shell on startup. */
|
||||||
|
static int act_like_sh;
|
||||||
|
|
||||||
|
@@ -266,6 +269,7 @@ static const struct {
|
||||||
|
{ "protected", Int, &protected_mode, (char **)0x0 },
|
||||||
|
#endif
|
||||||
|
{ "rcfile", Charp, (int *)0x0, &bashrc_file },
|
||||||
|
+ { "rpm-requires", Int, &rpm_requires, (char **)0x0 },
|
||||||
|
#if defined (RESTRICTED_SHELL)
|
||||||
|
{ "restricted", Int, &restricted, (char **)0x0 },
|
||||||
|
#endif
|
||||||
|
@@ -510,6 +514,12 @@ main (argc, argv, env)
|
||||||
|
read_but_dont_execute = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+ if (rpm_requires)
|
||||||
|
+ {
|
||||||
|
+ read_but_dont_execute = 1;
|
||||||
|
+ initialize_shell_builtins ();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (running_setuid && privileged_mode == 0)
|
||||||
|
disable_priv_mode ();
|
||||||
|
|
||||||
|
diff --git a/shell.h b/shell.h
|
||||||
|
--- a/shell.h
|
||||||
|
+++ b/shell.h
|
||||||
|
@@ -100,6 +100,7 @@ extern int interactive, interactive_shell;
|
||||||
|
extern int startup_state;
|
||||||
|
extern int reading_shell_script;
|
||||||
|
extern int shell_initialized;
|
||||||
|
+extern int rpm_requires;
|
||||||
|
extern int bash_argv_initialized;
|
||||||
|
extern int subshell_environment;
|
||||||
|
extern int current_command_number;
|
@ -0,0 +1,10 @@
|
|||||||
|
--- bash-3.0/builtins/setattr.def.setlocale 2005-08-08 12:22:42.000000000 +0100
|
||||||
|
+++ bash-3.0/builtins/setattr.def 2005-08-08 12:25:16.000000000 +0100
|
||||||
|
@@ -423,4 +423,7 @@
|
||||||
|
|
||||||
|
if (var && (exported_p (var) || (attribute & att_exported)))
|
||||||
|
array_needs_making++; /* XXX */
|
||||||
|
+
|
||||||
|
+ if (var)
|
||||||
|
+ stupidly_hack_special_variables (name);
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
diff --git a/tests/exec.right b/tests/exec.right
|
||||||
|
--- a/tests/exec.right
|
||||||
|
+++ b/tests/exec.right
|
||||||
|
@@ -60,7 +60,6 @@ this is ohio-state
|
||||||
|
0
|
||||||
|
1
|
||||||
|
testb
|
||||||
|
-expand_aliases on
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
diff --git a/tests/execscript b/tests/execscript
|
||||||
|
--- a/tests/execscript
|
||||||
|
+++ b/tests/execscript
|
||||||
|
@@ -108,8 +108,6 @@ ${THIS_SH} ./exec6.sub
|
||||||
|
# checks for properly deciding what constitutes an executable file
|
||||||
|
${THIS_SH} ./exec7.sub
|
||||||
|
|
||||||
|
-${THIS_SH} -i ${PWD}/exec8.sub
|
||||||
|
-
|
||||||
|
${THIS_SH} ./exec9.sub
|
||||||
|
|
||||||
|
${THIS_SH} ./exec10.sub
|
||||||
|
diff --git a/tests/read.right b/tests/read.right
|
||||||
|
--- a/tests/read.right
|
||||||
|
+++ b/tests/read.right
|
||||||
|
@@ -34,17 +34,6 @@ xyz
|
||||||
|
a = xyz
|
||||||
|
a = -xyz 123-
|
||||||
|
a = abc
|
||||||
|
-timeout 1: ok
|
||||||
|
-unset or null 1
|
||||||
|
-timeout 2: ok
|
||||||
|
-unset or null 2
|
||||||
|
-timeout 3: ok
|
||||||
|
-unset or null 3
|
||||||
|
-./read2.sub: line 45: read: -3: invalid timeout specification
|
||||||
|
-1
|
||||||
|
-
|
||||||
|
-abcde
|
||||||
|
-abcde
|
||||||
|
./read3.sub: line 17: read: -1: invalid number
|
||||||
|
abc
|
||||||
|
defg
|
||||||
|
diff --git a/tests/read.tests b/tests/read.tests
|
||||||
|
--- a/tests/read.tests
|
||||||
|
+++ b/tests/read.tests
|
||||||
|
@@ -95,9 +95,6 @@ echo " foo" | { IFS=$':' ; read line; recho "$line"; }
|
||||||
|
# test read -d delim behavior
|
||||||
|
${THIS_SH} ./read1.sub
|
||||||
|
|
||||||
|
-# test read -t timeout behavior
|
||||||
|
-${THIS_SH} ./read2.sub
|
||||||
|
-
|
||||||
|
# test read -n nchars behavior
|
||||||
|
${THIS_SH} ./read3.sub
|
||||||
|
|
@ -0,0 +1,24 @@
|
|||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
Version: GnuPG v1.2.4 (Darwin)
|
||||||
|
|
||||||
|
mQGiBEEOsGwRBACFa0A1oa71HSZLWxAx0svXzhOZNQZOzqHmSuGOG92jIpQpr8Dp
|
||||||
|
vgRh40YpAwdcXb8QG1J5yGAKeevNE1zCFaA725vGSdHUyypHouV0xoWwukYO6qly
|
||||||
|
yX+2BZU+okBUqoWQkoWxiYaCSfzB2Ln7pmdys1fJhcgBKf3VjWCjd2XJTwCgoFJO
|
||||||
|
wyBFJdugjfwjSoRSwDOIMf0D/iQKqlWhIO1LGpMrGX0il0/x4zj0NAcSwAk7LaPZ
|
||||||
|
bN4UPjn5pqGEHBlf1+xDDQCkAoZ/VqESGZragl4VqJfxBr29Ag0UDvNbUbXoxQsA
|
||||||
|
Rdero1M8GiAIRc50hj7HXFoERwenbNDJL86GPLAQOTGOCa4W2o29nFfFjQrsrrYH
|
||||||
|
zVtyA/9oyKvTeEMJ7NA3VJdWcmn7gOu0FxEmSNhSoV1T4vP21Wf7f5niCCRKQLNy
|
||||||
|
Uy0wEApQi4tSysdz+AbgAc0b/bHYVzIf2uO2lIEZQNNt+3g2bmXgloWmW5fsm/di
|
||||||
|
50Gm1l1Na63d3RZ00SeFQos6WEwLUHEB0yp6KXluXLLIZitEJLQaQ2hldCBSYW1l
|
||||||
|
eSA8Y2hldEBjd3J1LmVkdT6IXgQTEQIAHgUCQQ6wbAIbAwYLCQgHAwIDFQIDAxYC
|
||||||
|
AQIeAQIXgAAKCRC7WGnwZOp0q87NAJ99FEzFvDdYzqCczXF6KKXi7YN5OACfacDY
|
||||||
|
soZcnnsy7EjBZL0zwGwb/sG5AQ0EQQ6wbxAEAJCukwDigRDPhAuI+lf+6P64lWan
|
||||||
|
IFOXIndqhvU13cDbQ/Wt5LwPzm2QTvd7F+fcHOgZ8KOFScbDpjJaRqwIybMTcIN0
|
||||||
|
B2pBLX/C10W1aY+cUrXZgXUGVISEMmpaP9v02auToo7XXVEHC+XLO9IU7/xaU98F
|
||||||
|
L69l6/K4xeNSBRM/AAMHA/wNAmRBpcyK0+VggZ5esQaIP/LyolAm2qwcmrd3dZi+
|
||||||
|
g24s7yjV0EUwvRP7xHRDQFgkAo6++QbuecU/J90lxrVnQwucZmfz9zgWDkT/MpfB
|
||||||
|
/CNRSKLFjhYq2yHmHWT6vEjw9Ry/hF6Pc0oh1a62USdfaKAiim0nVxxQmPmiRvtC
|
||||||
|
mYhJBBgRAgAJBQJBDrBvAhsMAAoJELtYafBk6nSr43AAn2ZZFQg8Gs/zUzvXMt7e
|
||||||
|
vaFqVTzcAJ0cHtKpP1i/4H4R9+OsYeQdxxWxTQ==
|
||||||
|
=2MjR
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
@ -0,0 +1,2 @@
|
|||||||
|
# ~/.bash_logout
|
||||||
|
|
@ -0,0 +1,8 @@
|
|||||||
|
# .bash_profile
|
||||||
|
|
||||||
|
# Get the aliases and functions
|
||||||
|
if [ -f ~/.bashrc ]; then
|
||||||
|
. ~/.bashrc
|
||||||
|
fi
|
||||||
|
|
||||||
|
# User specific environment and startup programs
|
@ -0,0 +1,25 @@
|
|||||||
|
# .bashrc
|
||||||
|
|
||||||
|
# Source global definitions
|
||||||
|
if [ -f /etc/bashrc ]; then
|
||||||
|
. /etc/bashrc
|
||||||
|
fi
|
||||||
|
|
||||||
|
# User specific environment
|
||||||
|
if ! [[ "$PATH" =~ "$HOME/.local/bin:$HOME/bin:" ]]; then
|
||||||
|
PATH="$HOME/.local/bin:$HOME/bin:$PATH"
|
||||||
|
fi
|
||||||
|
export PATH
|
||||||
|
|
||||||
|
# Uncomment the following line if you don't like systemctl's auto-paging feature:
|
||||||
|
# export SYSTEMD_PAGER=
|
||||||
|
|
||||||
|
# User specific aliases and functions
|
||||||
|
if [ -d ~/.bashrc.d ]; then
|
||||||
|
for rc in ~/.bashrc.d/*; do
|
||||||
|
if [ -f "$rc" ]; then
|
||||||
|
. "$rc"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
unset rc
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue