mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-07-04 10:50:50 +02:00
commit bash-20200408 snapshot
This commit is contained in:
@@ -7921,3 +7921,30 @@ execute_cmd.c
|
||||
- execute_in_subshell,execute_simple_command,execute_disk_command:
|
||||
remove calls to CHECK_SIGTERM, since we don't install a handler
|
||||
any more
|
||||
|
||||
lib/readline/readline.c
|
||||
- _rl_enable_bracketed_paste: enabled by default for the time being
|
||||
|
||||
4/9
|
||||
---
|
||||
jobs.h
|
||||
- JWAIT_WAITING: new flag for wait functions; means only wait for jobs
|
||||
with the J_WAITING flag set
|
||||
- J_WAITING: new job flag, part of arg list to `wait -n'
|
||||
- IS_WAITING(i): job i has the J_WAITING flag set
|
||||
|
||||
jobs.c
|
||||
- wait_for_any_job: if the flags includes JWAIT_WAITING, we only return
|
||||
jobs with the J_WAITING flag already set; otherwise we skip them.
|
||||
For `wait -n args' support
|
||||
|
||||
builtins/wait.def
|
||||
- set_waitlist: take a list of jobspecs and set the J_WAITING flag in
|
||||
each valid job from the list
|
||||
- unset_waitlist: turn off the J_WAITING flag for all jobs where it's
|
||||
set
|
||||
- wait_builtin: if -n is supplied with a list of arguments, set the
|
||||
J_WAITING flag in each job in the list, call wait_for_any_job with
|
||||
the JWAIT_WAITING flag, and clean up by calling unset_waitlist().
|
||||
From a suggestion from Robert Elz <kre@munnari.oz.au> back in 3/2019
|
||||
(originally in 10/2017)
|
||||
|
||||
+1
-1
@@ -4161,7 +4161,7 @@ set_filename_bstab (string)
|
||||
|
||||
memset (filename_bstab, 0, sizeof (filename_bstab));
|
||||
for (s = string; s && *s; s++)
|
||||
filename_bstab[*s] = 1;
|
||||
filename_bstab[(unsigned char)*s] = 1;
|
||||
}
|
||||
|
||||
/* Quote a filename using double quotes, single quotes, or backslashes
|
||||
|
||||
+75
-4
@@ -1,7 +1,7 @@
|
||||
This file is wait.def, from which is created wait.c.
|
||||
It implements the builtin "wait" in Bash.
|
||||
|
||||
Copyright (C) 1987-2019 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -31,8 +31,9 @@ given, waits for all currently active child processes, and the return
|
||||
status is zero. If ID is a job specification, waits for all processes
|
||||
in that job's pipeline.
|
||||
|
||||
If the -n option is supplied, waits for the next job to terminate and
|
||||
returns its exit status.
|
||||
If the -n option is supplied, waits for a single job from the list of IDs,
|
||||
or, if no IDs are supplied, for the next job to complete and returns its
|
||||
exit status.
|
||||
|
||||
If the -p option is supplied, the process or job identifier of the job
|
||||
for which the exit status is returned is assigned to the variable VAR
|
||||
@@ -44,7 +45,8 @@ specified ID to terminate, instead of waiting for it to change status.
|
||||
|
||||
Exit Status:
|
||||
Returns the status of the last ID; fails if ID is invalid or an invalid
|
||||
option is given.
|
||||
option is given, or if -n is supplied and the shell has no unwaited-for
|
||||
children.
|
||||
$END
|
||||
|
||||
$BUILTIN wait
|
||||
@@ -79,6 +81,7 @@ $END
|
||||
#include "../execute_cmd.h"
|
||||
#include "../jobs.h"
|
||||
#include "../trap.h"
|
||||
#include "../sig.h"
|
||||
#include "common.h"
|
||||
#include "bashgetopt.h"
|
||||
|
||||
@@ -87,6 +90,9 @@ extern int wait_signal_received;
|
||||
procenv_t wait_intr_buf;
|
||||
int wait_intr_flag;
|
||||
|
||||
static int set_waitlist PARAMS((WORD_LIST *));
|
||||
static void unset_waitlist PARAMS((void));
|
||||
|
||||
/* Wait for the pid in LIST to stop or die. If no arguments are given, then
|
||||
wait for all of the active background processes of the shell and return
|
||||
0. If a list of pids or job specs are given, return the exit status of
|
||||
@@ -198,11 +204,22 @@ wait_builtin (list)
|
||||
#if defined (JOB_CONTROL)
|
||||
if (nflag)
|
||||
{
|
||||
if (list)
|
||||
{
|
||||
opt = set_waitlist (list);
|
||||
if (opt == 0)
|
||||
WAIT_RETURN (127);
|
||||
wflags |= JWAIT_WAITING;
|
||||
}
|
||||
|
||||
status = wait_for_any_job (wflags, &pstat);
|
||||
if (status < 0)
|
||||
status = 127;
|
||||
|
||||
if (vname && status >= 0)
|
||||
bind_var_to_int (vname, pstat.pid);
|
||||
if (list)
|
||||
unset_waitlist ();
|
||||
WAIT_RETURN (status);
|
||||
}
|
||||
#endif
|
||||
@@ -291,3 +308,57 @@ wait_builtin (list)
|
||||
|
||||
WAIT_RETURN (status);
|
||||
}
|
||||
|
||||
#if defined (JOB_CONTROL)
|
||||
/* Take each valid pid or jobspec in LIST and mark the corresponding job as
|
||||
J_WAITING, so wait -n knows which jobs to wait for. Return the number of
|
||||
jobs we found. */
|
||||
static int
|
||||
set_waitlist (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
sigset_t set, oset;
|
||||
int job, r, njob;
|
||||
intmax_t pid;
|
||||
WORD_LIST *l;
|
||||
|
||||
BLOCK_CHILD (set, oset);
|
||||
njob = 0;
|
||||
for (l = list; l; l = l->next)
|
||||
{
|
||||
job = NO_JOB;
|
||||
job = (l && legal_number (l->word->word, &pid) && pid == (pid_t) pid)
|
||||
? get_job_by_pid ((pid_t) pid, 0, 0)
|
||||
: get_job_spec (l);
|
||||
if (job == NO_JOB || jobs == 0 || INVALID_JOB (job))
|
||||
{
|
||||
sh_badjob (l->word->word);
|
||||
continue;
|
||||
}
|
||||
/* We don't check yet to see if one of the desired jobs has already
|
||||
terminated, but we could. We wait until wait_for_any_job(). This
|
||||
has the advantage of validating all the arguments. */
|
||||
if ((jobs[job]->flags & J_WAITING) == 0)
|
||||
{
|
||||
njob++;
|
||||
jobs[job]->flags |= J_WAITING;
|
||||
}
|
||||
}
|
||||
UNBLOCK_CHILD (oset);
|
||||
return (njob);
|
||||
}
|
||||
|
||||
/* Clean up after a call to wait -n jobs */
|
||||
static void
|
||||
unset_waitlist ()
|
||||
{
|
||||
int i;
|
||||
sigset_t set, oset;
|
||||
|
||||
BLOCK_CHILD (set, oset);
|
||||
for (i = 0; i < js.j_jobslots; i++)
|
||||
if (jobs[i] && (jobs[i]->flags & J_WAITING))
|
||||
jobs[i]->flags &= ~J_WAITING;
|
||||
UNBLOCK_CHILD (oset);
|
||||
}
|
||||
#endif
|
||||
|
||||
+9
-4
@@ -5,12 +5,12 @@
|
||||
.\" Case Western Reserve University
|
||||
.\" chet.ramey@case.edu
|
||||
.\"
|
||||
.\" Last Change: Tue Mar 24 16:38:43 EDT 2020
|
||||
.\" Last Change: Thu Apr 9 11:50:30 EDT 2020
|
||||
.\"
|
||||
.\" bash_builtins, strip all but Built-Ins section
|
||||
.if \n(zZ=1 .ig zZ
|
||||
.if \n(zY=1 .ig zY
|
||||
.TH BASH 1 "2020 March 24" "GNU Bash 5.0"
|
||||
.TH BASH 1 "2020 April 9" "GNU Bash 5.0"
|
||||
.\"
|
||||
.\" There's some problem with having a `@'
|
||||
.\" in a tagged paragraph with the BSD man macros.
|
||||
@@ -10863,8 +10863,13 @@ is not given,
|
||||
the last-executed process substitution, if its process id is the same as
|
||||
\fB$!\fP,
|
||||
and the return status is zero.
|
||||
If the \fB\-n\fP option is supplied, \fBwait\fP waits for a single job
|
||||
to terminate and returns its exit status.
|
||||
If the \fB\-n\fP option is supplied,
|
||||
\fBwait\fP waits for a single job
|
||||
from the list of \fIid\fPs or, if no \fIid\fPs are supplied, any job,
|
||||
to complete and returns its exit status.
|
||||
If none of the supplied arguments is a child of the shell, or if no arguments
|
||||
are supplied and the shell has no unwaited-for children, the exit status
|
||||
is 127.
|
||||
If the \fB\-p\fP option is supplied, the process or job identifier of the job
|
||||
for which the exit status is returned is assigned to the variable
|
||||
\fIvarname\fP named by the option argument.
|
||||
|
||||
+6
-1
@@ -8227,7 +8227,12 @@ the last-executed process substitution, if its process id is the same as
|
||||
@var{$!},
|
||||
and the return status is zero.
|
||||
If the @option{-n} option is supplied, @code{wait} waits for a single job
|
||||
to terminate and returns its exit status.
|
||||
from the list of @var{pids} or @var{jobspecs} or, if no arguments are
|
||||
supplied, any job,
|
||||
to complete and returns its exit status.
|
||||
If none of the supplied arguments is a child of the shell, or if no arguments
|
||||
are supplied and the shell has no unwaited-for children, the exit status
|
||||
is 127.
|
||||
If the @option{-p} option is supplied, the process or job identifier of the job
|
||||
for which the exit status is returned is assigned to the variable
|
||||
@var{varname} named by the option argument.
|
||||
|
||||
+3
-3
@@ -2,10 +2,10 @@
|
||||
Copyright (C) 1988-2020 Free Software Foundation, Inc.
|
||||
@end ignore
|
||||
|
||||
@set LASTCHANGE Tue Mar 24 16:38:56 EDT 2020
|
||||
@set LASTCHANGE Thu Apr 9 11:58:06 EDT 2020
|
||||
|
||||
@set EDITION 5.0
|
||||
@set VERSION 5.0
|
||||
|
||||
@set UPDATED 24 March 2020
|
||||
@set UPDATED-MONTH March 2020
|
||||
@set UPDATED 9 April 2020
|
||||
@set UPDATED-MONTH April 2020
|
||||
|
||||
@@ -3286,6 +3286,8 @@ wait_for_any_job (flags, ps)
|
||||
BLOCK_CHILD (set, oset);
|
||||
for (i = 0; i < js.j_jobslots; i++)
|
||||
{
|
||||
if ((flags & JWAIT_WAITING) && jobs[i] && IS_WAITING (i) == 0)
|
||||
continue; /* if we don't want it, skip it */
|
||||
if (jobs[i] && DEADJOB (i) && IS_NOTIFIED (i) == 0)
|
||||
{
|
||||
return_job:
|
||||
@@ -3336,8 +3338,12 @@ return_job:
|
||||
/* Now we see if we have any dead jobs and return the first one */
|
||||
BLOCK_CHILD (set, oset);
|
||||
for (i = 0; i < js.j_jobslots; i++)
|
||||
if (jobs[i] && DEADJOB (i))
|
||||
goto return_job;
|
||||
{
|
||||
if ((flags & JWAIT_WAITING) && jobs[i] && IS_WAITING (i) == 0)
|
||||
continue; /* if we don't want it, skip it */
|
||||
if (jobs[i] && DEADJOB (i))
|
||||
goto return_job;
|
||||
}
|
||||
UNBLOCK_CHILD (oset);
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#define JWAIT_PERROR 0x01
|
||||
#define JWAIT_FORCE 0x02
|
||||
#define JWAIT_NOWAIT 0x04 /* don't waitpid(), just return status if already exited */
|
||||
#define JWAIT_WAITING 0x08 /* wait for jobs marked J_WAITING only */
|
||||
|
||||
/* The max time to sleep while retrying fork() on EAGAIN failure */
|
||||
#define FORKSLEEP_MAX 16
|
||||
@@ -105,11 +106,13 @@ typedef enum { JNONE = -1, JRUNNING = 1, JSTOPPED = 2, JDEAD = 4, JMIXED = 8 } J
|
||||
#define J_STATSAVED 0x10 /* A process in this job had status saved via $! */
|
||||
#define J_ASYNC 0x20 /* Job was started asynchronously */
|
||||
#define J_PIPEFAIL 0x40 /* pipefail set when job was started */
|
||||
#define J_WAITING 0x80 /* one of a list of jobs for which we are waiting */
|
||||
|
||||
#define IS_FOREGROUND(j) ((jobs[j]->flags & J_FOREGROUND) != 0)
|
||||
#define IS_NOTIFIED(j) ((jobs[j]->flags & J_NOTIFIED) != 0)
|
||||
#define IS_JOBCONTROL(j) ((jobs[j]->flags & J_JOBCONTROL) != 0)
|
||||
#define IS_ASYNC(j) ((jobs[j]->flags & J_ASYNC) != 0)
|
||||
#define IS_WAITING(j) ((jobs[j]->flags & J_WAITING) != 0)
|
||||
|
||||
typedef struct job {
|
||||
char *wd; /* The working directory at time of invocation. */
|
||||
|
||||
@@ -1375,9 +1375,12 @@ bind_bracketed_paste_prefix (void)
|
||||
|
||||
_rl_keymap = emacs_standard_keymap;
|
||||
rl_bind_keyseq_if_unbound (BRACK_PASTE_PREF, rl_bracketed_paste_begin);
|
||||
|
||||
|
||||
#if defined (VI_MODE)
|
||||
_rl_keymap = vi_insertion_keymap;
|
||||
rl_bind_keyseq_if_unbound (BRACK_PASTE_PREF, rl_bracketed_paste_begin);
|
||||
/* XXX - is there a reason to do this in the vi command keymap? */
|
||||
#endif
|
||||
|
||||
_rl_keymap = xkeymap;
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
BUILD_DIR=/usr/local/build/chet/bash/bash-current
|
||||
BUILD_DIR=/usr/local/build/bash/bash-current
|
||||
THIS_SH=$BUILD_DIR/bash
|
||||
PATH=$PATH:$BUILD_DIR
|
||||
|
||||
|
||||
@@ -27,6 +27,10 @@ i killed it
|
||||
12
|
||||
[1]- Running sleep 20 &
|
||||
[3]+ Running sleep 20 &
|
||||
5: ok 1
|
||||
./jobs5.sub: line 40: wait: %8: no such job
|
||||
2: ok 2
|
||||
2: ok 3
|
||||
child1 exit status 0
|
||||
0
|
||||
./jobs.tests: line 38: wait: %1: no such job
|
||||
|
||||
+50
-1
@@ -1,12 +1,61 @@
|
||||
# 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
# framework to test new `wait -n' option that waits for any job to finish
|
||||
|
||||
set -m
|
||||
|
||||
sleep 20 &
|
||||
{ sleep 5; exit 12; } &
|
||||
{ sleep 2; exit 12; } &
|
||||
sleep 20 &
|
||||
|
||||
wait -n
|
||||
echo $?
|
||||
|
||||
jobs
|
||||
disown -a
|
||||
|
||||
{ sleep 1 ; exit 4; } &
|
||||
{ sleep 2 ; exit 5; } & bgpid1=$!
|
||||
{ sleep 4 ; exit 6; } &
|
||||
|
||||
wait -p wvar -n %2 %3
|
||||
case "$wvar" in
|
||||
$bgpid1) echo $?: ok 1;;
|
||||
*) echo bad 1;;
|
||||
esac
|
||||
|
||||
{ sleep 1 ; exit 2; } & bgpid2=$!
|
||||
wait -p wvar -n %8 $!
|
||||
case $wvar in
|
||||
$bgpid2) echo $?: ok 2;;
|
||||
*) echo bad 2;;
|
||||
esac
|
||||
|
||||
disown -a
|
||||
|
||||
{ sleep 3; exit 1; } & { sleep 1; exit 2; } & bgpid3=$!
|
||||
{ sleep 3; exit 3; } & { sleep 3; exit 4; } &
|
||||
|
||||
wait -n -p wpid %1 %2 %3 %4
|
||||
|
||||
case $wpid in
|
||||
$bgpid3) echo $?: ok 3;;
|
||||
*) echo bad 3 ;;
|
||||
esac
|
||||
|
||||
disown -a
|
||||
|
||||
unset bgpid1 bgpid2 bgpid3
|
||||
unset wpid
|
||||
|
||||
Reference in New Issue
Block a user