commit
39c85ea8ca
@ -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