Home | History | Annotate | Download | only in sh
History log of /src/bin/sh/jobs.h
RevisionDateAuthorComments
 1.27  15-Jun-2024  kre POSIX.1-2024 requires that when an async (background) job is started
at the top level (ie: not in any kind of subshell environment) of an
interactive shell, that the shell print the job number assigned, and
the process id of the lead (or only) process in the job, in the form:

[JN] pid

Make that happen. (Other shells have been doing this for ages).
 1.26  07-Apr-2023  kre The great shell trailing whitespace cleanup of 2023...
Inspired by private e-mail comments from mouse@

NFCI.
 1.25  11-Sep-2021  christos Add jobs -Z (like in zsh(1)) to setproctitle(3).
 1.24  04-Apr-2021  kre Related to PR bin/48875

Correct an issue found by Oguz <oguzismailuysal@gmail.com> and reported
in e-mail (on the bug-bash list initially!) with the code changed to deal
with PR bin/48875

With:

sh -c 'echo start at $SECONDS;
(sleep 3 & (sleep 1& wait) );
echo end at $SECONDS'

The shell should say "start at 0\nend at 1\n", but instead (before
this fix, in -9 and HEAD, but not -8) does "start at 0\nend at 3\n"
(Not in -8 as the 48875 changes were never pulled up)>

There was an old problem, fixed years ago, which cause the same symptom,
related to the way the jobs table was cleared (or not) in subshells, and
it seemed like that might have resurfaced.

But not so, the issue here is the sub-shell elimination, which was part
of the 48875 "fix" (not really, it wasn't really a bug, just sub-optimal
and unexpected behaviour).

What the shell actually has been running in this case is:

sh -c 'echo start at $SECONDS;
(sleep 3 & sleep 1& wait );
echo end at $SECONDS'

as the inner subshell was deemed unnecessary - all its parent would
do is wait for its exit status, and then exit with that status - we
may as well simply replace the current sub-shell with the new one,
let it do its thing, and we're done...

But not here, the running "sleep 3" will remain a child of that merged
sub-shell, and the "wait" will thus wait for it, along with the sleep 1
which is all it should be seeing.

For now, fix this by not eliminating a sub-shell if there are existing
unwaited upon children in the current one. It might be possible to
simply disregard the old child for the purposes of wait (and "jobs", etc,
all cmds which look at the jobs table) but the bookkeeping required to
make that work reliably is likely to take some time to get correct...

Along with this fix comes a fix to DEBUG mode shells, which, in situations
like this, could dump core in the debug code if the relevant tracing was
enabled, and add a new trace for when the jobs table is cleared (which was
added predating the discovery of the actual cause of this issue, but seems
worth keeping.) Neither of these changes have any effect on shells
compiled normally.

XXX pullup -9
 1.23  11-Sep-2018  kre branches: 1.23.2;

Whitespace cleanup from last update. NFC.
 1.22  04-Sep-2018  kre Change the way the pipefail option works. Now it is the setting of
the option when a pipeline is created that controls the way the exit
status of the pipeline is calculated. Previously it was the state of
the option when the exit status of the pipeline was collected.

This makes no difference at all for foreground pipelines (there is
no way to change the option between starting and completing the
pipeline) but it does for asynchronous (background) pipelines.

This was always the right way to implement it - it was originally
done the other way as I could not find any other shell implemented
this way - they all seemed to do it our previous way, and I could
not see a good reason to be the sole different shell.

However, now I know that ksh93 works as we will now work, and I
am told that if the option is added to the FreeBSD shell (apparently
the code exists, uncommitted) it will be the same.
 1.21  28-Oct-2017  kre branches: 1.21.2; 1.21.4;
Add '-n' and '-p var' args to the wait command (-n: wait for any,
-p var: set var to identifier, from arg list, or PID if no job args)
of the job for which status is returned (becomes $? after wait.)

Note: var is unset if the status returned from wait came from wait
itself rather than from some job exiting (so it is now possible to
tell whether 127 means "no such job" or "job did exit(127)", and
whether $? > 128 means "wait was interrupted" or "job was killed
by a signal or did exit(>128)". ($? is too limited to to allow
indicating whether the job died with a signal, or exited with a
status such that it looks like it did...)
 1.20  18-Jun-2011  christos PR/45069: Henning Petersen: Use prototypes from builtins.h .
 1.19  27-Nov-2003  dsl branches: 1.19.52;
Generate command line when SMALL is defined and make buffer full sized.
All the code has been present for a while, and the memory cost is (about)
180 bytes per process.
Fixes PR bin/23545
 1.18  07-Aug-2003  agc Move UCB-licensed code from 4-clause to 3-clause licence.

Patches provided by Joel Baker in PR 22249, verified by myself.
 1.17  22-Jan-2003  dsl Support command -p, -v and -V as posix
Stop temporary PATH assigments messing up hash table
Fix sh -c -e "echo $0 $*" -a x (as posix)
(agreed by christos)
 1.16  24-Nov-2002  christos Fixes from David Laight:
- ansification
- format of output of jobs command (etc)
- job identiers %+, %- etc
- $? and $(...)
- correct quoting of output of set, export -p and readonly -p
- differentiation between nornal and 'posix special' builtins
- correct behaviour (posix) for errors on builtins and special builtins
- builtin printf and kill
- set -o debug (if compiled with DEBUG)
- cd src obj (as ksh - too useful to do without)
- unset -e name, remove non-readonly variable from export list.
(so I could unset -e PS1 before running the test shell...)
 1.15  28-Sep-2002  christos Revert previous change. No need to save rootshell. It is only affecting
the non-vfork case. Having said that, it would be nice if pipelines of
simple commands were vforked too. Right now they are not.
Explain that setpgid() might fail because we are doing it both in the
parent and the child case, because we don't know which one will come
first.
Suspending a pipeline prints %1 Suspended n times where n is the number
of processes, but that was there before. It is easy to fix, but I'll
leave the code alone for now.
 1.14  27-Sep-2002  christos Deal with rootshell not being maintained correctly in the vfork() case.
Propagate isroot, throughout the eval process and maintain it properly.
Fixes sleep 10 | cat^C not exiting because sleep and cat ended up in
their own process groups, because wasroot was always true in the children.
 1.13  27-Sep-2002  christos VFork()ing shell: From elric@netbsd.org:
Plus my changes:
- walking process group fix in foregrounding a job.
- reset of process group in parent shell if interrupted before the wait.
- move INTON lower in the dowait so that the job structure is
consistent.
- error check all setpgid(), tcsetpgrp() calls.
- eliminate unneeded strpgid() call.
- check that we don't belong in the process group before we try to
set it.
 1.12  22-May-2000  elric branches: 1.12.6;
Back out previous vfork changes.
 1.11  13-May-2000  elric Quick fix.

jobs.h:91: warning: declaration of `vfork' shadows global declaration
 1.10  13-May-2000  elric Now we use vfork(2) instead of fork(2) when we can.
 1.9  15-Oct-1997  christos pid should be pid_t and status should be int! Avoid alignment problems...
 1.8  11-May-1995  christos Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.7  21-Mar-1995  cgd convert to new RCS id conventions.
 1.6  11-Jun-1994  mycroft Add RCS ids.
 1.5  11-May-1994  jtc sync with 4.4lite
 1.4  01-Aug-1993  mycroft Add RCS identifiers.
 1.3  23-Mar-1993  cgd changed "Id" to "Header" for rcsids
 1.2  22-Mar-1993  cgd added rcs ids to all files
 1.1  21-Mar-1993  cgd branches: 1.1.1;
Initial revision
 1.1.1.2  11-May-1994  jtc 44lite code
 1.1.1.1  21-Mar-1993  cgd initial import of 386bsd-0.1 sources
 1.12.6.1  27-Mar-2002  elric Doing the vfork work on ash on a branch to try to shake out the
problems before I expose everyone to them. This checkin represents
a merge of the prior work, which I backed out a while ago, to the
HEAD only and does not incorporate any additional bugfixes. The
additional bugfixes and code-cleanup will occur in later checkins.

For reference the patches that were used are:
cvs diff -kk -r1.51 -r1.55 eval.c | patch
cvs diff -kk -r1.27 -r1.28 exec.c | patch
cvs diff -kk -r1.15 -r1.16 exec.h | patch
cvs diff -kk -r1.32 -r1.33 input.c | patch
cvs diff -kk -r1.10 -r1.11 input.h | patch
cvs diff -kk -r1.32 -r1.35 jobs.c | patch
cvs diff -kk -r1.9 -r1.11 jobs.h | patch
cvs diff -kk -r1.36 -r1.37 main.c | patch
cvs diff -kk -r1.20 -r1.21 redir.c | patch
cvs diff -kk -r1.10 -r1.11 redir.h | patch
cvs diff -kk -r1.10 -r1.12 shell.h | patch
cvs diff -kk -r1.22 -r1.23 trap.c | patch
cvs diff -kk -r1.12 -r1.13 trap.h | patch
cvs diff -kk -r1.23 -r1.24 var.c | patch
cvs diff -kk -r1.16 -r1.17 var.h | patch

All other changes were simply the resolution of the resulting
conflicts, which occured only in the merge of jobs.c.

Begins to address PR: bin/5475
 1.19.52.1  23-Jun-2011  cherry Catchup with rmind-uvmplock merge.
 1.21.4.3  21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.21.4.2  21-Apr-2020  martin Sync with HEAD
 1.21.4.1  10-Jun-2019  christos Sync with HEAD
 1.21.2.2  30-Sep-2018  pgoyette Ssync with HEAD
 1.21.2.1  06-Sep-2018  pgoyette Sync with HEAD

Resolve a couple of conflicts (result of the uimin/uimax changes)
 1.23.2.1  28-Apr-2021  martin Pull up following revision(s) (requested by kre in ticket #1259):

bin/sh/jobs.h: revision 1.24
bin/sh/eval.c: revision 1.182
bin/sh/jobs.c: revision 1.110

Related to PR bin/48875

Correct an issue found by Oguz <oguzismailuysal@gmail.com> and reported
in e-mail (on the bug-bash list initially!) with the code changed to deal
with PR bin/48875

With:
sh -c 'echo start at $SECONDS;
(sleep 3 & (sleep 1& wait) );
echo end at $SECONDS'

The shell should say "start at 0\nend at 1\n", but instead (before
this fix, in -9 and HEAD, but not -8) does "start at 0\nend at 3\n"
(Not in -8 as the 48875 changes were never pulled up)>

There was an old problem, fixed years ago, which cause the same symptom,
related to the way the jobs table was cleared (or not) in subshells, and
it seemed like that might have resurfaced.

But not so, the issue here is the sub-shell elimination, which was part
of the 48875 "fix" (not really, it wasn't really a bug, just sub-optimal
and unexpected behaviour).

What the shell actually has been running in this case is:

sh -c 'echo start at $SECONDS;
(sleep 3 & sleep 1& wait );
echo end at $SECONDS'

as the inner subshell was deemed unnecessary - all its parent would
do is wait for its exit status, and then exit with that status - we
may as well simply replace the current sub-shell with the new one,
let it do its thing, and we're done...

But not here, the running "sleep 3" will remain a child of that merged
sub-shell, and the "wait" will thus wait for it, along with the sleep 1
which is all it should be seeing.

For now, fix this by not eliminating a sub-shell if there are existing
unwaited upon children in the current one. It might be possible to
simply disregard the old child for the purposes of wait (and "jobs", etc,
all cmds which look at the jobs table) but the bookkeeping required to
make that work reliably is likely to take some time to get correct...

Along with this fix comes a fix to DEBUG mode shells, which, in situations
like this, could dump core in the debug code if the relevant tracing was
enabled, and add a new trace for when the jobs table is cleared (which was
added predating the discovery of the actual cause of this issue, but seems
worth keeping.) Neither of these changes have any effect on shells
compiled normally.

XXX pullup -9

RSS XML Feed