]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
commit bash-20190322 snapshot
authorChet Ramey <chet.ramey@case.edu>
Mon, 25 Mar 2019 13:36:24 +0000 (09:36 -0400)
committerChet Ramey <chet.ramey@case.edu>
Mon, 25 Mar 2019 13:36:24 +0000 (09:36 -0400)
13 files changed:
CWRU/CWRU.chlog
Makefile.in
builtins/enable.def
doc/bash.1
doc/bashref.texi
doc/version.texi
lib/readline/rlprivate.h
lib/readline/signals.c
redir.c
tests/heredoc.right
tests/heredoc.tests
tests/herestr.right
tests/herestr.tests

index ab18ef22e26cccb5f194df76c43583c700766a91..398d4abe37598823754e93185609e4640d396a94 100644 (file)
@@ -5626,3 +5626,35 @@ execute_cmd.c
          do it at the beginning -- look at this more closely). Only do it
          for loops to avoid fd exhaustion. Fixes bug reported by
          sunnycemetery@gmail.com
+
+                                  3/22
+                                  ----
+lib/readline/{rlprivate.h,signals.c}
+       - _rl_interrupt_immediately: removed as no longer used
+
+redir.c
+       - heredoc_expand: new function, called for both here-documents and
+         here-strings, takes care of expanding the document and returns a
+         string
+       - write_here_document: use heredoc_expand, call write(2) once on the
+         entire document; structure is now very similar to write_here_string
+
+                                  3/23
+                                  ----
+redir.c
+       - here_document_to_fd: expand the here document/here string first,
+         using heredoc_expand, then decide what to do; remove calls to
+         write_here_document/write_here_string in favor of calling
+         heredoc_write directly
+       - here_document_to_fd: if the expanded document is of zero length,
+         just open /dev/null right away and return it -- idea from yash
+       - here_document_to_fd: if the length of the expanded document is
+         between 1 and PIPESIZE (pipe capacity, computed by builtins/psize.aux
+         and stored in builtins/pipesize.h), try to use a pipe: write
+         the document to the write end and return the read end. Prompted by a
+         report from Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+
+builtins/enable.def
+       - dyn_load_builtin: add warning if dynamic builtin with a load function
+         is loaded more than once, before running the load function a second
+         time. From a suggestion by Stan Marsh <gazelle@xmission.com>
index 2a83c4b7fa9b6be5e777aadc9e7b015712eb9e43..4391c40671174cecdee2f800bcaeb7f7c075e0b6 100644 (file)
@@ -742,6 +742,9 @@ ${DEFDIR}/bashgetopt.o:     $(BUILTIN_SRCDIR)/bashgetopt.c
 ${DEFDIR}/builtext.h: $(BUILTIN_DEFS)
        @(cd $(DEFDIR) && $(MAKE) $(MFLAGS) builtext.h ) || exit 1
 
+${DEFDIR}/pipesize.h:
+       @(cd $(DEFDIR) && $(MAKE) $(MFLAGS) pipesize.h ) || exit 1
+
 $(SDIR)/man2html$(EXEEXT):     ${SUPPORT_SRC}/man2html.c
        @(cd $(SDIR) && $(MAKE) $(MFLAGS) all ) || exit 1
 
@@ -1111,6 +1114,7 @@ redir.o: ${BASHINCDIR}/memalloc.h shell.h syntax.h bashjmp.h ${BASHINCDIR}/posix
 redir.o: general.h xmalloc.h variables.h arrayfunc.h conftypes.h array.h hashlib.h quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h
 redir.o: dispose_cmd.h make_cmd.h subst.h sig.h pathnames.h externs.h 
 redir.o: flags.h execute_cmd.h redir.h input.h
+redir.o: ${DEFDIR}/pipesize.h
 shell.o: config.h bashtypes.h ${BASHINCDIR}/posixstat.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/filecntl.h
 shell.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
 shell.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
index 39c3669825ff4170ad842dbfa8af82c314cf01c2..42af0e69cbbb91cdf15d74907c4945c2e5d55dc3 100644 (file)
@@ -362,6 +362,8 @@ dyn_load_builtin (list, flags, filename)
       strcpy (struct_name, name);
       strcpy (struct_name + size, STRUCT_SUFFIX);
 
+      old_builtin = builtin_address_internal (name, 1);
+
       b = (struct builtin *)dlsym (handle, struct_name);
       if (b == 0)
        {
@@ -381,6 +383,9 @@ dyn_load_builtin (list, flags, filename)
       loadfunc = (sh_load_func_t *)dlsym (handle, funcname);
       if (loadfunc)
        {
+         /* Add warning if running an init function more than once */
+         if (old_builtin && (old_builtin->flags & STATIC_BUILTIN) == 0)
+           builtin_warning (_("%s: dynamic builtin already loaded"), name);
          r = (*loadfunc) (name);
          if (r == 0)
            {
@@ -396,7 +401,7 @@ dyn_load_builtin (list, flags, filename)
        b->flags |= SPECIAL_BUILTIN;
       b->handle = handle;
 
-      if (old_builtin = builtin_address_internal (name, 1))
+      if (old_builtin)
        {
          replaced++;
          FASTCOPY ((char *)b, (char *)old_builtin, sizeof (struct builtin));
index a25e50dfe2b920cbe978e45bf7d798fa24136487..542730a07b85f7465e49efa20af47de7c83cd6d0 100644 (file)
@@ -5,12 +5,12 @@
 .\"    Case Western Reserve University
 .\"    chet.ramey@case.edu
 .\"
-.\"    Last Change: Tue Feb 26 09:46:20 EST 2019
+.\"    Last Change: Sun Mar 24 14:05:55 EDT 2019
 .\"
 .\" bash_builtins, strip all but Built-Ins section
 .if \n(zZ=1 .ig zZ
 .if \n(zY=1 .ig zY
-.TH BASH 1 "2019 February 26" "GNU Bash 5.0"
+.TH BASH 1 "2019 March 24" "GNU Bash 5.0"
 .\"
 .\" There's some problem with having a `@'
 .\" in a tagged paragraph with the BSD man macros.
@@ -5212,7 +5212,7 @@ jobs are terminated.
 .PP
 When the shell is waiting for a job or process using the \fBwait\fP
 builtin, and job control is enabled, \fBwait\fP will return when the
-job changes state. The \fB\-f\fP option will force \fBwait\fP to wait
+job changes state. The \fB\-f\fP option causes \fBwait\fP to wait
 until the job or process terminates before returning.
 .SH PROMPTING
 When executing interactively,
@@ -10761,9 +10761,9 @@ is not given, all currently active child processes
 are waited for, and the return status is zero.
 If the \fB\-n\fP option is supplied, \fBwait\fP waits for any job to
 terminate and returns its exit status.
-If the \fB\-f\fP option is supplied, and job control is enabled,
-\fBwait\fP forces \fIid\fP to terminate before returning its status,
-instead of returning when it changes status.
+Supplying the \fB\-f\fP option, when job control is enabled,
+forces \fBwait\fP to wait for \fIid\fP to terminate before returning
+its status, instead of returning when it changes status.
 If
 .I id
 specifies a non-existent process or job, the return status is
index 1d59bf6439dcd70136a59e20fb3c8dc1018801d1..70ab6473b6c9f4d36b65dd1180076a67c6ddd7a7 100644 (file)
@@ -7988,7 +7988,7 @@ Bash does not print another warning, and any stopped jobs are terminated.
 
 When the shell is waiting for a job or process using the @code{wait}
 builtin, and job control is enabled, @code{wait} will return when the
-job changes state. The @option{-f} option will force @code{wait} to wait
+job changes state. The @option{-f} option causes @code{wait} to wait
 until the job or process terminates before returning.
 
 @node Job Control Builtins
@@ -8098,9 +8098,10 @@ If no arguments are given, all currently active child processes are
 waited for, and the return status is zero.
 If the @option{-n} option is supplied, @code{wait} waits for any job to
 terminate and returns its exit status.
-If the @option{-f} option is supplied, and job control is enabled,
-@code{wait} forces each @var{pid} or @var{jobspec} to terminate before
-returning its status, intead of returning when it changes status.
+Supplying the @option{-f} option, when job control is enabled,
+forces @code{wait} to wait for each @var{pid} or @var{jobspec} to
+terminate before returning its status, intead of returning when it changes
+status.
 If neither @var{jobspec} nor @var{pid} specifies an active child process
 of the shell, the return status is 127.
 
index d0de6f95763ab9e096b1923cd8ffc9f723ceb083..b98da09406c9026a54eaae401703614c4258ef76 100644 (file)
@@ -2,10 +2,10 @@
 Copyright (C) 1988-2019 Free Software Foundation, Inc.
 @end ignore
 
-@set LASTCHANGE Tue Feb 26 09:46:37 EST 2019
+@set LASTCHANGE Sun Mar 24 14:05:55 EDT 2019
 
 @set EDITION 5.0
 @set VERSION 5.0
 
-@set UPDATED 26 February 2019
-@set UPDATED-MONTH February 2019
+@set UPDATED 24 March 2019
+@set UPDATED-MONTH March 2019
index 11da43cec60c7a696891d8e0554940dacc284311..38e1dc79bf6fc2fd605bad56156c431662235624 100644 (file)
@@ -526,7 +526,6 @@ extern int _rl_executing_keyseq_size;
 extern _rl_search_cxt *_rl_nscxt;
 
 /* signals.c */
-extern int _rl_interrupt_immediately;
 extern int volatile _rl_caught_signal;
 
 extern _rl_sigcleanup_func_t *_rl_sigcleanup;
index 76c5c4733010b61e5a891ebcf0c3fd308274975e..d738db4ef00328ecf6431c858d911afbda17130f 100644 (file)
@@ -99,7 +99,6 @@ int rl_catch_sigwinch = 0;    /* for the readline state struct in readline.c */
 #endif
 
 /* Private variables. */
-int _rl_interrupt_immediately = 0;
 int volatile _rl_caught_signal = 0;    /* should be sig_atomic_t, but that requires including <signal.h> everywhere */
 
 /* If non-zero, print characters corresponding to received signals as long as
@@ -163,14 +162,7 @@ _rl_signal_handler (int sig)
 static RETSIGTYPE
 rl_signal_handler (int sig)
 {
-  if (_rl_interrupt_immediately)
-    {
-      _rl_interrupt_immediately = 0;
-      _rl_handle_signal (sig);
-    }
-  else
-    _rl_caught_signal = sig;
-
+  _rl_caught_signal = sig;
   SIGHANDLER_RETURN;
 }
 
diff --git a/redir.c b/redir.c
index 0c0c9f2ba965be9b2285496ee7842e9a11242e3f..40ea6f2d1bc7d19e28ab19cbf1d409bb9159f319 100644 (file)
--- a/redir.c
+++ b/redir.c
@@ -1,6 +1,6 @@
 /* redir.c -- Functions to perform input and output redirection. */
 
-/* Copyright (C) 1997-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1997-2019 Free Software Foundation, Inc.
 
    This file is part of GNU Bash, the Bourne Again SHell.
 
@@ -58,6 +58,17 @@ extern int errno;
 #  include "input.h"
 #endif
 
+#include "builtins/pipesize.h"
+
+/* Normally set by a build process command that computes pipe capacity */
+#ifndef PIPESIZE
+#  ifdef PIPE_BUF
+#    define PIPESIZE PIPE_BUF
+#  else
+#    define PIPESIZE 4096
+#  endif
+#endif
+
 #define SHELL_FD_BASE  10
 
 int expanding_redir;
@@ -74,8 +85,8 @@ static int stdin_redirection __P((enum r_instruction, int));
 static int undoablefd __P((int));
 static int do_redirection_internal __P((REDIRECT *, int));
 
-static int write_here_document __P((int, WORD_DESC *));
-static int write_here_string __P((int, WORD_DESC *));
+static char *heredoc_expand __P((WORD_DESC *, enum r_instruction, size_t *));
+static int heredoc_write __P((int, char *, size_t));
 static int here_document_to_fd __P((WORD_DESC *, enum r_instruction));
 
 static int redir_special_open __P((int, char *, int, int, enum r_instruction));
@@ -309,19 +320,45 @@ redirection_expand (word)
   return (result);
 }
 
-static int
-write_here_string (fd, redirectee)
-     int fd;
+/* Expand a here-document or here-string (determined by RI) contained in
+   REDIRECTEE and return the expanded document. If LENP is non-zero, put
+   the length of the returned string into *LENP.
+
+   This captures everything about expanding here-documents and here-strings:
+   the returned document should be written directly to whatever file
+   descriptor is specified. In particular, it adds a newline to the end of
+   a here-string to preserve previous semantics. */
+static char *
+heredoc_expand (redirectee, ri, lenp)
      WORD_DESC *redirectee;
+     enum r_instruction ri;
+     size_t *lenp;
 {
-  char *herestr;
-  int herelen, n, e, old;
+  char *document;
+  size_t dlen;
+  int old;
+
+  if (redirectee->word == 0 || redirectee->word[0] == '\0')
+    {
+      if (lenp)
+        *lenp = 0;
+      return (redirectee->word);
+    }
 
+  /* Quoted here documents are not expanded */
+  if (ri != r_reading_string && (redirectee->flags & W_QUOTED))
+    {
+      if (lenp)
+        *lenp = STRLEN (redirectee->word);
+      return (redirectee->word);
+    }
+  
   expanding_redir = 1;
   /* Now that we've changed the variable search order to ignore the temp
      environment, see if we need to change the cached IFS values. */
   sv_ifs ("IFS");
-  herestr = expand_string_unsplit_to_string (redirectee->word, 0);
+  document = (ri == r_reading_string) ? expand_string_unsplit_to_string (redirectee->word, 0)
+                                     : expand_string_to_string (redirectee->word, Q_HERE_DOCUMENT);
   expanding_redir = 0;
   /* Now we need to change the variable search order back to include the temp
      environment.  We force the temp environment search by forcing
@@ -332,136 +369,108 @@ write_here_string (fd, redirectee)
   sv_ifs ("IFS");
   executing_builtin = old;
 
-  herelen = STRLEN (herestr);
-
-  n = write (fd, herestr, herelen);
-  if (n == herelen)
+  dlen = STRLEN (document);
+  /* XXX - Add trailing newline to here-string */
+  if (ri == r_reading_string)
     {
-      n = write (fd, "\n", 1);
-      herelen = 1;
+      document = xrealloc (document, dlen + 2);
+      document[dlen++] = '\n';
+      document[dlen] = '\0';
     }
+  if (lenp)
+    *lenp = dlen;    
+
+  return document;
+}
+
+/* Write HEREDOC (of length HDLEN) to FD, returning 0 on success and ERRNO on
+   error. Don't handle interrupts. */
+static int
+heredoc_write (fd, heredoc, herelen)
+     int fd;
+     char *heredoc;
+     size_t herelen;
+{
+  ssize_t nw;
+  int e;
+
+  errno = 0;
+  nw = write (fd, heredoc, herelen);
   e = errno;
-  FREE (herestr);
-  if (n != herelen)
+  if (nw != herelen)
     {
       if (e == 0)
        e = ENOSPC;
       return e;
     }
   return 0;
-}  
+}
 
-/* Write the text of the here document pointed to by REDIRECTEE to the file
-   descriptor FD, which is already open to a temp file.  Return 0 if the
-   write is successful, otherwise return errno. */
+/* Create a temporary file or pipe holding the text of the here document
+   pointed to by REDIRECTEE, and return a file descriptor open for reading
+   to it. Return -1 on any error, and make sure errno is set appropriately. */
 static int
-write_here_document (fd, redirectee)
-     int fd;
+here_document_to_fd (redirectee, ri)
      WORD_DESC *redirectee;
+     enum r_instruction ri;
 {
+  char *filename;
+  int r, fd, fd2, herepipe[2];
   char *document;
-  int document_len, fd2, old;
-  FILE *fp;
-  register WORD_LIST *t, *tlist;
+  size_t document_len;
 
-  /* Expand the text if the word that was specified had
-     no quoting.  The text that we expand is treated
-     exactly as if it were surrounded by double quotes. */
+  /* Expand the here-document/here-string first and then decide what to do. */
+  document = heredoc_expand (redirectee, ri, &document_len);
 
-  if (redirectee->flags & W_QUOTED)
+  /* If we have a zero-length document, don't mess with a temp file */
+  if (document_len == 0)
     {
-      document = redirectee->word;
-      document_len = strlen (document);
-      /* Set errno to something reasonable if the write fails. */
-      if (write (fd, document, document_len) < document_len)
-       {
-         if (errno == 0)
-           errno = ENOSPC;
-         return (errno);
-       }
-      else
-       return 0;
+      fd = open ("/dev/null", O_RDONLY);
+      r = errno;
+      if (document != redirectee->word)
+       FREE (document);
+      errno = r;
+      return fd;
     }
 
-  expanding_redir = 1;
-  /* Now that we've changed the variable search order to ignore the temp
-     environment, see if we need to change the cached IFS values. */
-  sv_ifs ("IFS");
-  tlist = expand_string (redirectee->word, Q_HERE_DOCUMENT);
-  expanding_redir = 0;
-  /* Now we need to change the variable search order back to include the temp
-     environment.  We force the temp environment search by forcing
-     executing_builtin to 1.  This is what makes `read' get the right values
-     for the IFS-related cached variables, for example. */
-  old = executing_builtin;
-  executing_builtin = 1;
-  sv_ifs ("IFS");
-  executing_builtin = old;
-
-  if (tlist)
+#if defined (PIPESIZE)
+  /* Try to use a pipe internal to this process if the document is shorter
+     than the system's pipe capacity (computed at build time). We want to
+     write the entire document without write blocking. */
+  if (document_len <= PIPESIZE)
     {
-      /* Try using buffered I/O (stdio) and writing a word
-        at a time, letting stdio do the work of buffering
-        for us rather than managing our own strings.  Most
-        stdios are not particularly fast, however -- this
-        may need to be reconsidered later. */
-      if ((fd2 = dup (fd)) < 0 || (fp = fdopen (fd2, "w")) == NULL)
-       {
-         old = errno;
-         if (fd2 >= 0)
-           close (fd2);
-         dispose_words (tlist);
-         errno = old;
-         return (errno);
-       }
-      errno = 0;
-      for (t = tlist; t; t = t->next)
+      if (pipe (herepipe) < 0)
        {
-         /* This is essentially the body of
-            string_list_internal expanded inline. */
-         document = t->word->word;
-         document_len = strlen (document);
-         if (t != tlist)
-           putc (' ', fp);     /* separator */
-         fwrite (document, document_len, 1, fp);
-         if (ferror (fp))
-           {
-             if (errno == 0)
-               errno = ENOSPC;
-             fd2 = errno;
-             fclose(fp);
-             dispose_words (tlist);
-             return (fd2);
-           }
+         r = errno;
+         if (document != redirectee->word)
+           free (document);
+         errno = r;
+         return (-1);
        }
-      dispose_words (tlist);
-      if (fclose (fp) != 0)
+      r = heredoc_write (herepipe[1], document, document_len);
+      if (document != redirectee->word)
+       free (document);
+      close (herepipe[1]);
+      if (r)                   /* write error */
        {
-         if (errno == 0)
-           errno = ENOSPC;
-         return (errno);
+         close (herepipe[0]);
+         errno = r;
+         return (-1);
        }
+      return (herepipe[0]);
     }
-  return 0;
-}
-
-/* Create a temporary file holding the text of the here document pointed to
-   by REDIRECTEE, and return a file descriptor open for reading to the temp
-   file.  Return -1 on any error, and make sure errno is set appropriately. */
-static int
-here_document_to_fd (redirectee, ri)
-     WORD_DESC *redirectee;
-     enum r_instruction ri;
-{
-  char *filename;
-  int r, fd, fd2;
+#endif
 
   fd = sh_mktmpfd ("sh-thd", MT_USERANDOM|MT_USETMPDIR, &filename);
 
   /* If we failed for some reason other than the file existing, abort */
   if (fd < 0)
     {
+      r = errno;
       FREE (filename);
+      if (document != redirectee->word)
+       FREE (document);
+      errno = r;
       return (fd);
     }
 
@@ -469,10 +478,9 @@ here_document_to_fd (redirectee, ri)
   SET_CLOSE_ON_EXEC (fd);
 
   errno = r = 0;               /* XXX */
-  /* write_here_document returns 0 on success, errno on failure. */
-  if (redirectee->word)
-    r = (ri != r_reading_string) ? write_here_document (fd, redirectee)
-                                : write_here_string (fd, redirectee);
+  r = heredoc_write (fd, document, document_len);
+  if (document != redirectee->word)
+    FREE (document);
 
   if (r)
     {
index f6541dcafc129bdf7d381a13d7c7b1b048efaa25..be68f9b72e36c587a4eed3e735895861bb20e2e4 100644 (file)
@@ -1,3 +1,11 @@
+a
+b
+c
+a
+$PS4
+
+
+
 there
 one - alpha
 two - beta
@@ -93,6 +101,6 @@ argv[1] = <two>
 argv[2] = <threefi>
 argv[3] = <ve>
 comsub here-string
-./heredoc.tests: line 105: warning: here-document at line 103 delimited by end-of-file (wanted `EOF')
+./heredoc.tests: line 133: warning: here-document at line 131 delimited by end-of-file (wanted `EOF')
 hi
 there
index 303949f48e659cd61af1a86c8648c51514285a6e..6cbc4f8087ce391f7e4010260d9b6cec9e827ad6 100644 (file)
@@ -1,5 +1,33 @@
-# check order and content of multiple here docs
+# basics
+cat <<EOF
+a
+b
+c
+EOF
+read x <<EOF
+a
+b
+c
+EOF
+echo "$x"
+read x y <<\EOF
+$PS4
+EOF
+echo "$x"
 
+# empty here-documents
+read x <<EOF
+EOF
+echo "$x"
+read x <<\EOF
+EOF
+echo "$x"
+read x <<EOF
+$empty
+EOF
+echo "$x"
+
+# check order and content of multiple here docs
 cat << EOF1 << EOF2 
 hi
 EOF1
index 03f38ed6b425a2d6d33e4f66d85da638f395bbe8..4ac2cc65b3947a0dbabfb94bdaa2c2dc6d7cc888 100644 (file)
@@ -1,3 +1,10 @@
+alpha
+beta
+4
+4
+
+
+
 abcde
 yo
 hot damn
index 607f85eedf6f33372df4e5810592ece466040612..154e416875e1afb1ffb336b4ded74e221a856b36 100644 (file)
@@ -1,3 +1,23 @@
+# basics
+read x <<<"alpha"
+echo "$x"
+read x <<<beta
+echo "$x"
+X=4
+read x <<<$X
+echo "$x"
+read x <<<"$X"
+echo "$x"
+unset X
+
+# empty here-strings
+read x <<<""
+echo "$x"
+read x <<<"$empty"
+echo "$x"
+read x <<<$empty
+echo "$x"
+
 a=hot
 b=damn
 f1()