commit bash-20190322 snapshot

This commit is contained in:
Chet Ramey
2019-03-25 09:36:24 -04:00
parent 6e5013142b
commit 31321bf1b2
13 changed files with 251 additions and 147 deletions
+32
View 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>
+4
View 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
+6 -1
View 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));
+6 -6
View 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
+5 -4
View 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.
+3 -3
View 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
-1
View 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;
+1 -9
View 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;
}
+129 -121
View File
@@ -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;
WORD_DESC *redirectee;
{
char *herestr;
int herelen, n, e, old;
/* 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 *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. */
static int
write_here_document (fd, redirectee)
int fd;
WORD_DESC *redirectee;
{
char *document;
int document_len, fd2, old;
FILE *fp;
register WORD_LIST *t, *tlist;
/* 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. */
if (redirectee->flags & W_QUOTED)
{
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;
}
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)
{
/* 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)
{
/* 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);
}
}
dispose_words (tlist);
if (fclose (fp) != 0)
{
if (errno == 0)
errno = ENOSPC;
return (errno);
}
}
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. */
/* 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
here_document_to_fd (redirectee, ri)
WORD_DESC *redirectee;
enum r_instruction ri;
{
char *filename;
int r, fd, fd2;
int r, fd, fd2, herepipe[2];
char *document;
size_t document_len;
/* Expand the here-document/here-string first and then decide what to do. */
document = heredoc_expand (redirectee, ri, &document_len);
/* If we have a zero-length document, don't mess with a temp file */
if (document_len == 0)
{
fd = open ("/dev/null", O_RDONLY);
r = errno;
if (document != redirectee->word)
FREE (document);
errno = r;
return fd;
}
#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)
{
if (pipe (herepipe) < 0)
{
r = errno;
if (document != redirectee->word)
free (document);
errno = r;
return (-1);
}
r = heredoc_write (herepipe[1], document, document_len);
if (document != redirectee->word)
free (document);
close (herepipe[1]);
if (r) /* write error */
{
close (herepipe[0]);
errno = r;
return (-1);
}
return (herepipe[0]);
}
#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)
{
+9 -1
View 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
+29 -1
View 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
+7
View File
@@ -1,3 +1,10 @@
alpha
beta
4
4
abcde
yo
hot damn
+20
View 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()