]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
fix for exec builtin when the command is not found
authorChet Ramey <chet.ramey@case.edu>
Tue, 23 Aug 2022 13:58:22 +0000 (09:58 -0400)
committerChet Ramey <chet.ramey@case.edu>
Tue, 23 Aug 2022 13:58:22 +0000 (09:58 -0400)
CHANGES
CHANGES-5.2
CWRU/CWRU.chlog
MANIFEST
NEWS
NEWS-5.2
builtins/exec.def
examples/loadables/Makefile.in
examples/loadables/dsv.c [new file with mode: 0644]
execute_cmd.c
lib/sh/setlinebuf.c

diff --git a/CHANGES b/CHANGES
index 46386fe3403fc3e9f062c3108c1aa213fd596e98..0af4703806caf347da9d3dbfc8f7be122339cc14 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,27 @@
+This document details the changes between this version, bash-5.2-rc3, and
+the previous version, bash-5.2-rc2.
+
+1. Changes to Bash
+
+a. Added a compatibility mode feature that causes the parser to parse command
+   substitutions as if extglob were enabled. If it is enabled before execution,
+   parse at execution will succeed. If not, the subsequent execution parse will
+   fail.
+
+b. Fixed an issue with handling a `return' executed in a trap action if the
+   trap is executed while running in a shell function.
+
+2. Changes to Readline
+
+3. New Features in Bash
+
+4. New Features in Readline
+
+a. Readline now checks for changes to locale settings (LC_ALL/LC_CTYPE/LANG)
+   each time it is called, and modifies the appropriate locale-specific display
+   and key binding variables when the locale changes.
+
+------------------------------------------------------------------------------
 This document details the changes between this version, bash-5.2-rc2, and
 the previous version, bash-5.2-rc1.
 
index 3a1239b3312b5569fdde331d9c22216a5fece75e..cfd1c9c994976dc9f83e2611328de690f6e40ed8 100644 (file)
@@ -1,3 +1,27 @@
+This document details the changes between this version, bash-5.2-rc3, and
+the previous version, bash-5.2-rc2.
+
+1. Changes to Bash
+
+a. Added a compatibility mode feature that causes the parser to parse command
+   substitutions as if extglob were enabled. If it is enabled before execution,
+   parse at execution will succeed. If not, the subsequent execution parse will
+   fail.
+
+b. Fixed an issue with handling a `return' executed in a trap action if the
+   trap is executed while running in a shell function.
+
+2. Changes to Readline
+
+3. New Features in Bash
+
+4. New Features in Readline
+
+a. Readline now checks for changes to locale settings (LC_ALL/LC_CTYPE/LANG)
+   each time it is called, and modifies the appropriate locale-specific display
+   and key binding variables when the locale changes.
+
+------------------------------------------------------------------------------
 This document details the changes between this version, bash-5.2-rc2, and
 the previous version, bash-5.2-rc1.
 
index 1f373d217ab6a787b1c3afe5237f64e1d431c750..0de19642c966956da9a589d8e1d185c95ad54ecb 100644 (file)
@@ -3888,3 +3888,20 @@ lib/readline/readline.c
          the internal readline variables get set when we move from a non-
          multibyte locale ("C") to a multibyte one ("en_US.UTF-8"). Report
          from Alan Coopersmith <alan.coopersmith@oracle.com>
+
+                                  8/16
+                                  ----
+lib/sh/setlinebuf.c
+       - sh_setlinebuf: allocate buffers for line-buffering stdout and stderr
+         only once, the first time it is requested. Only allocate memory if
+         we're using setvbuf (we usually are). Double the buffer size to 2016
+         if we're using the bash malloc. Otherwise, let stdio handle it.
+
+                                  8/17
+                                  ----
+builtins/exec.def
+       - exec_builtin: make sure to initialize orig_job_control in case the
+         command is not found by search_for_command. Report and fix from
+         Xiami <i@f2light.com>
+
+         
index ee8b0c7eb433ba831bf2a247ce56902cd0941f7a..4bd7f0fb234ec24479cde3dbcd3379b2e0b5059d 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -735,6 +735,7 @@ examples/loadables/fdflags.c        f
 examples/loadables/finfo.c     f
 examples/loadables/cat.c       f
 examples/loadables/csv.c       f
+examples/loadables/dsv.c       f
 examples/loadables/cut.c       f
 examples/loadables/logname.c   f
 examples/loadables/basename.c  f
diff --git a/NEWS b/NEWS
index e5ada2f57333160069098f3b02ca1a51ce25fb1a..62d22127fcad336e59c5e5067567d5912ff5b8a9 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -164,6 +164,10 @@ l. There is a new configuration option: --with-shared-termcap-library, which
    forces linking the shared readline library with the shared termcap (or
    curses/ncurses/termlib) library so applications don't have to do it.
 
+m. Readline now checks for changes to locale settings (LC_ALL/LC_CTYPE/LANG)
+   each time it is called, and modifies the appropriate locale-specific display
+   and key binding variables when the locale changes.
+
 -------------------------------------------------------------------------------
 This is a terse description of the new features added to bash-5.1 since
 the release of bash-5.0.  As always, the manual page (doc/bash.1) is
index f2e7af3da5f0e6cf4f518769b9a55ea175462bce..0e1524cae44145bd1ced86ef35c72487c7636243 100644 (file)
--- a/NEWS-5.2
+++ b/NEWS-5.2
@@ -163,3 +163,7 @@ k. New readline state (RL_STATE_EOF) and application-visible variable
 l. There is a new configuration option: --with-shared-termcap-library, which
    forces linking the shared readline library with the shared termcap (or
    curses/ncurses/termlib) library so applications don't have to do it.
+
+m. Readline now checks for changes to locale settings (LC_ALL/LC_CTYPE/LANG)
+   each time it is called, and modifies the appropriate locale-specific display
+   and key binding variables when the locale changes.
index 16a81daeee48164392c938392c2464dac44d1b7f..add9082295e56ab3e64bfac6816e6d773c2ae0e9 100644 (file)
@@ -104,7 +104,7 @@ exec_builtin (list)
   int cleanenv, login, opt, orig_job_control;
   char *argv0, *command, **args, **env, *newname, *com2;
 
-  cleanenv = login = 0;
+  cleanenv = login = orig_job_control = 0;
   exec_argv0 = argv0 = (char *)NULL;
 
   reset_internal_getopt ();
index a3cf372552b67a5a5643aae0ba949b9cdc5fbc55..956f018933f861ff157841f42247a778f04ba909 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Simple makefile for the sample loadable builtins
 #
-# Copyright (C) 1996-2019 Free Software Foundation, Inc.
+# Copyright (C) 1996-2022 Free Software Foundation, Inc.
 
 #   This program is free software: you can redistribute it and/or modify
 #   it under the terms of the GNU General Public License as published by
@@ -104,7 +104,7 @@ INC = -I. -I.. -I$(topdir) -I$(topdir)/lib -I$(topdir)/builtins -I${srcdir} \
 ALLPROG = print truefalse sleep finfo logname basename dirname fdflags \
          tty pathchk tee head mkdir rmdir mkfifo mktemp printenv id whoami \
          uname sync push ln unlink realpath strftime mypid setpgid seq rm \
-         accept csv cut stat getconf
+         accept csv dsv cut stat getconf
 OTHERPROG = necho hello cat pushd asort
 
 all:   $(SHOBJ_STATUS)
@@ -222,6 +222,9 @@ realpath:   realpath.o
 csv:   csv.o
        $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ csv.o $(SHOBJ_LIBS)
 
+dsv:   dsv.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ dsv.o $(SHOBJ_LIBS)
+
 cut:   cut.o
        $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ cut.o $(SHOBJ_LIBS)
 
@@ -313,6 +316,7 @@ necho.o: necho.c
 hello.o: hello.c
 cat.o: cat.c
 csv.o: csv.c
+dsv.o: dsv.c
 cut.o: cut.c
 printenv.o: printenv.c
 id.o: id.c
diff --git a/examples/loadables/dsv.c b/examples/loadables/dsv.c
new file mode 100644 (file)
index 0000000..70e59cb
--- /dev/null
@@ -0,0 +1,300 @@
+/* dsv - process a line of delimiter-separated data and populate an indexed
+        array with the fields */
+
+/*
+   Copyright (C) 2022 Free Software Foundation, Inc.
+
+   Bash is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   Bash is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with Bash.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* See Makefile for compilation details. */
+
+#include <config.h>
+
+#if defined (HAVE_UNISTD_H)
+#  include <unistd.h>
+#endif
+#include "bashansi.h"
+#include <stdio.h>
+
+#include "loadables.h"
+
+#define DSV_ARRAY_DEFAULT      "DSV"
+
+#define NQUOTE 0
+#define DQUOTE 1
+#define SQUOTE 2
+
+#define F_SHELLQUOTE   0x01
+#define F_GREEDY       0x02
+#define F_PRESERVE     0x04
+
+/* Split LINE into delimiter-separated fields, storing each field into a
+   separate element of array variable DSV, starting at index 0. The format
+   of LINE is delimiter-separated values. By default, this splits lines of
+   CSV data as described in RFC 4180. If *DSTRING is any other value than
+   ',', this uses that character as a field delimiter. Pass F_SHELLQUOTE in
+   FLAGS to understand shell-like double-quoting and backslash-escaping in
+   double quotes instead of the "" CSV behavior, and shell-like single quotes.
+   Pass F_GREEDY in FLAGS to consume multiple leading and trailing instances
+   of *DSTRING and consecutive instances of *DSTRING in LINE without creating
+   null fields. If you want to preserve the quote characters in the generated
+   fields, pass F_PRESERVE; by default, this removes them. */
+static int
+dsvsplit (dsv, line, dstring, flags)
+     SHELL_VAR *dsv;
+     char *line, *dstring;
+     int flags;
+{
+  arrayind_t ind;
+  char *field, *prev, *buf, *xbuf;
+  int delim, qstate;
+  int b, rval;
+
+  xbuf = 0;
+  ind = 0;
+  field = prev = line;
+
+  /* If we want a greedy split, consume leading instances of *DSTRING */
+  if (flags & F_GREEDY)
+    {
+      while (*prev == *dstring)
+       prev++;
+      field = prev;
+    }
+
+  do
+    {
+      if (*prev == '"')
+       {
+         if (xbuf == 0)
+           xbuf = xmalloc (strlen (prev) + 1);
+         buf = xbuf;
+         b = 0;
+         if (flags & F_PRESERVE)
+           buf[b++] = *prev;
+         qstate = DQUOTE;
+         for (field = ++prev; *field; field++)
+           {
+             if (qstate == DQUOTE && *field == '"' && field[1] == '"' && (flags & F_SHELLQUOTE) == 0)
+               buf[b++] = *field++;    /* skip double quote */
+             else if (qstate == DQUOTE && (flags & F_SHELLQUOTE) && *field == '\\' && strchr (slashify_in_quotes, field[1]) != 0)
+               buf[b++] = *++field;    /* backslash quoted double quote */
+             else if (qstate == DQUOTE && *field == '"')
+               {
+                 qstate = NQUOTE;
+                 if (flags & F_PRESERVE)
+                   buf[b++] = *field;
+               }
+             else if (qstate == NQUOTE && *field == *dstring)
+               break;
+             else
+               /* This copies any text between a closing double quote and the
+                  delimiter. If you want to change that, make sure to do the
+                  copy only if qstate == DQUOTE. */
+               buf[b++] = *field;
+           }
+         buf[b] = '\0';
+       }
+      else if ((flags & F_SHELLQUOTE) && *prev == '\'')
+       {
+         if (xbuf == 0)
+           xbuf = xmalloc (strlen (prev) + 1);
+         buf = xbuf;
+         b = 0;
+         if (flags & F_PRESERVE)
+           buf[b++] = *prev;
+         qstate = SQUOTE;
+         for (field = ++prev; *field; field++)
+           {
+             if (qstate == SQUOTE && *field == '\'')
+               {
+                 qstate = NQUOTE;
+                 if (flags & F_PRESERVE)
+                   buf[b++] = *field;
+               }
+             else if (qstate == NQUOTE && *field == *dstring)
+               break;
+             else
+               /* This copies any text between a closing single quote and the
+                  delimiter. If you want to change that, make sure to do the
+                  copy only if qstate == SQUOTE. */
+               buf[b++] = *field;
+           }
+         buf[b] = '\0';
+       }
+      else
+       {
+         buf = prev;
+         field = prev + strcspn (prev, dstring);
+       }
+
+      delim = *field;
+      *field = '\0';
+
+      if ((flags & F_GREEDY) == 0 || buf[0])
+       {
+         bind_array_element (dsv, ind, buf, 0);
+         ind++;
+       }
+
+      *field = delim;
+
+      if (delim == *dstring)
+       prev = field + 1;
+    }
+  while (delim == *dstring);
+
+  if (xbuf)
+    free (xbuf);
+
+  return (rval = ind);                         /* number of fields */
+}
+
+int
+dsv_builtin (list)
+     WORD_LIST *list;
+{
+  int opt, rval, flags;
+  char *array_name, *dsvstring, *delims;
+  SHELL_VAR *v;
+
+  array_name = 0;
+  rval = EXECUTION_SUCCESS;
+
+  delims = ",";
+  flags = 0;
+
+  reset_internal_getopt ();
+  while ((opt = internal_getopt (list, "a:d:Sgp")) != -1)
+    {
+      switch (opt)
+       {
+       case 'a':
+         array_name = list_optarg;
+         break;
+       case 'd':
+         delims = list_optarg;
+         break;
+       case 'S':
+         flags |= F_SHELLQUOTE;
+         break;
+       case 'g':
+         flags |= F_GREEDY;
+         break;
+       case 'p':
+         flags |= F_PRESERVE;
+         break;
+       CASE_HELPOPT;
+       default:
+         builtin_usage ();
+         return (EX_USAGE);
+       }
+    }
+  list = loptend;
+
+  if (array_name == 0)
+    array_name = DSV_ARRAY_DEFAULT;
+
+  if (legal_identifier (array_name) == 0)
+    {
+      sh_invalidid (array_name);
+      return (EXECUTION_FAILURE);
+    }
+
+  if (list == 0)
+    {
+      builtin_error ("dsv string argument required");
+      return (EX_USAGE);
+    }
+
+  v = find_or_make_array_variable (array_name, 1);
+  if (v == 0 || readonly_p (v) || noassign_p (v))
+    {
+      if (v && readonly_p (v))
+       err_readonly (array_name);
+      return (EXECUTION_FAILURE);
+    }
+  else if (array_p (v) == 0)
+    {
+      builtin_error ("%s: not an indexed array", array_name);
+      return (EXECUTION_FAILURE);
+    }
+  if (invisible_p (v))
+    VUNSETATTR (v, att_invisible);
+  array_flush (array_cell (v));
+
+  dsvstring = list->word->word;
+
+  if (dsvstring == 0 || *dsvstring == 0)
+    return (EXECUTION_SUCCESS);
+
+  opt = dsvsplit (v, dsvstring, delims, flags);
+  /* Maybe do something with OPT here, it's the number of fields */
+
+  return (rval);
+}
+
+/* Called when builtin is enabled and loaded from the shared object.  If this
+   function returns 0, the load fails. */
+int
+dsv_builtin_load (name)
+     char *name;
+{
+  return (1);
+}
+
+/* Called when builtin is disabled. */
+void
+dsv_builtin_unload (name)
+     char *name;
+{
+}
+
+char *dsv_doc[] = {
+       "Read delimiter-separated fields from STRING.",
+       "",     
+       "Parse STRING, a line of delimiter-separated values, into individual",
+       "fields, and store them into the indexed array ARRAYNAME starting at",
+       "index 0. The parsing understands and skips over double-quoted strings. ",
+       "If ARRAYNAME is not supplied, \"DSV\" is the default array name.",
+       "If the delimiter is a comma, the default, this parses comma-",
+       "separated values as specified in RFC 4180.",
+       "",
+       "The -d option specifies the delimiter. The delimiter is the first",
+       "character of the DELIMS argument. Specifying a DELIMS argument that",
+       "contains more than one character is not supported and will produce",
+       "unexpected results. The -S option enables shell-like quoting: double-",
+       "quoted strings can contain backslashes preceding special characters,",
+       "and the backslash will be removed; and single-quoted strings are",
+       "processed as the shell would process them. The -g option enables a",
+       "greedy split: sequences of the delimiter are skipped at the beginning",
+       "and end of STRING, and consecutive instances of the delimiter in STRING",
+       "do not generate empty fields. If the -p option is supplied, dsv leaves",
+       "quote characters as part of the generated field; otherwise they are",
+       "removed.",
+       "",
+       "The return value is 0 unless an invalid option is supplied or the ARRAYNAME",
+       "argument is invalid or readonly.",
+       (char *)NULL
+};
+
+struct builtin dsv_struct = {
+       "dsv",                  /* builtin name */
+       dsv_builtin,            /* function implementing the builtin */
+       BUILTIN_ENABLED,        /* initial flags for builtin */
+       dsv_doc,                /* array of long documentation strings. */
+       "dsv [-a ARRAYNAME] [-d DELIMS] [-Sgp] string", /* usage synopsis; becomes short_doc */
+       0                       /* reserved for internal use */
+};
index d0d1dd31e228b78660ccf5ef61b3b9706cfcea38..e5c6b9ab79431b248ac4b3c1ddcb7ad7a657980f 100644 (file)
@@ -3918,11 +3918,15 @@ execute_cond_node (cond)
        arg1 = nullstr;
       if (echo_command_at_execute)
        xtrace_print_cond_term (cond->type, invert, cond->op, arg1, (char *)NULL);
+#if defined (ARRAY_VARS)
       if (varop)
        oa = set_expand_once (0, 0);    /* no-op for compatibility levels <= 51 */
+#endif
       result = unary_test (cond->op->word, arg1, varflag) ? EXECUTION_SUCCESS : EXECUTION_FAILURE;
+#if defined (ARRAY_VARS)
       if (varop)
        assoc_expand_once = oa;
+#endif
       if (arg1 != nullstr)
        free (arg1);
     }
index 67805ed0d5e1bc4eaee6fd4f9457be0dfbadb0ee..dd76e9fcb7c5bccba1726b00d411343600ab71c7 100644 (file)
@@ -1,6 +1,6 @@
 /* setlinebuf.c - line-buffer a stdio stream. */
 
-/* Copyright (C) 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1997,2022 Free Software Foundation, Inc.
 
    This file is part of GNU Bash, the Bourne Again SHell.
 
 #include <xmalloc.h>
 
 #if defined (USING_BASH_MALLOC)
-#  define LBUF_BUFSIZE 1008
+#  define LBUF_BUFSIZE 2016
 #else
 #  define LBUF_BUFSIZE BUFSIZ
 #endif
 
+static char *stdoutbuf = 0;
+static char *stderrbuf = 0;
+
 /* Cause STREAM to buffer lines as opposed to characters or blocks. */
 int
 sh_setlinebuf (stream)
      FILE *stream;
 {
-  char *local_linebuf;
-
 #if !defined (HAVE_SETLINEBUF) && !defined (HAVE_SETVBUF)
   return (0);
 #endif
 
+#if defined (HAVE_SETVBUF)
+  char *local_linebuf;
+
 #if defined (USING_BASH_MALLOC)
-  local_linebuf = (char *)xmalloc (LBUF_BUFSIZE);
+  if (stream == stdout && stdoutbuf == 0)
+    local_linebuf = stdoutbuf = (char *)xmalloc (LBUF_BUFSIZE);
+  else if (stream == stderr && stderrbuf == 0)
+    local_linebuf = stderrbuf = (char *)xmalloc (LBUF_BUFSIZE);
+  else
+    local_linebuf = (char *)NULL;      /* let stdio handle it */
 #else
   local_linebuf = (char *)NULL;
 #endif
 
-#if defined (HAVE_SETVBUF)
   return (setvbuf (stream, local_linebuf, _IOLBF, LBUF_BUFSIZE));
-# else /* !HAVE_SETVBUF */
+#else /* !HAVE_SETVBUF */
 
   setlinebuf (stream);
   return (0);