Home | History | Annotate | only in /src/bin/sh
History log of /src/bin/sh
RevisionDateAuthorComments
 1.124 14-Oct-2024  kre Reject nul characters in shell input.

At the request of Thomas Klausner (wiz@) copy an idea from OpenBSD,
and have the shell simply reject any (sh) input containing a \0 (nul)
character. Previously nul characters were simply ignored (removed
from the input before it was examined in any other way).

Note this affects data read by the shell itself only, and has no
impact on other utilities, including those that are built into
the shell (so 'read' can still use -d '' to process output using
\0 as the record separator).

While I have tested that this works, there are so many places
where a nul might appear, that I cannot possibly test them all
(or even imagine all the possible places), so if this change
causes any problems, let me know (if from a script, send me the
script).

To undo this change, simply comment out (or delete) the line
CPPFLAGS+= -DREJECT_NULS
from the Makefile, and build again. Eventually if this causes
no problems, that option (conditional compilation) will probably
just go away, and this change would be permanent.

While the conditional compilation (on or off) persists, the
NETBSD_SHELL variable value will contain the word REJECT_NULLS
so you can easily verify if you are running a shell with this
included or not.

No pullups planned.
 1.123 19-Oct-2023  mrg branches: 1.123.2;
convert gcc12 -O1 into -Wno-error=clobbered.

parser.c wants all the optimisation, and this is very likely a
false positive.
 1.122 14-Oct-2023  mrg the parser.c longjmp vs gcc12 issue affects a few ports,
make the workaround global.
 1.121 14-Aug-2023  mrg use -O1 on sh3, GCC 12 and parser.c.

this triggers clobbered vs. longjmp/setjmp warnings with -Os that sh3 uses.
 1.120 10-Oct-2021  rillig sh: remove no-op 'continue' from do-while-0 loop

With Clang, the only change to the binary are the line number changes
from __LINE__, GCC generates a bit different code.

No functional change.
 1.119 09-Oct-2021  rillig bin: in builds with MKLINT=yes, run lint on all programs
 1.118 09-Oct-2021  rillig sh: ignore lint error about 'continue' in 'do while' loop

exec.c(575): error: continue in 'do ... while (0)' loop [323]
jobs.c(203): error: continue in 'do ... while (0)' loop [323]

It is certainly a rarely used feature, I saw it the first time today and
had to look up its meaning in the C standard. But after that, I don't
see why a 'continue' statement in a 'do while' loop should be an error.
Maybe a warning since up to now I thought that 'continue' would jump
back to the top of the loop, while it really jumps to the bottom of the
loop body, for all 3 kinds of loops.
 1.117 15-Aug-2021  christos Add -I to find filecomplete.h
 1.116 26-May-2021  christos Use the date tool
 1.115 28-Oct-2018  kre branches: 1.115.6;

Change the (commented out) setting of -DDEBUG to the form that
is most likely to be useful if someone other than me wants to
build a DEBUG shell. NFC (it is a comment in a Makefile!)
 1.114 10-Jun-2018  christos branches: 1.114.2;
use SUBDIR.roff suggested by uwe@
 1.113 30-Jun-2017  kre branches: 1.113.4;

Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
 1.112 08-Jun-2017  kre I am an idiot... revert the previous unintended commit.
 1.111 08-Jun-2017  kre Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
 1.110 29-May-2017  kre branches: 1.110.2;

More DEBUG mode changes. As usual, read the source if you care.
 1.109 28-May-2017  kre Redo mkoptions.sh .. much better this way, now fully automated
option sorting (no longer required option.list to be manually
sorted by long option name) and properly handles conditional
options. Cleaner output format as well.

This allows option.list to be reordered to group related options
together ... also added more comments to it.
 1.108 28-May-2017  kre Arrange for set -o and $- output to be sorted, rather than more
or less random (and becoming worse as more options are added.)
Since the data is known at compile time, sort at compile time,
rather than at run time.
 1.107 15-May-2017  kre Drop the lex library - hasn't been needed since the airthmetic
upgrade a while ago (this should make no difference to anything
other than a minor - very minor - build time speedup, ld is
smart enough to relaise that nothing from the lex library was
needed, and the executable contains no reference to it, even
befor ethis change.)
 1.106 14-May-2017  kre Fix a minor omission in last...
 1.105 14-May-2017  kre Make ${NETBSD_SHELL} value include (a human recognisable form of)
MKREPRO_TIMESTAMP (as an additional word in the value, with a "BUILD:" prefix)
if it is set during the build. (Trailing 00 pairs in the time are removed).

While here, throw in some extra words that list the compilation
options used which alter sh behaviour (mostly by removing stuff.)
Usually that will only be noticed in a SMALL shell compiled for
install media, or similar - none of the others (not that there
are many) are ever changed from the default in a normal build
(default settings are just omitted.) This also allows scripts
to tell if they are running in a DEBUG shell, which can sometimes
make debugging easier.
 1.104 20-Mar-2017  kre branches: 1.104.2;


Finish support for all required $(( )) (shell arithmetic) operators,
closing PR bin/50958

That meant adding the assignment operators ('=', and all of the +=, *= ...)
Currently, ++, --, and ',' are not implemented (none of those are required
by posix) but support for them (most likely ',' first) might be added later.

To do this, I removed the yacc/lex arithmetic parser completely, and
replaced it with a hand written recursive descent parser, that I obtained
from FreeBSD, who earlier had obtained it from dash (Herbert Xu).

While doing the import, I cleaned up the sources (changed some file names
to avoid requiring a clean build, or signifigant surgery to the obj
directories if "build.sh -u" was to be used - "build.sh -u" should work
fine as it is now) removed some dashisms, applied some KNF, ...
 1.103 16-Mar-2017  kre Have "make clean" remove sh.html1 and adapt it to clean trace files
the way they have been generated the past 20 years or so...
 1.102 27-Feb-2016  christos branches: 1.102.2; 1.102.4;
Improve debugging, from kre (I hooked it to the build).
 1.101 10-May-2015  joerg Include printf by default even for SMALL builds. It is used e.g. by
dhcpcd and as such required by most ramdisk images. Allow turning it off
again by TINYPROG.
 1.100 05-Jul-2014  dholland branches: 1.100.2;
remove .if make(install)
 1.99 02-Dec-2012  apb branches: 1.99.8;
Adjust everything under src (but outside src/tools) to use
the TOOLDIR version of libnbcompat, associated include files,
and associated defs.mk file, instead of the version from the
.OBJDIR of src/tools/compat. This should fix PR 47188.
 1.98 23-Aug-2011  christos branches: 1.98.2; 1.98.8;
document another non-literal format string
 1.97 14-Aug-2011  christos Document non-literal formats
 1.96 12-Jul-2011  joerg Move the savehandler assignment before setjmp() to avoid triggering
warnings about use before initialization with clang.
 1.95 26-May-2011  joerg Default to -Wno-sign-compare -Wno-pointer-sign for clang.
Push -Wno-array-bounds down to the cases that depend on it.
Selectively disable warnings for 3rd party software or non-trivial
issues to be reviewed later to get clang -Werror to build most of the
tree.
 1.94 30-Aug-2010  christos increase commented out debugging.
 1.93 22-Aug-2010  perry add bsd.subdir.mk
 1.92 22-Aug-2010  perry build the tutoral
 1.91 06-Feb-2010  he When using -lcurses, you also need -lterminfo.
This fixes the build for sun2, and also builds with LDSTATIC=-static,
since archive libraries don't record inter-library dependencies.
 1.90 03-Feb-2010  roy Userland now builds and uses terminfo instead of termcap.

OK: core@, jdc@
 1.89 14-Dec-2009  christos use .ORDER for rules that create multiple files.
 1.88 11-Dec-2009  uebayasi Rewrite file generation rules using ${GENCMD}. No functional changes intended.
 1.87 07-Dec-2009  uebayasi Define dependencies of arith.[ch] on arith.y.
 1.86 29-Oct-2009  christos use flex options instead of #defines
 1.85 20-Apr-2009  drochner define YY_NO_INPUT where appropriate, from Kurt J. Lidl per PR misc/41160
 1.84 14-Feb-2009  lukem Default to WARNS=4 (except for rcp & ksh)
 1.83 25-Oct-2008  apb branches: 1.83.4;
Pass SED=${TOOL_SED:Q} in the environment to scripts run during the build.
 1.82 19-Oct-2008  apb Use ${TOOL_AWK} instead of ${AWK} or plain "awk" in make commands.
Pass AWK=${TOOL_AWK:Q} to shell scripts that use awk.
 1.81 25-Mar-2007  apb WARNS=4
 1.80 26-Jun-2005  christos sprinkle a little const, and now everything compiles with WARNS=3
 1.79 30-Oct-2004  christos Pass WARNS=3
 1.78 06-Jun-2004  christos don't include the printf builtin if we are SMALL; saves 10K.
 1.77 17-Jan-2004  dsl Put a syntax.c under CVS instead of building if with the mksyntax program.
Kill mksyntax.c - no longer possible to get the 'wrong sort of chars'.
/bin/sh now has no helper binaries.
syntax.c uses C99 initialisers, run time initialisation could be used
for systems where the compiler doesn't support them.
I've used some #defines to help make this possible - but writing the code
starts making it rather messy.
 1.76 17-Jan-2004  dsl Put syntax.h under CVS instead of having it generated by mksyntax.
Use CHAR_MIN (from limits.h) to determine whether target char are signed
or unsigned - the syntax tables will not be indexed properly.
Rip out all the stuff from mksyntax.c that wrote syntax.h.
syntax.c can stiff be generated incorrectly...
 1.75 17-Jan-2004  dsl Replace mkinit.c with mkinit.sh
Build mksyntax directly from mksyntax.c so that the -DTARGET_CHAR=xxx
is applied when it is build.
OTOH mksyntax is broken as it tries to determine properties of the
target system by running code on the build system.
 1.74 16-Jan-2004  dsl Replace the C program mknodes.c with a shell script mknodes.sh
(mkinit and mksyntax may also die soon...)
 1.73 16-Nov-2003  lukem Improve how various "simple" host tools are built and invoked.
 1.72 21-Oct-2003  lukem Rework how MAKEVERBOSE operates:

* Don't bother prefixing commands with a line of ${_MKCMD}\
and instead rely upon "make -s". This is less intrusive on
all the Makefiles than the former. Idea from David Laight.

* Rename the variables use to print messages. The scheme now is:
_MKMSG_FOO Run _MKMSG 'foo'
_MKTARGET_FOO Run _MKMSG_FOO ${.TARGET}
From discussion with Alistair Crooks.
 1.71 19-Oct-2003  lukem rework to use the newer _MKMSGCREATE (et al) macros
 1.70 19-Oct-2003  lukem improve MAKEVERBOSE message for HOST_LINKed tools
 1.69 19-Oct-2003  lukem Support MAKEVERBOSE (XXX: mksyntax is noisy when MAKEVERBOSE=0).
Use DPSRCS appropriately.
 1.68 18-Oct-2003  lukem Link the host tools against tools/compat -lnbcompat since someone decided to
use strlcpy() and snprintf() in the host tools...

Should fix part of [toolchain/22504], and build problems on other
platforms that don't have strlcpy() or snprintf()...
 1.67 14-Sep-2003  jmmv Add 'trace' to CLEANFILES, generated when debug is enabled.
 1.66 15-May-2003  dsl Fix problems with parallel makes.
 1.65 08-May-2003  christos Use ${HOST_SH}
 1.64 10-Mar-2003  lukem If building as a CRUNCHEDPROG, use "lex -L" and "yacc -l" to suppress #line
generation. This may solve [bin/20637].
 1.63 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.62 09-Jan-2003  christos allow this to be compiled with unsigned-chars.
 1.61 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.60 31-Oct-2002  wrstuden Use signed char to replace int8_t, not just char. Should fix macppc
cross-build problems introduced in rev 1.59.

Pointed out by Valeriy E. Ushakov uwe at ptc dot spbu dot ru on
tech-toolchain.
 1.59 15-Sep-2002  thorpej Use "unsigned char" and "char" instead of "u_int8_t" and "int8_t"
for TARGET_CHAR when building mksyntax. This isn't perfect, but
it lets the host tool work on non-BSD systems without completely
redoing how sh is built.
 1.58 19-Aug-2002  lukem Use ${NETBSDSRCDIR}/some/path instead of ${.CURDIR}/../../some/path (etc).
 1.57 15-May-2002  bjh21 branches: 1.57.2;
The printf builtin has been "temporarily" disabled for eight years. Remove
its directory from .PATH to avoid confusion.
 1.56 12-Feb-2002  ross back this directory up a day, systems won't even boot (rc.subr splodes)

suggested back-to-the-drawing-board test: $ echo "${PWD:-notlikely}"
 1.55 11-Feb-2002  christos Add a commented out -DDEBUG in CPPFLAGS.
 1.54 07-Feb-2002  lukem .ifdef SMALLPROG, -DSMALL
 1.53 03-Nov-2001  lukem change from WARNS?=1 to WARNS?=2 for bin/
 1.52 18-Apr-2001  bjh21 Use ${MACHINE_CPU} == "arm" to test for ARMishness.
 1.51 29-Dec-2000  bjh21 arm26 has unsigned chars too.
 1.50 09-Apr-2000  christos PR/9847: Geoff C. Wing: Make test(1) a builtin.
 1.49 09-Jul-1999  christos compile with WARNS = 2
 1.48 05-Feb-1999  tron branches: 1.48.2;
Remove "arith.h" while cleaning.
 1.47 05-Feb-1999  christos PR/5577: Craig M. Chase: sh does not build with PARALLEL set.
- Added YHEADER in Makefile, removed arith.h and adjusted the sources.
 1.46 08-Oct-1998  ross The recent cross-compile changes broke the build of x_sh. Properly use
${.IMPSRC} instead of the broken ${.CURDIR}/thing.c.
 1.45 12-Sep-1998  wrstuden We don't generate .o's anymore for helper programs, so don't CLEANFILES them.
 1.44 12-Sep-1998  wrstuden Patch to make sh cross-compile right. mksyntax reports unsigned char for
powerpc, and signed for m68k & i386.
 1.43 19-Apr-1998  cgd move OBJS depenency on built headers to after include of bsd.prog.mk, so
that things are built in the right order on 'make cleandir && make' (i.e.
so that the headers are properly built).
 1.42 13-Apr-1998  lukem * remove CFLAGS+=-w for powerpc (added in 1.26):
- it was in the wrong place
- makefiles shouldn't override CFLAGS; only CPPFLAGS and COPTS
- christos fixed unsigned char stuff in 1.33 which should
remove the need for -w anyway
* move .include <bsd.prog.mk> to EOF
 1.41 09-Apr-1998  tv .y.c <sys.mk> rule fixes. Don't create a y.tab.h file unless asked for,
and use smarter creation of the header file.
 1.40 30-Mar-1998  veego Another try to make this work again. Lets hope that the we don't need a 4th
fix for it.
 1.39 30-Mar-1998  mrg make this work again when . is not in $PATH
 1.38 29-Mar-1998  christos Pr/5221: Jason Thorpe: Simplify sh Makefile, so that builts from other
directories work.
 1.37 21-Jan-1998  christos BSD4_4 is a standard symbol in <sys/param.h>; make sure that files
that need this defined, include <sys/param.h> and don't define it in
the Makefile. Add a comment to that effect.
 1.36 20-Jan-1998  pk Define BSD4_4: quad_t's in struct rlimit;
 1.35 10-Oct-1997  christos branches: 1.35.2;
CFLAGS->CPPFLAGS
 1.34 20-Jul-1997  christos Remove WARNS=1 from all the subdirectory Makefiles, and add it to Makefile.inc
now that all /bin has been cleaned.
 1.33 04-Jul-1997  christos Make the syntax tables work on machines where characters are unsigned.
 1.32 04-Jul-1997  christos Don't roll own rules to build helper programs.
Add WARNS
 1.31 16-Jun-1997  lukem add auto-generated token.h to dependancy for ${OBJS}.
not everyone runs "make depend" ...
 1.30 15-May-1997  veego Add mkinit.o mknodes.o mksyntax.o to CLEANFILES
 1.29 09-May-1997  mycroft Eliminate bogus redefinitions of standard targets.
 1.28 08-May-1997  gwr Back out the .PATH.c changes. The .depend problem (and others)
will be fixed using the new .NOPATH make feature instead.
 1.27 06-May-1997  gwr Use .PATH.c: ...
 1.26 17-Apr-1997  thorpej - XXX Inhibit warnings on PowerPC for now - there are lots of
"char is unsigned" problems here.
- Add rules for mkinit, mknodes, and mksyntax that use the HOST_*
facilities, for cross-compiling.
 1.25 22-Oct-1996  cgd add builtins.h to the list of (built) headers depended on by ${OBJS}, so
make from 'cleandir' works.
 1.24 16-Oct-1996  christos PR/2808: Depend and clean fixes from FreeBSD
 1.23 18-Feb-1996  mycroft branches: 1.23.4;
Fix problems with the way init.o is built:
* Prevent gratuitous rebuilds when nothing has changed.
* Make sure it's rebuilt if a .h file is updated.
From Mike Long, PR 1454.
 1.22 22-Oct-1995  christos Parallel make fixes.
 1.21 10-Jun-1995  mycroft Add a DPADD.
 1.20 11-May-1995  christos Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.19 21-Mar-1995  cgd convert to new RCS id conventions.
 1.18 04-Nov-1994  jtc ulimit builtin (PR #388)

This public domain code, originally by Doug Gwyn, Doug Kingston, Eric
Gisin, and Michael Rendell was ripped from pdksh 5.0.8 and hacked for
use with ash.
 1.17 24-Jun-1994  jtc Renamed builtins to builtins.def to eliminate make's (incorrect) circular
dependancy between the builtins data file and builtins.c.

The bug only occured when there was no obj directory, and is a result of
NetBSD's better (compared to 4.4lite's) default make rules.

Fixes bug #301.
 1.16 11-Jun-1994  mycroft Add RCS ids.
 1.15 02-Jun-1994  pk Exclude `mkinit' from argument list to `mkinit'; this especially causes
trouble when compiling with `-g'.
 1.14 14-May-1994  cgd add back in support for building w/o obj dir. also, add NO_HISTORY
define, which (if you invoke mkbuiltins properly) gets you a sh w/o
history of command line editing (for floppy sh).
 1.13 12-May-1994  jtc Added DPADD.
 1.12 12-May-1994  jtc Use libc's sys_siglist[] instead of building and using our own array of
signal names. (from charles)
 1.11 11-May-1994  jtc temporarily disable printf builtin
 1.10 11-May-1994  jtc sync with 4.4lite
 1.9 28-Dec-1993  davidb Changed to use make's new .OBJDIR
 1.8 14-Nov-1993  cgd from Thomas Eberhardt <thomas@mathematik.uni-Bremen.de>:
Some reordering and modifications in the Makefiles for sh, dump,
restore to get dependicies right. The README in /usr/share/mk
states that it's a Bad Thing(tm) to add something after
.include <bsd.prog.mk>, but this seems the only way to get the
dependencies right.
 1.7 09-Aug-1993  mycroft Tweak for cross-compiling.
 1.6 06-Aug-1993  mycroft Use sys_signame[].
 1.5 02-Aug-1993  mycroft Add RCS identifiers, remove some completely useless RCS logs and patchkit
headers, and a few other insignificant changes.
 1.4 04-May-1993  mycroft Make sure init.c is touched so it doesn't get rebuilt if we
make again. (Okay, so I did reproduce it.)
 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.23.4.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.35.2.1 08-May-1998  mycroft Sync with trunk, per request of christos.
 1.48.2.1 03-Jun-2000  he Pull up revision 1.50 (requested by he):
Enable test as a shell builtin. Fixes PR#9847.
 1.57.2.2 06-Dec-2002  he Pull up revision 1.60 (requested by thorpej in ticket #1027):
Use ``signed char'' instead of ``char'' to replace ``int8_t''.
Should fix cross-building problem introudced by the pull-up
in ticket #874.
 1.57.2.1 01-Dec-2002  he Pull up revision 1.59 (requested by thorpej in ticket #819):
Use ``unsigned char'' and ``char'' instead of ``u_int8_t''
and ``int8_t'' for TARGET_CHAR when building mksyntax.
This lets the host tool work on non-BSD systems without
causing too many changes to how sh is built.
 1.83.4.1 13-May-2009  jym Sync with HEAD.

Third (and last) commit. See http://mail-index.netbsd.org/source-changes/2009/05/13/msg221222.html
 1.98.8.2 19-Aug-2014  tls Rebase to HEAD as of a few days ago.
 1.98.8.1 25-Feb-2013  tls resync with head
 1.98.2.1 16-Jan-2013  yamt sync with (a bit old) head
 1.99.8.1 10-Aug-2014  tls Rebase.
 1.100.2.1 04-Jun-2015  msaitoh Pull up following revision(s) (requested by martin in ticket #821):
bin/sh/builtins.def: revision 1.23
bin/sh/Makefile: revision 1.101
Include printf by default even for SMALL builds. It is used e.g. by
dhcpcd and as such required by most ramdisk images. Allow turning it off
again by TINYPROG.
 1.102.4.1 21-Apr-2017  bouyer Sync with HEAD
 1.102.2.2 26-Apr-2017  pgoyette Sync with HEAD
 1.102.2.1 20-Mar-2017  pgoyette Sync with HEAD
 1.104.2.1 19-May-2017  pgoyette Resolve conflicts from previous merge (all resulting from $NetBSD
keywork expansion)
 1.110.2.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.113.4.2 26-Nov-2018  pgoyette Sync with HEAD, resolve a couple of conflicts
 1.113.4.1 25-Jun-2018  pgoyette Sync with HEAD
 1.114.2.3 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.114.2.2 21-Apr-2020  martin Sync with HEAD
 1.114.2.1 10-Jun-2019  christos Sync with HEAD
 1.115.6.1 31-May-2021  cjep sync with head
 1.123.2.1 02-Aug-2025  perseant Sync with HEAD
 1.11 25-Oct-2016  abhinav branches: 1.11.14;
Fix grammar in couple of sentences.
 1.10 15-Nov-2008  snj branches: 1.10.32;
Some spelling fixes from VaX#n8 in PR bin/23812.
 1.9 24-Apr-2006  snj It's "its."
 1.8 16-Oct-1996  christos PR/2808: tokens.def -> tokens.h
 1.7 11-May-1995  christos branches: 1.7.6;
Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.6 21-Mar-1995  cgd convert to new RCS id conventions.
 1.5 11-Jun-1994  mycroft Add RCS ids.
 1.4 11-May-1994  jtc sync with 4.4lite
 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.7.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.10.32.1 04-Nov-2016  pgoyette Sync with HEAD
 1.11.14.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.11.14.1 21-Apr-2020  martin Sync with HEAD
 1.24 12-May-2025  kre Fix a (probably) minor alias command bug

If run as
alias ''
the implementation could potentially reference
uninit'd memory, potentially even leading to a
SEGV, though in testing that doesn't happen, and
I doubt ever could.

Note this only occurs because of some ancient
code commented as "funny ksh stuff" with the
seemingly exotic purpose of allowing '=' to be
an alias.

Prevent even the possibility of the bug, and if
nothing else, make the error message that now
occurs more explicitly indicate the issue.

Note that this code (& this bug) has been in sh since
rev 1.1 of this file (ie: forever in NetBSD, and
before it - original ash had no aliases, so it wasn't
in that, but it has been in CSRG sh since aliases were
first added to that (sccs rev 1.1), in May 1992) and
has never been observed or reported as a problem, that
I'm aware of anyway, so I am not planning any pullups of
this fix. Found by code reading alone.
 1.23 11-May-2025  rillig sh: fix a lint warning

No binary change.
 1.22 24-Feb-2023  kre branches: 1.22.2;

Allow (but do not require) the magic '--' option terminator in
the builtin 'alias' command. This allows portability (not that
anyone should really care with aliases) for scripts from other
shells in which the alias command has options, and the -- is
required to allow the first alias name to begin with a '-'.

That is, for us, alias -x='echo x' works fine, always has,
and still does. But other shells treat that as an attempt
to use the -x option (and maybe -= etc), and require
alias -- -x='echo x'. For us that variant used to complain
about the alias -- not existing (as an arg with no '=' is
treated as a request to extract the value of the alias).

Posix also generally requires all standard commands (or
which "alias" is one, unfortunately) to support '--' even
if they have no options, for precisely this reason.
 1.21 09-Feb-2019  kre Allocate alias pointers for qsort() to use on the stack, rather than
directly via malloc() so they get cleaned up correctly on error/intr.

NFCI.
 1.20 03-Dec-2018  kre Revamp aliases - as dumb an idea as they are, if we're going
to have them, they should work as documented, not cause core
dumps, reference after free, incorrect replacements, failing
to implement alias after alias, ...

The big comment that ended:
This is a good idea ------- ***NOT***
and the hack it was describing are gone.

Note that most of this was from original CVS version 1.1
code (ie: came from the original import, even before 4.4-Lite
was merged. That is, May 1994. And no-one in 24.5 years
noticed (or at least complained about) all the bugs (or at
least, most of them)).

With these changes, aliases ought to work (if you can call it
that) as they are expected to by POSIX. Now if only we could
get POSIX to delete them (or make them optional)...

Changes partly inspired by similar changes made by FreeBSD,
(as was the previous change to alias.c, forgot ack in commit
log for that one, apologies) but done a little differently,
and perhaps with a slightly better outcome.
 1.19 02-Dec-2018  kre Fix the worst of the bugs in alias processing. This has been in sh
since this code was first imported (May 1994) (ie: before 4.4-Lite)

There is (much) more coming soon (the big ugly comment is going away).

This one has been separated out, as it can easily cause sh
core dumps, so needs:

XXX pullup-8

(the other changes to aliases probably will not get that.)
 1.18 01-Dec-2018  kre NFC. KNF. return (x) -> return x
 1.17 07-Oct-2018  rillig When listing aliases, sort them alphabetically.
 1.16 24-Jul-2017  kre branches: 1.16.2; 1.16.4;
PR bin/52348

Silence nuisance testing environments - avoid << of a negative number
(a signed char -- in a hash function, the result is irrelevant, as long
as it is repeatable).
 1.15 18-Jun-2014  christos branches: 1.15.16;
Adjust to the new alias text libedit API.
 1.14 18-Jun-2011  christos branches: 1.14.8; 1.14.20;
PR/45069: Henning Petersen: Use prototypes from builtins.h .
 1.13 29-Oct-2010  stacktic branches: 1.13.4;
Initialized flag field in struct alias (Fixed PR/43281)
 1.12 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.11 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.10 20-May-1998  christos Fix dangling else warning.
 1.9 04-Jul-1997  christos Fix compiler warnings.
 1.8 11-Jan-1997  tls kill 'register'
 1.7 16-Oct-1996  christos PR/2808: Remove trailing whitespace (from FreeBSD)
 1.6 11-May-1995  christos branches: 1.6.6;
Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.5 21-Mar-1995  cgd convert to new RCS id conventions.
 1.4 04-Dec-1994  cgd from James Jegers <jimj@miller.cs.uwm.edu>: quiet -Wall, and squelch
some of the worst style errors.
 1.3 23-Sep-1994  mycroft Eliminate uses of some obsolete functions.
 1.2 11-Jun-1994  mycroft Add RCS ids.
 1.1 11-May-1994  jtc branches: 1.1.1;
Initial revision
 1.1.1.1 11-May-1994  jtc 44lite code
 1.6.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.13.4.1 23-Jun-2011  cherry Catchup with rmind-uvmplock merge.
 1.14.20.1 10-Aug-2014  tls Rebase.
 1.14.8.1 19-Aug-2014  tls Rebase to HEAD as of a few days ago.
 1.15.16.1 07-Dec-2018  martin Pull up following revision(s) (requested by kre in ticket #1126):

bin/sh/alias.c: revision 1.19

Fix the worst of the bugs in alias processing. This has been in sh
since this code was first imported (May 1994) (ie: before 4.4-Lite)

There is (much) more coming soon (the big ugly comment is going away).

This one has been separated out, as it can easily cause sh
core dumps, so needs:
XXX pullup-8

(the other changes to aliases probably will not get that.)
 1.16.4.3 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.16.4.2 21-Apr-2020  martin Sync with HEAD
 1.16.4.1 10-Jun-2019  christos Sync with HEAD
 1.16.2.2 26-Dec-2018  pgoyette Sync with HEAD, resolve a few conflicts
 1.16.2.1 20-Oct-2018  pgoyette Sync with head
 1.22.2.1 02-Aug-2025  perseant Sync with HEAD
 1.9 03-Dec-2018  kre Revamp aliases - as dumb an idea as they are, if we're going
to have them, they should work as documented, not cause core
dumps, reference after free, incorrect replacements, failing
to implement alias after alias, ...

The big comment that ended:
This is a good idea ------- ***NOT***
and the hack it was describing are gone.

Note that most of this was from original CVS version 1.1
code (ie: came from the original import, even before 4.4-Lite
was merged. That is, May 1994. And no-one in 24.5 years
noticed (or at least complained about) all the bugs (or at
least, most of them)).

With these changes, aliases ought to work (if you can call it
that) as they are expected to by POSIX. Now if only we could
get POSIX to delete them (or make them optional)...

Changes partly inspired by similar changes made by FreeBSD,
(as was the previous change to alias.c, forgot ack in commit
log for that one, apologies) but done a little differently,
and perhaps with a slightly better outcome.
 1.8 18-Jun-2014  christos branches: 1.8.22; 1.8.24;
Adjust to the new alias text libedit API.
 1.7 18-Jun-2011  christos branches: 1.7.8; 1.7.20;
PR/45069: Henning Petersen: Use prototypes from builtins.h .
 1.6 07-Aug-2003  agc branches: 1.6.52;
Move UCB-licensed code from 4-clause to 3-clause licence.

Patches provided by Joel Baker in PR 22249, verified by myself.
 1.5 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.4 11-May-1995  christos Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.3 21-Mar-1995  cgd convert to new RCS id conventions.
 1.2 11-Jun-1994  mycroft Add RCS ids.
 1.1 11-May-1994  jtc branches: 1.1.1;
Initial revision
 1.1.1.1 11-May-1994  jtc 44lite code
 1.6.52.1 23-Jun-2011  cherry Catchup with rmind-uvmplock merge.
 1.7.20.1 10-Aug-2014  tls Rebase.
 1.7.8.1 19-Aug-2014  tls Rebase to HEAD as of a few days ago.
 1.8.24.3 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.8.24.2 21-Apr-2020  martin Sync with HEAD
 1.8.24.1 10-Jun-2019  christos Sync with HEAD
 1.8.22.1 26-Dec-2018  pgoyette Sync with HEAD, resolve a few conflicts
 1.3 05-Feb-1999  christos PR/5577: Craig M. Chase: sh does not build with PARALLEL set.
- Added YHEADER in Makefile, removed arith.h and adjusted the sources.
 1.2 04-Jul-1997  christos Fix compiler warnings.
 1.1 11-May-1995  christos Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.26 20-Mar-2017  kre Finish support for all required $(( )) (shell arithmetic) operators,
closing PR bin/50958

That meant adding the assignment operators ('=', and all of the +=, *= ...)
Currently, ++, --, and ',' are not implemented (none of those are required
by posix) but support for them (most likely ',' first) might be added later.

To do this, I removed the yacc/lex arithmetic parser completely, and
replaced it with a hand written recursive descent parser, that I obtained
from FreeBSD, who earlier had obtained it from dash (Herbert Xu).

While doing the import, I cleaned up the sources (changed some file names
to avoid requiring a clean build, or signifigant surgery to the obj
directories if "build.sh -u" was to be used - "build.sh -u" should work
fine as it is now) removed some dashisms, applied some KNF, ...
 1.25 12-May-2016  kre branches: 1.25.2; 1.25.4;

Fix the implementation of the ?: $(( )) operator. It is right associative...

ok christos@
 1.24 16-Mar-2016  christos PR/50960: The || and && operators in $(( )) should always have a 0 or 1
result, never anything different. (from kre)
 1.23 16-Mar-2016  christos PR/50958: (partial fix) - support ?: expressions in arith expansions
(from kre)
 1.22 20-Mar-2012  matt Use C89 function definitions
 1.21 29-Aug-2011  joerg branches: 1.21.2;
Mark yyerror as static and __dead.
 1.20 18-Jun-2011  christos PR/45069: Henning Petersen: Use prototypes from builtins.h .
 1.19 13-Nov-2009  gson branches: 1.19.4;
Removed return statement in parser action that caused a memory leak with
the new yacc, making "sh MAKEDEV -MM init" consume 27 MB of virtual memory
with the result that NetBSD could no longer be installed on a 32 MB system.
 1.18 25-Mar-2007  apb Make /bin/sh use intmax_t (instead of int) for arithmetic in $((...)).
 1.17 17-Sep-2003  jmmv branches: 1.17.16;
Drop equal signs from rule definitions; they cause problems with "bison -y".
 1.16 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.15 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.14 04-Feb-2001  christos remove redundant declaration of yyparse, and move code to the bottom of
the file.
 1.13 09-Jul-1999  christos compile with WARNS = 2
 1.12 05-Feb-1999  christos PR/5577: Craig M. Chase: sh does not build with PARALLEL set.
- Added YHEADER in Makefile, removed arith.h and adjusted the sources.
 1.11 28-Jul-1998  mycroft Be more retentive about use of NOTREACHED and noreturn.
 1.10 18-May-1998  christos Need stdlib.h
 1.9 31-Jan-1998  christos Fix printf format.
 1.8 04-Jul-1997  christos branches: 1.8.2;
Fix compiler warnings.
 1.7 16-Oct-1996  christos PR/2808: Remove trailing whitespace (from FreeBSD)
 1.6 11-May-1995  christos branches: 1.6.6;
Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.5 21-Mar-1995  cgd convert to new RCS id conventions.
 1.4 23-Dec-1994  cgd eliminate two wrong-sized variables which were unused.
 1.3 15-Jul-1994  jtc Don't dump core when evaluating X % 0.
Simplify lexer by using %prec feature in yacc grammar.
Implement most of the operators required by POSIX.2.
 1.2 11-Jun-1994  mycroft Add RCS ids.
 1.1 11-May-1994  jtc branches: 1.1.1;
Initial revision
 1.1.1.1 11-May-1994  jtc 44lite code
 1.6.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.8.2.1 08-May-1998  mycroft Sync with trunk, per request of christos.
 1.17.16.1 16-Apr-2007  bouyer Pull up following revision(s) (requested by apb in ticket #570):
bin/sh/expand.c: revision 1.78
bin/sh/arith.y: revision 1.18
bin/sh/expand.h: revision 1.17
regress/bin/sh/expand.sh: revision 1.4
bin/sh/sh.1: revision 1.86
bin/sh/arith_lex.l: revision 1.14
Make /bin/sh use intmax_t (instead of int) for arithmetic in $((...)).
 1.19.4.1 23-Jun-2011  cherry Catchup with rmind-uvmplock merge.
 1.21.2.1 17-Apr-2012  yamt sync with head
 1.25.4.1 21-Apr-2017  bouyer Sync with HEAD
 1.25.2.1 26-Apr-2017  pgoyette Sync with HEAD
 1.19 20-Mar-2017  kre Finish support for all required $(( )) (shell arithmetic) operators,
closing PR bin/50958

That meant adding the assignment operators ('=', and all of the +=, *= ...)
Currently, ++, --, and ',' are not implemented (none of those are required
by posix) but support for them (most likely ',' first) might be added later.

To do this, I removed the yacc/lex arithmetic parser completely, and
replaced it with a hand written recursive descent parser, that I obtained
from FreeBSD, who earlier had obtained it from dash (Herbert Xu).

While doing the import, I cleaned up the sources (changed some file names
to avoid requiring a clean build, or signifigant surgery to the obj
directories if "build.sh -u" was to be used - "build.sh -u" should work
fine as it is now) removed some dashisms, applied some KNF, ...
 1.18 16-Mar-2016  christos branches: 1.18.2; 1.18.4;
PR/50958: (partial fix) - support ?: expressions in arith expansions
(from kre)
 1.17 16-Mar-2016  christos PR bin/50959 - allow consistent use of 0X hex constants (not just 0x)
(from kre)
 1.16 20-Mar-2012  matt Use C89 function definitions
 1.15 29-Oct-2009  christos branches: 1.15.6;
use flex options instead of #defines
 1.14 25-Mar-2007  apb Make /bin/sh use intmax_t (instead of int) for arithmetic in $((...)).
 1.13 21-Mar-2005  dsl branches: 1.13.4;
A rather better fix for treating $((x)) as equivalent to $(($x)) provided
that $x has a numeric value - which is what posix/sus needs.
 1.12 07-Aug-2003  agc branches: 1.12.6;
Move UCB-licensed code from 4-clause to 3-clause licence.

Patches provided by Joel Baker in PR 22249, verified by myself.
 1.11 06-May-2003  dsl Recognise octal and hexadecimal constants in expressions.
- as required by SUSv3
 1.10 05-Feb-1999  christos branches: 1.10.14;
PR/5577: Craig M. Chase: sh does not build with PARALLEL set.
- Added YHEADER in Makefile, removed arith.h and adjusted the sources.
 1.9 18-May-1998  christos Portability fixes for a non flex based lexical analyzer.
 1.8 29-Mar-1998  mrg - change "extern" variables into int's
- remove extern'd variables not actually referenced
- don't use char as an array index
 1.7 04-Jul-1997  christos branches: 1.7.2;
Fix compiler warnings.
 1.6 16-Oct-1996  christos PR/2808: Remove trailing whitespace (from FreeBSD)
 1.5 11-May-1995  christos branches: 1.5.6;
Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.4 21-Mar-1995  cgd convert to new RCS id conventions.
 1.3 15-Jul-1994  jtc Don't dump core when evaluating X % 0.
Simplify lexer by using %prec feature in yacc grammar.
Implement most of the operators required by POSIX.2.
 1.2 11-Jun-1994  mycroft Add RCS ids.
 1.1 11-May-1994  jtc branches: 1.1.1;
Initial revision
 1.1.1.1 11-May-1994  jtc 44lite code
 1.5.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.7.2.1 08-May-1998  mycroft Sync with trunk, per request of christos.
 1.10.14.1 06-Apr-2004  jmc Pullup rev 1.11 (requested by simonb in ticket #1650)

Recognise octal and hexadecimal constants in expressions.
 1.12.6.1 07-Apr-2005  tron Pull up revision 1.13 (requested by dsl in ticket #120):
A rather better fix for treating $((x)) as equivalent to $(($x)) provided
that $x has a numeric value - which is what posix/sus needs.
 1.13.4.1 16-Apr-2007  bouyer Pull up following revision(s) (requested by apb in ticket #570):
bin/sh/expand.c: revision 1.78
bin/sh/arith.y: revision 1.18
bin/sh/expand.h: revision 1.17
regress/bin/sh/expand.sh: revision 1.4
bin/sh/sh.1: revision 1.86
bin/sh/arith_lex.l: revision 1.14
Make /bin/sh use intmax_t (instead of int) for arithmetic in $((...)).
 1.15.6.1 17-Apr-2012  yamt sync with head
 1.18.4.1 21-Apr-2017  bouyer Sync with HEAD
 1.18.2.1 26-Apr-2017  pgoyette Sync with HEAD
 1.7 17-Dec-2017  kre branches: 1.7.4;
Do a better job of reporting invalid numeric constants in arithmetic exprs.

For example, given $(( 08 + 1 )) (or similar) instead of reporting
"expecting end of expression" - the generic error for parse failed,
which happened as this was parsed as $(( 0 8 + 1 )) because the 8
could not be a part of an octal constant, and that expr makes no sense -
instead say "unexpected '8' (out of range) in numeric constant: 08"
which makes the cause of the error more obvious.

NFC for valid expressions, just the error message (and the way the
error is detected).
 1.6 24-Jul-2017  kre Add support for ++ and -- (pre & post) and ',' to arithmetic.
 1.5 07-Jun-2017  kre A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)

This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)

The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.

This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).

I would not call the results of this perfect yet, but it is close.
 1.4 29-May-2017  kre branches: 1.4.2;

Add DEBUG tracing to arithmetic $(( )) parsing & evaluation.
NFC for non-DEBUG shells.
 1.3 20-Mar-2017  kre branches: 1.3.2; 1.3.4;

That will teach me to commit from the version I've actually
been testing, rather than the "other version" ...
 1.2 20-Mar-2017  kre Alternative way of writing (part of) the arithmetic lexical analyzer
- committed separately to make it easier to swap back if desired.

This version avoids open coding is_name() and isdigit() - measurements
show it is perhaps fractionally faster (though the difference is so small
as to probably be statistically insignifigant - if I were a statician
I might understand that) and just a little larger than the previous version.
 1.1 20-Mar-2017  kre Finish support for all required $(( )) (shell arithmetic) operators,
closing PR bin/50958

That meant adding the assignment operators ('=', and all of the +=, *= ...)
Currently, ++, --, and ',' are not implemented (none of those are required
by posix) but support for them (most likely ',' first) might be added later.

To do this, I removed the yacc/lex arithmetic parser completely, and
replaced it with a hand written recursive descent parser, that I obtained
from FreeBSD, who earlier had obtained it from dash (Herbert Xu).

While doing the import, I cleaned up the sources (changed some file names
to avoid requiring a clean build, or signifigant surgery to the obj
directories if "build.sh -u" was to be used - "build.sh -u" should work
fine as it is now) removed some dashisms, applied some KNF, ...
 1.3.4.2 26-Apr-2017  pgoyette Sync with HEAD
 1.3.4.1 20-Mar-2017  pgoyette file arith_token.c was added on branch pgoyette-localcount on 2017-04-26 02:52:13 +0000
 1.3.2.2 21-Apr-2017  bouyer Sync with HEAD
 1.3.2.1 20-Mar-2017  bouyer file arith_token.c was added on branch bouyer-socketcan on 2017-04-21 16:50:42 +0000
 1.4.2.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.7.4.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.7.4.1 21-Apr-2020  martin Sync with HEAD
 1.3 24-Jul-2017  kre branches: 1.3.4;
Add support for ++ and -- (pre & post) and ',' to arithmetic.
 1.2 07-Jun-2017  kre A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)

This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)

The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.

This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).

I would not call the results of this perfect yet, but it is close.
 1.1 20-Mar-2017  kre branches: 1.1.2; 1.1.4; 1.1.8;


Finish support for all required $(( )) (shell arithmetic) operators,
closing PR bin/50958

That meant adding the assignment operators ('=', and all of the +=, *= ...)
Currently, ++, --, and ',' are not implemented (none of those are required
by posix) but support for them (most likely ',' first) might be added later.

To do this, I removed the yacc/lex arithmetic parser completely, and
replaced it with a hand written recursive descent parser, that I obtained
from FreeBSD, who earlier had obtained it from dash (Herbert Xu).

While doing the import, I cleaned up the sources (changed some file names
to avoid requiring a clean build, or signifigant surgery to the obj
directories if "build.sh -u" was to be used - "build.sh -u" should work
fine as it is now) removed some dashisms, applied some KNF, ...
 1.1.8.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.1.4.2 26-Apr-2017  pgoyette Sync with HEAD
 1.1.4.1 20-Mar-2017  pgoyette file arith_tokens.h was added on branch pgoyette-localcount on 2017-04-26 02:52:13 +0000
 1.1.2.2 21-Apr-2017  bouyer Sync with HEAD
 1.1.2.1 20-Mar-2017  bouyer file arith_tokens.h was added on branch bouyer-socketcan on 2017-04-21 16:50:42 +0000
 1.3.4.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.3.4.1 21-Apr-2020  martin Sync with HEAD
 1.5 21-Apr-2018  kre branches: 1.5.2;

In uses like $(( var )) (un-dollared vars in arithmetic) we allow
leading whitespace in the value of var (because strtoimax() does)
but did not allow trailing whitespace. The effect is that some
cases where $(( ${var:-0} )) would work do not work without the $
expansion.

Fix that - allow trailing whitespace. However, continue to insist
upon at least one digit (a non-null var that contains nothing but
whitespace is still an error).

Note: posix is not helpful here, it simply requires that the variable
contain "a value that forms a valid integer constant" (with an optional
+ or - sign).
 1.4 24-Jul-2017  kre branches: 1.4.2;
Add support for ++ and -- (pre & post) and ',' to arithmetic.
 1.3 07-Jun-2017  kre A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)

This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)

The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.

This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).

I would not call the results of this perfect yet, but it is close.
 1.2 29-May-2017  kre branches: 1.2.2;

Add DEBUG tracing to arithmetic $(( )) parsing & evaluation.
NFC for non-DEBUG shells.
 1.1 20-Mar-2017  kre branches: 1.1.2; 1.1.4;


Finish support for all required $(( )) (shell arithmetic) operators,
closing PR bin/50958

That meant adding the assignment operators ('=', and all of the +=, *= ...)
Currently, ++, --, and ',' are not implemented (none of those are required
by posix) but support for them (most likely ',' first) might be added later.

To do this, I removed the yacc/lex arithmetic parser completely, and
replaced it with a hand written recursive descent parser, that I obtained
from FreeBSD, who earlier had obtained it from dash (Herbert Xu).

While doing the import, I cleaned up the sources (changed some file names
to avoid requiring a clean build, or signifigant surgery to the obj
directories if "build.sh -u" was to be used - "build.sh -u" should work
fine as it is now) removed some dashisms, applied some KNF, ...
 1.1.4.2 26-Apr-2017  pgoyette Sync with HEAD
 1.1.4.1 20-Mar-2017  pgoyette file arithmetic.c was added on branch pgoyette-localcount on 2017-04-26 02:52:13 +0000
 1.1.2.2 21-Apr-2017  bouyer Sync with HEAD
 1.1.2.1 20-Mar-2017  bouyer file arithmetic.c was added on branch bouyer-socketcan on 2017-04-21 16:50:42 +0000
 1.2.2.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.4.2.1 22-Apr-2018  pgoyette Sync with HEAD
 1.5.2.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.5.2.1 21-Apr-2020  martin Sync with HEAD
 1.2 07-Jun-2017  kre branches: 1.2.6;
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)

This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)

The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.

This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).

I would not call the results of this perfect yet, but it is close.
 1.1 20-Mar-2017  kre branches: 1.1.2; 1.1.4; 1.1.8;


Finish support for all required $(( )) (shell arithmetic) operators,
closing PR bin/50958

That meant adding the assignment operators ('=', and all of the +=, *= ...)
Currently, ++, --, and ',' are not implemented (none of those are required
by posix) but support for them (most likely ',' first) might be added later.

To do this, I removed the yacc/lex arithmetic parser completely, and
replaced it with a hand written recursive descent parser, that I obtained
from FreeBSD, who earlier had obtained it from dash (Herbert Xu).

While doing the import, I cleaned up the sources (changed some file names
to avoid requiring a clean build, or signifigant surgery to the obj
directories if "build.sh -u" was to be used - "build.sh -u" should work
fine as it is now) removed some dashisms, applied some KNF, ...
 1.1.8.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.1.4.2 26-Apr-2017  pgoyette Sync with HEAD
 1.1.4.1 20-Mar-2017  pgoyette file arithmetic.h was added on branch pgoyette-localcount on 2017-04-26 02:52:13 +0000
 1.1.2.2 21-Apr-2017  bouyer Sync with HEAD
 1.1.2.1 20-Mar-2017  bouyer file arithmetic.h was added on branch bouyer-socketcan on 2017-04-21 16:50:42 +0000
 1.2.6.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.2.6.1 21-Apr-2020  martin Sync with HEAD
 1.3 26-Jan-1994  mycroft Clean up deleted files.
 1.2 02-Aug-1993  mycroft Makefile
 1.1 21-Mar-1993  cgd branches: 1.1.1;
Initial revision
 1.1.1.1 21-Mar-1993  cgd initial import of 386bsd-0.1 sources
 1.10 24-Jun-1994  mycroft Clean up deleted files.
 1.9 11-Jun-1994  mycroft Add RCS ids.
 1.8 14-May-1994  cgd add back in support for building w/o obj dir. also, add NO_HISTORY
define, which (if you invoke mkbuiltins properly) gets you a sh w/o
history of command line editing (for floppy sh).
 1.7 11-May-1994  jtc reintegrate NetBSD's false builtin
 1.6 11-May-1994  jtc temporarily disable printf builtin
 1.5 11-May-1994  jtc sync with 4.4lite
 1.4 07-Jul-1993  jtc IEEE 1003.2 (D11.2.2.3) requires that the system's true and false be accessed
instead of searching $PATH. The best way to satisfy this requirement is to
make them builtins.

True was allready builtin, this patch adds false.
 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.29 09-Oct-2024  kre PR bin/58687 -- implement suspend as a builtin in sh

Requested by uwe@ in PR bin/58687 without objections from
anyone except me, here is an implementation of a suspend
builtin command for /bin/sh

The sh.1 man page is updated, naturally, to describe it.

This new builtin does not exist in SMALL shells -- as used
on (some) boot media, etc.

If this turns out not to be useful, it can easily be removed.
 1.28 09-Oct-2024  kre Housekeeping.

Improve some comments, and sort the list of builtins, to make it easier
to find what is there and what isn't (since some have multiple different
command names, sort by the internal function name). Still leave the
commented out, could be implemented, but haven't ones, almost to last,
and the almost never indluded debug command absolute last.

NFCI. (No changes should be visible externally).
 1.27 10-Nov-2021  kre branches: 1.27.4;

Ensure that all of the POSIX standard utilities are correctly
identified with the -u flag (that is, I hope I identified all
the ones that were missing it).

This change is a no-op (NFC) as the -u flag does nothing.

Still, just in case we find a use for it one day, and just as a
matter of general principle, we should get this correct.
 1.26 14-Feb-2019  kre Add the "specialvar" built-in command. Discussed (well, mentioned
anway) on tech-userlevel with no adverse response.

This allows the magic of vars like HOSTNAME SECONDS, ToD (etc) to be
restored should it be lost - perhaps by having a var of the same name
imported from the environment (which needs to remove the magic in case
a set of scripts are using the env to pass data, and the var name chosen
happens to be one of our magic ones).

No change to SMALL shells (or smaller) - none of the magic vars (except
LINENO, which is exempt from all of this) exist in those, hence such a
shell has no need for this command either.
 1.25 15-May-2017  kre branches: 1.25.10;

DEBUG mode shell update (changes nothing for shells which are not
compiled for DEBUG.)

Add debug builtin command, and corresponding -D command line option.
As usual, for DEBUG related stuff, read the source for info, that's
all there is about this.

This completes the infrastructure changes for the updated DEBUG TRACE
mechanism, so now converting the rest of the shell's internal tracing
can happen as desired - piecemeal.
 1.24 02-Feb-2017  christos branches: 1.24.2;
Add fdflags builtin. Discussed with Chet and he has implemented it for
bash too.
 1.23 10-May-2015  joerg branches: 1.23.2; 1.23.4;
Include printf by default even for SMALL builds. It is used e.g. by
dhcpcd and as such required by most ramdisk images. Allow turning it off
again by TINYPROG.
 1.22 31-Dec-2012  dsl branches: 1.22.10;
Add support for '%n' being a shorthand for 'fg %n'.
 1.21 13-Jul-2004  seb branches: 1.21.48; 1.21.54;
Add new builtin `wordexp' to support wordexp(3).

From FreeBSD.
Provided in PR lib/26123.
Approved by kleink@.
 1.20 06-Jun-2004  christos don't include the printf builtin if we are SMALL; saves 10K.
 1.19 22-Aug-2003  itojun remove \r (agc, are you using MS-DOS?)
 1.18 22-Aug-2003  agc Move 4 more files from UCB 4 clause to 3 clause licence.

Thanks to Julio Merino for pointing them out.
 1.17 04-May-2003  gmcgarry Add new builtin 'inputrc' which allows keybindings to be redefined
for the current shell. From Arne H Juul in PR#10097.
 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 09-Apr-2000  christos PR/9847: Geoff C. Wing: Make test(1) a builtin.
 1.14 14-Mar-1997  christos branches: 1.14.4;
NO_HISTORY->SMALL
 1.13 06-Feb-1997  christos add type builtin.
 1.12 11-May-1995  christos branches: 1.12.6;
Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.11 21-Mar-1995  cgd convert to new RCS id conventions.
 1.10 04-Nov-1994  jtc ulimit builtin (PR #388)

This public domain code, originally by Doug Gwyn, Doug Kingston, Eric
Gisin, and Michael Rendell was ripped from pdksh 5.0.8 and hacked for
use with ash.
 1.9 11-Jun-1994  mycroft Add RCS ids.
 1.8 14-May-1994  cgd add back in support for building w/o obj dir. also, add NO_HISTORY
define, which (if you invoke mkbuiltins properly) gets you a sh w/o
history of command line editing (for floppy sh).
 1.7 11-May-1994  jtc reintegrate NetBSD's false builtin
 1.6 11-May-1994  jtc temporarily disable printf builtin
 1.5 11-May-1994  jtc sync with 4.4lite
 1.4 07-Jul-1993  jtc IEEE 1003.2 (D11.2.2.3) requires that the system's true and false be accessed
instead of searching $PATH. The best way to satisfy this requirement is to
make them builtins.

True was allready builtin, this patch adds false.
 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 04-Mar-1997  mycroft Pull up latest sh(1). Fixes yet more bugs.
 1.14.4.1 03-Jun-2000  he Pull up revision 1.15 (requested by he):
Enable test as a shell builtin. Fixes PR#9847.
 1.21.54.1 25-Feb-2013  tls resync with head
 1.21.48.1 23-Jan-2013  yamt sync with head
 1.22.10.1 04-Jun-2015  msaitoh Pull up following revision(s) (requested by martin in ticket #821):
bin/sh/builtins.def: revision 1.23
bin/sh/Makefile: revision 1.101
Include printf by default even for SMALL builds. It is used e.g. by
dhcpcd and as such required by most ramdisk images. Allow turning it off
again by TINYPROG.
 1.23.4.1 21-Apr-2017  bouyer Sync with HEAD
 1.23.2.1 20-Mar-2017  pgoyette Sync with HEAD
 1.24.2.1 19-May-2017  pgoyette Resolve conflicts from previous merge (all resulting from $NetBSD
keywork expansion)
 1.25.10.3 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.25.10.2 21-Apr-2020  martin Sync with HEAD
 1.25.10.1 10-Jun-2019  christos Sync with HEAD
 1.27.4.1 02-Aug-2025  perseant Sync with HEAD
 1.56 18-Aug-2025  kre PR bin/59602 PWD update failure message from cd fix.

Only complain about being unable to determine the new
directory name after a cd when -e is given (test for
that was forgotten).
 1.55 12-Aug-2025  kre Improve error messages from cd builtin

Have cd indicate (particularly for when CDPATH is in use,
but also in other cases) which path name was attempted
and failed, and why it failed. For CDPATH uses, when
(if) the cd eventually fails, prefer the first entry in
which the requested destination path is located (when
the chdir() to it fails), or if there is none of those,
the first lookup which failed to determine if the path
exists there or not (ie: not ENOENT).

If the all attempts return ENOENT simply report the arg
given (after "cd -" and "cd a b" processing), as no
one CDPATH entry is more appropriate than any other.

Inspired by PR standards/59565 but not directly related.
 1.54 12-Aug-2025  kre PR standards/59565 - cd "" is now an error, not == cd .

POSIX 2024 requires that cd "" generate an error message,
and fail.

Until now shells (including this one) have typically equated
it to "cd ." as in the distant past, a lookup of "" as a path
name would return the current directory (aka ".").

From now on, we generate an error, as specified.
(For this commit, the error message is kind of pathetic,
but it is at least there - that will be fixed in a
subsequent commit.)
 1.53 31-Jan-2022  kre branches: 1.53.6;

Add some comments explaining accesses to the environment via
getenv()/setenv()/unsetenv() which manipulate the envornoment
the shell was passed at entry.

These are a little odd in sh as that environment is copied into
the shell's internal variable data struct at shell startup, and
normally never accessed after that - in builtin commands (test.
printf, ...) getenv() is #defined to become an internal sh lookup
function instead, so even those never use the startup environment).

NFCI
 1.52 16-Nov-2021  kre Make pwd (both /bin/pwd and the /bin/sh built-in version) check for
write errors on stdout, and indicate an error if that happens.
 1.51 31-Oct-2021  kre PR bin/45390 - fix for folly four

In the pwd builtin, verify that curdir names '.' before
simply printing it. Never alter PWD or OLDPWD in the
pwd command.

Also while here, implement the (new: coming in POSIX, but has existed
for a while in several other shells) -e option to cd (with -e, cd -P
will exit(1) if the chdir() succeeds, but PWD cannot be discovered).

cd now prints the directory name used (if different from that given,
or cdprint is on) if interactive or (the new bit)in posix mode.

Some additional/changed comments added, and a DEBUG mode trace call
that was accidentally put inside an #if 0 block moved to where it
can do some good.

XXX pullup -9
 1.50 05-Jul-2017  kre branches: 1.50.6; 1.50.8;

DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
 1.49 17-Jun-2017  kre Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
 1.48 04-Jun-2017  kre Make cd (really) do cd -P, and not just claim that is what it is doing
while doing a half-hearted, broken, partial, version of cd -L instead.
The latter (as the manual says) is not supported, what's more, it is an
abomination, and should never be supported (anywhere.)

Fix the doc so that the pretense that we notice when a path given crosses
a symlink (and turns on printing of the destination directory) is claimed
no more (that used to be true until late Dec 2016, but was changed). Now
the print happens if -o cdprint is set, or if an entry from CDPATH that is
not "" or "." is used (or if the "cd dest repl" cd cmd variant is used.)

Fix CDPATH processing: avoid the magic '%' processing that is used for
PATH and MAILPATH from corrupting CDPATH. The % magic (both variants)
remains undocumented.

Also, don't double the '/' if an entry in PATH or CDPATH ends in '/'
(as in CDPATH=":/usr/src/"). A "cd usr.bin" used to do
chdir("/usr/src//usr.bin"). No more. This is almost invisible,
and relatively harmless, either way....

Also fix a bug where if a plausible destination directory in CDPATH
was located, but the chdir() failed (eg: permission denied) and then
a later "." or "" CDPATH entry succeeded, "print" mode was turned on.
That is:
cd /tmp; mkdir bin
mkdir -p P/bin; chmod 0 P/bin
CDPATH=/tmp/P:
cd bin
would cd to /tmp/bin (correctly) but print it (incorrectly).

Also when in "cd dest replace" mode, if the result of the replacement
generates '-' as the path named, as in:
cd $PWD -
then simply change to '-' (or attempt to, with CDPATH search), rather
than having this being equivalent to "cd -")

Because of these changes, the pwd command (and $PWD) essentially
always acts as pwd -P, even when called as pwd -L (which is still
the default.) That is, even more than it did before.

Also fixed a (kind of minor) mem management error (CDPATH related)
"whosoever shall padvance must stunalloc before repeating" (and the
same for MAILPATH).
 1.47 26-Dec-2016  christos branches: 1.47.6;
Don't trash the logical $PWD if a component is a symlink; no other shell
does this.
 1.46 02-May-2016  christos branches: 1.46.2;
Fix handing of user file descriptors outside the 0..9 range.
Also, move (most of) the shell's internal use fd's to much
higher values (depending upon what ulimit -n allows) so they
are less likely to clash with user supplied fd numbers. A future
patch will (hopefully) avoid this problem completely by dynamically
moving the shell's internal fds around as needed. (From kre@)
 1.45 04-Jan-2016  christos Don't leak redirected rescriptors to exec'ed processes. This is what ksh
does, but bash does not. For example:

$ cat test1
#!/bin/sh
exec 6> out
echo "test" >&6
sh ./test2
exec 6>&-
$ cat test2
echo "test2" >&6
$ ./test1
./test2: 6: Bad file descriptor

This fixes by side effect the problem of the rc system leaking file descriptors
7 and 8 to all starting daemons:

$ fstat -p 1359
USER CMD PID FD MOUNT INUM MODE SZ|DV R/W
root powerd 1359 wd / 2 drwxr-xr-x 512 r
root powerd 1359 0 / 63029 crw-rw-rw- null rw
root powerd 1359 1 / 63029 crw-rw-rw- null rw
root powerd 1359 2 / 63029 crw-rw-rw- null rw
root powerd 1359 3* kqueue pending 0
root powerd 1359 4 / 64463 crw-r----- power r
root powerd 1359 7 flags 0x80034<ISTTY,MPSAFE,LOCKSWORK,CLEAN>
root powerd 1359 8 flags 0x80034<ISTTY,MPSAFE,LOCKSWORK,CLEAN>
root powerd 1359 9* pipe 0xfffffe815d7bfdc0 -> 0x0 w

Note fd=7,8 pointing to the revoked pty from the parent rc process.
 1.44 31-Aug-2011  plunky NULL does not need a cast
 1.43 18-Jun-2011  christos PR/45069: Henning Petersen: Use prototypes from builtins.h .
 1.42 10-Jun-2011  uebayasi Support $OLDPWD. (christos@ will update the manual.)

Reviewd By: christos
 1.41 17-Feb-2011  pooka branches: 1.41.2;
Tell copyfd if the caller wants the exact tofd to just fd >= tofd.
Fixes "echo foo > /rump/bar" in a rump hijacked shell.

reviewed by christos
 1.40 01-Jan-2010  dholland branches: 1.40.2;
Make the cd builtin accept and ignore -P, which is a kshism that has been
allowed to leak into POSIX and selects the behavior cd already implements.
Closes PR bin/42557 and also relevant to PR pkg/42168.

I suppose this should probably be pulled up to both -4 and -5...
 1.39 04-May-2006  simonb branches: 1.39.4; 1.39.26; 1.39.32;
Make the change for bin/31548 to set $PWD on shell startup non-fatal if
the current directory doesn't exist.
 1.38 26-Nov-2005  dsl Don't change the name of the directory we are going to 'cd' to just because
we decide to remove a leading "./" when deciding whether to print the name.
Stops 'cd .//tmp' ending up the same as 'cd /tmp'.
Fixes PR/30735
 1.37 10-Oct-2005  christos PR/31548: Alexander Rigbo: $PWD not set when shell starts up, before pwd
or cd get executed.
 1.36 20-Aug-2005  dsl Don't apply CDPATH if the the first component of the target is "." or "..".
Fixes PR/30973 and applies the principle of least surprise.
Update documentation to match (including date).
(matches behaviour of pdksh - if not it's documentation)
 1.35 15-Jul-2005  christos Only do certain actions when we are trully interactive, not just when we
are connected to a tty:
1. enable editor
2. print directory on directory change.
3. print job messages
 1.34 14-Nov-2003  dsl Posix requires that 'pwd -P' reset the shells saved cwd value - so a
subsequent 'pwd -L' will report the same value.
Update man page to be a closer match to reality.
 1.33 30-Oct-2003  dsl Validate the arguments to 'pwd'. Treat -L and -P as per pwd(1).
Note that 'pwd -L' and 'pwd -P' almost always report the same answer as
the shell detects when 'cd' follows a symlink and discards its cached 'pwd'
 1.32 25-Aug-2003  jmmv Move an assignment that was using a variable out of scope to fix a build
problem on !NetBSD.
 1.31 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.30 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.29 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.28 14-Nov-2001  he Plug a memory leak when setting PWD -- don't mark the variable with
VTEXTFIXED because the value is dynamically allocated. Fix from
Tor Egge, FreeBSD PR#31533.
 1.27 09-Jul-1999  christos compile with WARNS = 2
 1.26 28-Jul-1998  mycroft Be more retentive about use of NOTREACHED and noreturn.
 1.25 21-May-1998  ross Fix a set of bugs where a cd of a relative pathname or a cd through a
symbolic link would not set PWD.
 1.24 17-Feb-1998  christos PR/5001: Tom Yu: cd ./ does not work.
 1.23 04-Jul-1997  christos branches: 1.23.2;
PR/3827: Wolfgang Rupprecht: cd ./. core dumps
Warning cleanups
 1.22 11-Apr-1997  christos __svr4__ -> __SVR4
 1.21 07-Mar-1997  christos Fix PR/3289: upon initialization check if $PWD contains the right directory
and use it. We also maintain $PWD now, like the rest of the
shells.
 1.20 11-Jan-1997  tls kill 'register'
 1.19 22-Dec-1996  cjs Re-introduce some code from 1.14 (with modifications) to make the
shell's idea of the current working directory match reality when
symlinks (or anything else we can't stat) are traversed with the
cd command. However, this does not print out the cwd after cd
traverses symlinks, as it used to, though the capability is still
there should one want to use it.
 1.18 16-Oct-1996  christos PR/2808: Handle cd "". This is for systems where "" != "."
 1.17 18-Sep-1996  thorpej If getcwd() fails, dang it, I want to know _why_.
 1.16 25-Jun-1996  christos Include header files to get function prototypes; don't use home grown ones.
 1.15 01-Mar-1996  jtc branches: 1.15.4;
Changed so that cd builtin doesn't do wierd stuff when cd'ing through
symlinks. From Chris Demetriou <cgd@NetBSD.ORG>. Fixes PR #1776.

Changed so that INTOFF/INTON are paired in getpwd(). From Matthias
Pfaller <leo@marco.de>. Fixes PR #2130.
 1.14 19-Nov-1995  christos Fix PR/1760, where 'cd -' before any other command could cause a reference
to an uninitialized pointer. Use getcwd() to get the current working directory,
instead of forking /bin/pwd [per Scott's suggestion]
 1.13 11-May-1995  christos Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.12 21-Mar-1995  cgd convert to new RCS id conventions.
 1.11 30-Jan-1995  mycroft Use S_IS*().
 1.10 05-Dec-1994  cgd clean up further. more patches from Jim Jegers
 1.9 04-Dec-1994  cgd from James Jegers <jimj@miller.cs.uwm.edu>: quiet -Wall, and squelch
some of the worst style errors.
 1.8 11-Jun-1994  mycroft Add RCS ids.
 1.7 12-May-1994  jtc Include appropriate header files to bring function prototypes into scope.
 1.6 11-May-1994  jtc sync with 4.4lite
 1.5 01-Aug-1993  mycroft Add RCS identifiers.
 1.4 23-Mar-1993  cgd changed "Id" to "Header" for rcsids
 1.3 22-Mar-1993  cgd added rcs ids to all files
 1.2 21-Mar-1993  cgd after 0.2.2 "stable" patches applied
 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.15.4.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.23.2.1 08-May-1998  mycroft Sync with trunk, per request of christos.
 1.39.32.1 21-Apr-2010  matt sync to netbsd-5
 1.39.26.1 30-Jan-2010  snj Pull up following revision(s) (requested by dholland in ticket #1274):
bin/sh/cd.c: revision 1.40
bin/sh/sh.1: revision 1.95
Make the cd builtin accept and ignore -P, which is a kshism that has been
allowed to leak into POSIX and selects the behavior cd already implements.
Closes PR bin/42557 and also relevant to PR pkg/42168.
I suppose this should probably be pulled up to both -4 and -5...
 1.39.4.1 27-Jan-2010  bouyer Pull up following revision(s) (requested by dholland in ticket #1380):
bin/sh/cd.c: revision 1.40
bin/sh/sh.1: revision 1.95
bin/sh/sh.1: revision 1.97
Make the cd builtin accept and ignore -P, which is a kshism that has been
allowed to leak into POSIX and selects the behavior cd already implements.
Closes PR bin/42557 and also relevant to PR pkg/42168.
I suppose this should probably be pulled up to both -4 and -5...
Bump date for cd -P support.
 1.40.2.1 05-Mar-2011  bouyer Sync with HEAD
 1.41.2.1 23-Jun-2011  cherry Catchup with rmind-uvmplock merge.
 1.46.2.1 07-Jan-2017  pgoyette Sync with HEAD. (Note that most of these changes are simply $NetBSD$
tag issues.)
 1.47.6.2 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.47.6.1 05-Jun-2017  snj Pull up following revision(s) (requested by kre in ticket #5):
bin/sh/cd.c: revision 1.48
bin/sh/eval.c: revision 1.141
bin/sh/exec.c: revision 1.48
bin/sh/exec.h: revision 1.25
bin/sh/mail.c: revisions 1.17, 1.18
bin/sh/sh.1: revision 1.147
Make cd (really) do cd -P, and not just claim that is what it is doing
while doing a half-hearted, broken, partial, version of cd -L instead.
The latter (as the manual says) is not supported, what's more, it is an
abomination, and should never be supported (anywhere.)
Fix the doc so that the pretense that we notice when a path given crosses
a symlink (and turns on printing of the destination directory) is claimed
no more (that used to be true until late Dec 2016, but was changed). Now
the print happens if -o cdprint is set, or if an entry from CDPATH that is
not "" or "." is used (or if the "cd dest repl" cd cmd variant is used.)
Fix CDPATH processing: avoid the magic '%' processing that is used for
PATH and MAILPATH from corrupting CDPATH. The % magic (both variants)
remains undocumented.
Also, don't double the '/' if an entry in PATH or CDPATH ends in '/'
(as in CDPATH=":/usr/src/"). A "cd usr.bin" used to do
chdir("/usr/src//usr.bin"). No more. This is almost invisible,
and relatively harmless, either way....
Also fix a bug where if a plausible destination directory in CDPATH
was located, but the chdir() failed (eg: permission denied) and then
a later "." or "" CDPATH entry succeeded, "print" mode was turned on.
That is:
cd /tmp; mkdir bin
mkdir -p P/bin; chmod 0 P/bin
CDPATH=/tmp/P:
cd bin
would cd to /tmp/bin (correctly) but print it (incorrectly).
Also when in "cd dest replace" mode, if the result of the replacement
generates '-' as the path named, as in:
cd $PWD -
then simply change to '-' (or attempt to, with CDPATH search), rather
than having this being equivalent to "cd -")
Because of these changes, the pwd command (and $PWD) essentially
always acts as pwd -P, even when called as pwd -L (which is still
the default.) That is, even more than it did before.
Also fixed a (kind of minor) mem management error (CDPATH related)
"whosoever shall padvance must stunalloc before repeating" (and the
same for MAILPATH).
--
If we are going to keep the MAILPATH % hack, then at least do something
rational. Since it isn't documented, what "rational" is is up for
discussion, but what it did before was not it (it was nonsense...).
 1.50.8.1 06-Nov-2021  martin Pull up following revision(s) (requested by kre in ticket #1372):

bin/sh/sh.1: revision 1.236 (patch)
bin/sh/cd.c: revision 1.51

PR bin/45390 - fix for folly four

In the pwd builtin, verify that curdir names '.' before
simply printing it. Never alter PWD or OLDPWD in the
pwd command.

Also while here, implement the (new: coming in POSIX, but has existed
for a while in several other shells) -e option to cd (with -e, cd -P
will exit(1) if the chdir() succeeds, but PWD cannot be discovered).
cd now prints the directory name used (if different from that given,
or cdprint is on) if interactive or (the new bit)in posix mode.

Some additional/changed comments added, and a DEBUG mode trace call
that was accidentally put inside an #if 0 block moved to where it
can do some good.

XXX pullup -9

PR bin/45390

Be explicit about what happens to PWD after a successful cd command.
Also be very clear that "cd" and "cd -P" are the same thing, and
the only cd variant implemented.
Also, when it is appropriate to print the new directory after a cd
command, note that it happens if interactive (as it always has here)
and also if the posix option is set (for POSIX compat, where "interactive"
is irrelevant). Mention that "cd -" is a case where the new directory
is printed (along with paths relative to a non-empty CDPATH entry,
and where the "cd old new" (string replacement in curdir) is used.

While here document the new -e option to cd.

XXX pullup -9
 1.50.6.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.50.6.1 21-Apr-2020  martin Sync with HEAD
 1.53.6.1 02-Sep-2025  martin Pull up following revision(s) (requested by kre in ticket #24):

bin/sh/cd.c: revision 1.54
bin/sh/cd.c: revision 1.55
bin/sh/cd.c: revision 1.56

PR standards/59565 - cd "" is now an error, not == cd .

POSIX 2024 requires that cd "" generate an error message,
and fail.

Until now shells (including this one) have typically equated
it to "cd ." as in the distant past, a lookup of "" as a path
name would return the current directory (aka ".").

From now on, we generate an error, as specified.
(For this commit, the error message is kind of pathetic,
but it is at least there - that will be fixed in a
subsequent commit.)


Improve error messages from cd builtin

Have cd indicate (particularly for when CDPATH is in use,
but also in other cases) which path name was attempted
and failed, and why it failed. For CDPATH uses, when
(if) the cd eventually fails, prefer the first entry in
which the requested destination path is located (when
the chdir() to it fails), or if there is none of those,
the first lookup which failed to determine if the path
exists there or not (ie: not ENOENT).

If the all attempts return ENOENT simply report the arg
given (after "cd -" and "cd a b" processing), as no
one CDPATH entry is more appropriate than any other.

Inspired by PR standards/59565 but not directly related.


PR bin/59602 PWD update failure message from cd fix.
Only complain about being unable to determine the new
directory name after a cd when -e is given (test for
that was forgotten).
 1.6 18-Jun-2011  christos branches: 1.6.44;
PR/45069: Henning Petersen: Use prototypes from builtins.h .
 1.5 10-Oct-2005  christos branches: 1.5.40;
PR/31548: Alexander Rigbo: $PWD not set when shell starts up, before pwd
or cd get executed.
 1.4 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.3 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.2 04-Jul-1997  christos Fix compiler warnings.
 1.1 19-Nov-1995  christos Fix PR/1760, where 'cd -' before any other command could cause a reference
to an uninitialized pointer. Use getcwd() to get the current working directory,
instead of forking /bin/pwd [per Scott's suggestion]
 1.5.40.1 23-Jun-2011  cherry Catchup with rmind-uvmplock merge.
 1.6.44.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.6.44.1 21-Apr-2020  martin Sync with HEAD
 1.5 11-May-1994  mycroft Clean up deleted files.
 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.1 21-Mar-1993  cgd initial import of 386bsd-0.1 sources
 1.7 15-Jan-1995  mycroft Clean up deleted files.
 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.7 15-Jan-1995  mycroft Clean up deleted files.
 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.45 19-Mar-2023  kre Do a better job handling EACCES errors from exec() calls. If the
EACCES is from the namei(), treat it just like ENOENT or ENOTDIR
(and if that is the final error, the exit status from a failed exec
will be 127). If the EACCES is from the exec() itself, that indicates
the file to be run exists, but has no 'x' permission. That's a
meaningful error (as distinct from just "yet another PATH element
search failure").

While here, return the first meaingful error we encountered while
searching PATH, rather than the last (and ENOENT if there are none
of those).

This change results in some failed command executions returning status
127 now, where they returned 126 before - which better reflects the
intent of those values (127 is simply "not found" whereas 126 is "found
but couldn't be executed").

We still do nothing to distinguish errors encountered looking up the
command name give, with errors encountered (by the kernel) attempting to
run an interpreter needed for the exec to succeed (#! line path, or
/libexec/ld.elf_so and similar - or anything else of a similar nature).
 1.44 10-Nov-2021  kre DEBUG mode changes only. NFC (NC) for any normally compiled shell.

Mostly adding DEBUG mode tracing (when appropriate verbose tracing
is enabled generally) whenever a shell (including sushell) process
exits, so shells that the tracing should indicate why ehslls that
vanish did that.

Note for future investigators: if the relevant tracing is enabled,
and a (sub-)shell still simply seems to have vanished without trace,
the likely cause is that it was killed by a signal - and of those,
the most common that occurs is SIGPIPE.
 1.43 04-Feb-2019  kre PR bin/53919

Suppress shell error messages while expanding $ENV (which also causes
errors while expanding $PS1 $PS2 and $PS4 to be suppressed as well).

This allows any random garbage that happens to be in ENV to not
cause noise when the shell starts (which is effectively all it did).

On a parse error (for any of those vars) we also use "" as the result,
which will be a null prompt, and avoid attempting to open any file for ENV.

This does not in any way change what happens for a correctly parsed command
substitution (either when it is executed when permitted for one of the
prompts, or when it is not (which is always for ENV)) and commands run
from those can still produce error output (but shell errors remain suppressed).
 1.42 21-Jan-2019  kre DEBUG mode shell cleanups (NFC for any normal shell).

Add an error DEBUG trace in exraise() (when the shell has detected
some error or signal, and is aborting what it is doing)

Fix an arith error in DEBUG bit assignments (harmless as we haven't
reached the limit of flags yet), and add some missing (recently added)
debug flags so they are turned on when the user (ie: me) asks for
"everything".
 1.41 24-Jul-2017  kre branches: 1.41.2; 1.41.4;
PR bin/52348

Avoid a reference after free (detected by asan) - harmless here, but
easy to fix.
 1.40 05-Jul-2017  kre DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
 1.39 01-Jun-2016  kre branches: 1.39.8;

PR bin/47065 PR bin/39466

When the shell exits after an error (when that is the right thing for
it to do) ensure that it never does exit(0).
 1.38 15-Mar-2012  joerg Add __printflike attribution to use vprintf and friends with an argument
as format string.
 1.37 16-Oct-2008  dholland branches: 1.37.18;
Use "extern" properly for referencing globals defined in other modules.
Now builds cleanly with -warn-common.
 1.36 15-Feb-2008  matt Fix inconsistent definitions
 1.35 18-Dec-2007  dogcow This should have been all on one line anyway - and hey, it fixes my build
issue.
 1.34 15-Dec-2007  perry convert __attribute__s to applicable cdefs.h macros
 1.33 04-Oct-2006  christos branches: 1.33.8;
Prefix "Syntax Error" with the program name, if the command name is not
available. At least this way we get an idea of what program gives us the
message.
 1.32 02-Jan-2006  garbled Add error printing for ENAMETOOLONG. Partially addresses PR bin/13850 .
The actual bug mentioned in that PR no longer exists, but it does cause:
~~~~~: error 63
Which this fix cleans up.
 1.31 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.30 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.29 16-Jan-2003  kleink Rename `sigset' locals to avoid symbol shadowing warning.
 1.28 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.27 27-Sep-2002  mycroft Clean up INTOFF/INTON usage a little -- none of fork{shell,parent,child}()
screw with them now, only their callers.
 1.26 27-Sep-2002  christos no SYSV for eagain, enable EMFILE
 1.25 25-May-2002  wiz __STDC__ is always defined on NetBSD, so remove #ifdef __STDC__ (and
unnecessary #else cases).
 1.24 15-May-2002  christos implement noclobber. From Ben Harris, with minor tweaks from me. Two
unimplemented comments to go. Go Ben!
 1.23 03-Jul-2000  matt include <stdlib.h>, <string.h>, or whatever as appropriate to shut up
gcc 2.96
 1.22 09-Jul-1999  christos compile with WARNS = 2
 1.21 05-Apr-1999  mycroft If we exit due to a SIGINT, do it with raise() so that the wait status is
correct in the parent.
 1.20 28-Jul-1998  mycroft branches: 1.20.2;
Be more retentive about use of NOTREACHED and noreturn.
 1.19 28-Jul-1998  mycroft Delint.
 1.18 31-Jan-1998  christos Include our local includes after the system's ones.
 1.17 04-Jul-1997  christos branches: 1.17.2;
Fix compiler warnings.
 1.16 11-Apr-1997  christos Use #ifdef __STDC__ instead of #if __STDC__
 1.15 16-Oct-1996  christos PR/287: Shell does not exit with 126/127 when permission denied/
command not found. Add extra exception type and generalize
error handling routines to take that exception type. Use
a global variable exerrno to keep the last exec error.
 1.14 11-May-1995  christos branches: 1.14.6;
Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.13 23-Mar-1995  mycroft Fix typo in previous.
 1.12 21-Mar-1995  mycroft Use sigprocmask(), not sigsetmask().
 1.11 21-Mar-1995  cgd convert to new RCS id conventions.
 1.10 05-Dec-1994  cgd clean up further. more patches from Jim Jegers
 1.9 04-Dec-1994  cgd from James Jegers <jimj@miller.cs.uwm.edu>: quiet -Wall, and squelch
some of the worst style errors.
 1.8 11-Jun-1994  mycroft Add RCS ids.
 1.7 12-May-1994  jtc Include appropriate header files to bring function prototypes into scope.
 1.6 11-May-1994  jtc sync with 4.4lite
 1.5 05-Sep-1993  mycroft From Vincent Broman:
error.c: Add , in initializer list if ENOLINK defined.
output.c: Gratuitously remove extra ;.
mknodes.c: main() should return a value.
Not from Vincent Broman:
mknodes.c: main() should return an error condition when approriate, too.
 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.14.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.17.2.1 08-May-1998  mycroft Sync with trunk, per request of christos.
 1.20.2.1 19-Apr-1999  mycroft Pull up rev 1.21:
If we exit due to a SIGINT, do it with raise() so that the wait status is
correct in the parent.
 1.33.8.2 23-Mar-2008  matt sync with HEAD
 1.33.8.1 09-Jan-2008  matt sync with HEAD
 1.37.18.1 17-Apr-2012  yamt sync with head
 1.39.8.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.41.4.3 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.41.4.2 21-Apr-2020  martin Sync with HEAD
 1.41.4.1 10-Jun-2019  christos Sync with HEAD
 1.41.2.1 26-Jan-2019  pgoyette Sync with HEAD
 1.25 21-Mar-2023  hannken Use "sigjmp_buf loc" after switch to sigsetjmp()/siglongjmp().

Fixes errors and aborts on sparc at least.
 1.24 19-Mar-2023  kre Switch from using _setjmp()/_longjmp() (on BSD systems which aren't SVR4)
(and setjmp()/longjmp() elsewhere) to using sigsetjmp()/siglongjmp()
everywhere.

NFCI.
 1.23 19-Mar-2023  kre Change a few #defines from octal to hex (pdp11 days are long gone).
Improve the layout of those definitions at the same time.

NFC.
 1.22 04-Feb-2019  kre PR bin/53919

Suppress shell error messages while expanding $ENV (which also causes
errors while expanding $PS1 $PS2 and $PS4 to be suppressed as well).

This allows any random garbage that happens to be in ENV to not
cause noise when the shell starts (which is effectively all it did).

On a parse error (for any of those vars) we also use "" as the result,
which will be a null prompt, and avoid attempting to open any file for ENV.

This does not in any way change what happens for a correctly parsed command
substitution (either when it is executed when permitted for one of the
prompts, or when it is not (which is always for ENV)) and commands run
from those can still produce error output (but shell errors remain suppressed).
 1.21 19-Aug-2018  kre PR bin/48875 (is related, and ameliorated, but not exactly "fixed")

Import a whole set of tree evaluation enhancements from FreeBSD.

With these, before forking, the shell predicts (often) when all it will
have to do after forking (in the parent) is wait for the child and then
exit with the status from the child, and in such a case simply does not
fork, but rather allows the child to take over the parent's role.

This turns out to handle the particular test case from PR bin/48875 in
such a way that it works as hoped, rather than as it did (the delay there
was caused by an extra copy of the shell hanging around waiting for the
background child to complete ... and keeping the command substitution
stdout open, so the "real" parent had to wait in case more output appeared).

As part of doing this, redirection processing for compound commands gets
moved out of evalsubshell() and into a new evalredir(), which allows us
to properly handle errors occurring while performing those redirects,
and not mishandle (as in simply forget) fd's which had been moved out
of the way temporarily.

evaltree() has its degree of recursion reduced by making it loop to
handle the subsequent operation: that is instead of (for any binop
like ';' '&&' (etc)) where it used to
evaltree(node->left);
evaltree(node->right);
return;
it now does (kind of)
next = node;
while ((node = next) != NULL) {
next = NULL;

if (node is a binary op) {
evaltree(node->left);
if appropriate /* if && test for success, etc */
next = node->right;
continue;
}
/* similar for loops, etc */
}
which can be a good saving, as while the left side (now) tends to be
(usually) a simple (or simpleish) command, the right side can be many
commands (in a command sequence like a; b; c; d; ... the node at the
top of the tree will now have "a" as its left node, and the tree for
b; c; d; ... as its right node - until now everything was evaluated
recursively so it made no difference, and the tree was constructed
the other way).

if/while/... statements are done similarly, recurse to evaluate the
condition, then if the (or one of the) body parts is to be evaluated,
set next to that, and loop (previously it recursed).

There is more to do in this area (particularly in the way that case
statements are processed - we can avoid recursion there as well) but
that can wait for another day.

While doing all of this we keep much better track of when the shell is
just going to exit once the current tree is evaluated (with a new
predicate at_eof() to tell us that we have, for sure, reached the end
of the input stream, that is, this shell will, for certain, not be reading
more command input) and use that info to avoid unneeded forks. For that
we also need another new predicate (have_traps()) to determine of there
are any caught traps which might occur - if there are, we need to remain
to (potentially) handle them, so these optimisations will not occur (to
make the issue in PR 48875 appear again, run the same code, but with a
trap set to execute some code when a signal (or EXIT) occurs - note that
the trap must be set in the appropriate level of sub-shell to have this
effect, any caught traps are cleared in a subshell whenever one is created).

There is still work to be done to handle traps properly, whatever
weirdness they do (some of which is related to some of this.)

These changes do not need man page updates, but 48875 does - an update
to sh.1 will be forthcoming once it is decided what it should say...

Once again, all the heavy lifting for this set of changes comes directly
(with thanks) from the FreeBSD shell.

XXX pullup-8 (but not very soon)
 1.20 22-Jul-2018  kre NFC: better protect the INTON (etc) macros ( do { } while(0) )
This is just a kind of precaution, none of the uses actually
require the extra protection.
 1.19 15-Mar-2012  joerg branches: 1.19.32; 1.19.34;
Add __printflike attribution to use vprintf and friends with an argument
as format string.
 1.18 23-Aug-2011  christos branches: 1.18.2;
add more gcc printf format attributes
 1.17 29-Mar-2008  apb If SHELL_BUILTIN is defined (as will be the case when building external
builtins such as the printf command), then hide a few declarations.

This allows the shell to build again, fixing a problem with
"error" being declared as a function here, and as a variable in
.../usr.bin/printf/printf.c.
 1.16 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.15 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.14 04-Feb-2001  christos remove redundant declarations and nexted externs.
 1.13 09-Jul-1999  christos compile with WARNS = 2
 1.12 28-Jul-1998  mycroft Be more retentive about use of NOTREACHED and noreturn.
 1.11 15-Jul-1997  christos Don't re-define setjmp/longjmp in the svr4 case
 1.10 04-Jul-1997  christos Fix compiler warnings.
 1.9 16-Oct-1996  christos PR/287: Shell does not exit with 126/127 when permission denied/
command not found. Add extra exception type and generalize
error handling routines to take that exception type. Use
a global variable exerrno to keep the last exec error.
 1.8 11-May-1995  christos branches: 1.8.6;
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.8.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.18.2.1 17-Apr-2012  yamt sync with head
 1.19.34.3 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.19.34.2 21-Apr-2020  martin Sync with HEAD
 1.19.34.1 10-Jun-2019  christos Sync with HEAD
 1.19.32.2 06-Sep-2018  pgoyette Sync with HEAD

Resolve a couple of conflicts (result of the uimin/uimax changes)
 1.19.32.1 28-Jul-2018  pgoyette Sync with HEAD
 1.197 11-Nov-2024  kre This commit is intended to be what was intended to happen in the
commit of Sun Nov 10 01:22:24 UTC 2024, see:

http://mail-index.netbsd.org/source-changes/2024/11/10/msg154310.html

The commit message for that applies to this one (wholly). I believe that
the problem with that version which caused it to be reverted has been found
and fixed in this version (a necessary change was made as part of one of
the fixes, but the side-effect implications of that were missed -- bad bad me.)

In addition, I found some more issues with setting close-on-exec on other
command lines

With:
func 3>whatever

fd 3 (anything > 2) got close on exec set. That makes no difference
to the function itself (nothing gets exec'd therefore nothing gets closed)
but does to any exec that might happen running a command within the function.

I believe that if this is done (just as if "func" was a regular command,
and not a function) such open fds should be passed through to anything
they exec - unless the function (or other command) takes care to close the
fd passed to it, or explicitly turn on close-on exec.

I expect this usage to be quite rare, and not make much practical difference.

The same applies do builtin commands, but is even less relevant there, eg:

printf 3>whatever

would have set close-on-exec on fd 3 for printf. This is generally
completely immaterial, as printf - and most other built-in commands -
neither uses any fd other than (some of) 0 1 & 2, nor do they exec anything.

That is, except for the "exec" built-in which was the focus of the original
fix (mentioned above) and which should remain fixed here, and for the "."
command.

Because of that last one (".") close-on-exec should not be set on built-in
commands (any of them) for redirections on the command line. This will
almost never make a difference - any such redirections last only as long
as the built-in command lasts (same with functions) and so will generally
never care about the state of close-on-exec, and I have never seen a use
of the "." command with any redirections other than stderr (which is unaffected
here, fd's <= 2 never get close-on-exec set). That's probably why no-one
ever noticed.

There are still "fd issues" when running a (non #!) shell script, that
are hard to fix, which we should probably handle the way most other shells
have, by simply abandoning the optimisation of not exec'ing a whole new
shell (#! scripts do that exec) and just doing it that way. Issues solved!
One day.
 1.196 10-Nov-2024  kre Revert the recent change until I can work out how things are broken.
 1.195 10-Nov-2024  kre exec builtin command redirection fixes

Several changes, all related to the exec special built in command,
or to close on exec, one way or another. (Except a few white space
and comment additions, KNF, etc)

1. The bug found by Edgar Fuß reported in:
http://mail-index.netbsd.org/tech-userlevel/2024/11/05/msg014588.html
has been fixed, now "exec N>whatever" will set close-on-exec for fd N
(as do ksh versions, and allowed by POSIX, though other shells do not)
which has happened now for many years. But "exec cmd N>whatever"
(which looks like the same command when redirections are processed)
which was setting close-on-exec on N, now no longer does, so fd N
can be passed to cmd as an open fd.

For anyone who cares, the big block of change just after "case CMDBUILTIN:"
in evalcommand() in eval.c is the fix for this (one line replaced by
about 90 ... though most of that is comments or #if 0'd example code
for later). It is a bit ugly, and will get worse if our exec command
ever gets any options, as others have, but it does work.

2. when the exec builtin utility is used to alter the shell's redirections
it is now "all or nothing". Previously the redirections were executed
left to right. If one failed, no more were attempted, but the earlier
ones remained. This makes no practical difference to a non-interactive
shell, as a redirection error causes that shell to exit, but it makes
a difference to interactive shells. Now if a redirection fails, any
earlier ones which had been performed are undone. Note however that
side-effects of redirections (like creating, or truncating, files in
the filesystem, cannot be reversed - just the shell's file descriptors
returned to how they were before the error).

Similarly usage errors on exec now exist .. our exec takes no options
(but does handle "--" as POSIX says it must - has done for ages).
Until now, that was the only magic piece of exec, running
exec -a name somecommand
(which several other shells support) would attempt to exec the "-a"
command, and most likely fail, causing immediate exit from the shell.
Now that is a usage error - a non-interactive shell still exits, as
exec is a special builtin, and any error from a special builtin causes
a non-interactive shell to exit. But now, an interactive shell will
no longer exit (and any redirections that were on the command will be
undone, the same as for a redirection error).

3. When a "close on exec" file descriptor is temporarily saved, so the
same fd can be redirected for another command (only built-in commands
and functions matter, redirects for file system commands happen after
a fork() and at that stage if anything goes wrong, the child simply
exits - but for non-forking commands, doing something like printf >file
required the previous stdout to be saved elsewhere, "file" opened to
be the new stdout, then when printf is finished, the old stdout moved
back. Anyway, if the fd being moved had close on exec set, then
when it was moved back, the close on exec was lost. That is now fixed.

4. The fdflags command no longer allows setting close on exec on stdin,
stdout, or stderr - POSIX requires that those 3 fd's always be open
(to something) when any normal command is invoked. With close-on-exec
set on one of these, that is impossible, so simply refuse it (when
"exec N>file" sets close on exec, it only does it for N>2).

Minor changes (should be invisible)

a. The shell now keeps track of the highest fd number it sees doing
normal operations (there are a few internal pipe() calls that aren't
monitored and a couple of others, but in general the shell will now
know the highest fd it ever saw allocated to it). This is mostly
for debugging.

b. calls to fcntl() passing an int as the "arg" are now all properly
cast to the void * that the fcntl kernel is expecting to receive.
I suspect that makes no actual difference to anything, but ...
 1.194 21-Oct-2024  kre Add function names to relevant error messages.

When a shell detected error occurs while executing a function,
include the name of the function currently being executed in
the error message.
 1.193 03-Aug-2024  kre Change the "string" argument to evalstring() and setinputstring()
from being "char *" to being "const char *".

This is needed for a forthcoming change which needs to pass a const char *
to evalstring (and through it to setinputstring) and be assured that
nothing will alter the characters in the string supplied.

This is (aside from the additional compile time protection provided)
a no-op change, all evalstring() does with its string is pass it to
setinputstring() and all that does with it is determine its length
(strlen() which expects a const char *) and assign the string pointer
to parsenextc which is already a const char * - there never has been
any reason for these two functions to not include the "const" in
the arg declaration -- except that when originally written (early
1990's) I suspect "const" either didn't exist at all, or wasn't
supported by relevant compilers.

NFCI. Most probably (though I didn't check) no binary change at all.
 1.192 15-Jun-2024  kre branches: 1.192.2;
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.191 25-Dec-2023  kre PR bin/57773

Fix a bug reported by Jarle Fredrik Greipsland in PR bin/57773,
where a substring expansion where the substring to be removed from
a variable expansion is itself a var expansion where the value
contains one (or more) of sh's CTLxxx chars - the pattern had
CTLESC inserted, the string to be matched against did not. Fail.
We fix that by always inserting CTLESC in var assign expansions.
See the PR for all the gory details.

Thanks for the PR.

XXX pullup to everything.
 1.190 24-Jun-2023  msaitoh Fix typo in a debug message.
 1.189 07-Apr-2023  kre The great shell trailing whitespace cleanup of 2023...
Inspired by private e-mail comments from mouse@

NFCI.
 1.188 05-Jan-2022  kre branches: 1.188.2;

Use a volative local shadow of a field in an (on-stack) non-volatile struct
that is to be referenced after a return from setjmp() via longjmp().

This doesn't ever seem to have caused a problem, but I think using
volative vars is required here.

For reasons I never bothered to discover, even though this change
certainly requires a store into stack memory which wasn't required
before, earlier measurements showed the shell getting (slightly) smaller
with this change in place.

NFCI
 1.187 05-Dec-2021  msaitoh s/commmand/command/ in comment.
 1.186 22-Nov-2021  kre PR bin/53550

Here we go again... One more time to redo how here docs are
processed (it has been a few years since the last time!)

This is actually a relatively minor change, mostly to timimg
(to just when things happen). Now here docs are expanded at the
same time the "filename" word in a redirect is expanded, rather than
later when the heredoc was being sent to its process. This actually
makes things more consistent - but does break one of the ATF tests
which was testing that we were (effectively) internally inconsistent
in this area.

Not all shells agree on the context in which redirection expansions
should happen, some make any side effects visible to the parent shell
(the majority do) others do the redirection expansions in a subshell
so any side effcts are lost. We used to have a foot in each camp,
with the majority for everything but here docs, and the minority for
here docs. Now we're all the way with LBJ ... (or something like that).
 1.185 16-Nov-2021  kre Detect write errors to stdout, and exit(1) from some built-in
commands which (primarily) are used just to generate output
(or with a particular option combination do so).
 1.184 16-Nov-2021  kre Fix value of ${LINENO} in "for" commands.

This affects (as best I can tell) only uses of ${LINENO} in PS4
when -x is enabled (and perhaps only when the list contains no
expansions). "for" like "case" (which was already handled) is
special in that it generates trace output before actually executing
any kind of simple command.
 1.183 10-Nov-2021  kre DEBUG mode changes only. NFC (NC) for any normally compiled shell.

Mostly adding DEBUG mode tracing (when appropriate verbose tracing
is enabled generally) whenever a shell (including sushell) process
exits, so shells that the tracing should indicate why ehslls that
vanish did that.

Note for future investigators: if the relevant tracing is enabled,
and a (sub-)shell still simply seems to have vanished without trace,
the likely cause is that it was killed by a signal - and of those,
the most common that occurs is SIGPIPE.
 1.182 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.181 20-Aug-2020  kre Be less conservative about when we do clear_traps() when we have
traps_invalid (that is, when we actually nuke the parent shell's
caught traps in a subshell). This allows more reasonable use of
"trap -p" (and similar) in subshells than existed before (and in
particular, that command can be in a function now - there can also
be several related commands like
traps=$(trap -p INT; trap -p QUIT; trap -p HUP)
A side effect of all of this is that
(eval "$(trap -p)"; ...)
now allows copying caught traps into a subshell environment, if desired.

Also att the ksh93 variant (the one not picked by POSIX as it isn't
generally as useful) of "trap -p" (but call it "trap -P" which extracts
just the trap action for named signals (giving more than one is usually
undesirable). This allows
eval "$(trap -P INT)"
to run the action for SIGINT traps, without needing to attempt to parse
the "trap -p" output.
 1.180 14-May-2020  msaitoh Remove extra semicolon.
 1.179 23-Apr-2020  kre Stop forcing the -e option off in the subshell createds for a command
substitution. This was inherited in the big "-e" fixup patch set (rev 1.50)
of Jan 2000, which came from dash. dash no longer acts this way.
 1.178 04-Feb-2020  kre After bug report 262 (from 2010)
https://austingroupbugs.net/view.php?id=252
the Austin Group decided to require processing of "--" by the "."
and "exec" commands to solve a problem where some shells did
option processing for those commands (permitted) and others did
not (also permitted) which left no safe way to process a file
with a name beginning with "-".

This has finally made its way into what will be the next version of
the POSIX standard.

Since this shell did no option processing at all for those commands,
we need to update. This is that update.

The sole effect is that a "--" 'option' (to "." or "exec") is ignored.
This means that if you want to use "--" as the arg to one of those
commands, it needs to be given twice ". -- --". Apart from that there
should be no difference at all (though the "--" can now be used in other
situations, where we did not require it before, and still do not).
 1.177 21-Dec-2019  kre Use fork() rather than vfork() when forking to run a background
process with redirects. If we use vfork() and a redirect hangs
(eg: opening a fifo) which the parent was intended to unhang,
then the parent never gets to continue to unhang the child.

eg: mkfifo f; cat <f &; echo foo>f

The parent should not be waiting for a background process, even
just for its exec() to complete. if there are no redirects there
is (should be) nothing left that might be done that will cause any
noticeable delay, so vfork() should be safe in all other cases.
 1.176 09-Dec-2019  kre PR bin/54743

Having traps set should not enforce a fork for the next command,
whatever that command happens to be, only for commands which would
normally fork if they weren't the last command expected to be
executed (ie: builtins and functions shouldn't be exexuted in a
sub-shell merely because a trap is set).

As it was (for example)
trap 'whatever' SIGANY; wait $anypid
was guaranteed to fail the wait, as the subshell it was executed
in could not have any children.

XXX pullup -9
 1.175 04-May-2019  kre branches: 1.175.2;
When a return occurs in the test part of a loop statement (while/until)
(inside a function or dot script) the exit status of that return
statement should become the exit status of the function (or dot
script) - we were ignoring it,

That is
fn() { while return 7; do return 9; done; return 11; }
should exit with status 7. It was exiting 0.

This is apparently another old ash bug that has been fixed
everywhere else in the past.

Issue pointed out by Martijn Dekker, (fairly obvious) fix borrowed
from FreeBSD, due for return sometime next century.
 1.174 09-Feb-2019  kre DEBUG mode build changes - add extra trace output.

NFC for any normal shell build.
 1.173 09-Feb-2019  kre Delete extern decl for trap[] - hasn't been needed for a while now.
 1.172 09-Feb-2019  kre INTON / INTOFF audit and cleanup.

No visible differences expected - there is a remote chance that
some internal lossage may no longer occur in interactive shells
that receive SIGINT (untrapped) at inopportune times, but you would
have had to have been very unlucky to have ever suffered from that.
 1.171 04-Feb-2019  kre PR bin/53919

Suppress shell error messages while expanding $ENV (which also causes
errors while expanding $PS1 $PS2 and $PS4 to be suppressed as well).

This allows any random garbage that happens to be in ENV to not
cause noise when the shell starts (which is effectively all it did).

On a parse error (for any of those vars) we also use "" as the result,
which will be a null prompt, and avoid attempting to open any file for ENV.

This does not in any way change what happens for a correctly parsed command
substitution (either when it is executed when permitted for one of the
prompts, or when it is not (which is always for ENV)) and commands run
from those can still produce error output (but shell errors remain suppressed).
 1.170 21-Jan-2019  kre When we are about to execute something, and the traps are invalid
(which means this is the very first execution in a new subshell)
clear the traps completely, unless the command is "trap". We were
allowing any special builtin, which was probably harmless, but not
intended.

Also (though not required) permit "command trap" and "eval trap"
and combinations thereof, because they might be useful, and there is
no particular reason why not. This is all a part of making t=$(trap)
work as POSIX requires, but almost nothing beyond that. The "trap"
command must be alone (modulo eval and command) in the subshell for
the exception to apply, no t=$(trap; echo) or anything like that.

Martijn Dekker asked for "command trap" to work (no idea why though,
it converts "trap" from being a special builtin, to a normal one,
which means an error won't cause the shell to exit ... if there's
an error, the "trap" command won't do anything useful, and as we
permit no more commands (for this special treatment) the shell is
going to exit anyway, this difference is not really significant.
 1.169 09-Jan-2019  kre When an error occurs in a builtin from which we do not exit
(a normal builtin, though those are not genrally an issue for
this problem, or a special builtin that has been prefixed by "command")
make sure that we discard any pending input that might have been
queued up, but not yet processed.

We had the mechanism to fix this from when expansion of PS1 etc
was added (which has a similar problem to deal with) - all taken
from FreeBSD - but did not bother to use it here until now...

This fixes an error detected by newly added ATF tests of the eval
builtin, where
eval 'syntax error
another command'
would go ahead and evaluate "another command" which should not
happen (note: only when there was a \n between the two).
 1.168 03-Dec-2018  kre Cleanup traps a bit - attempt to handle weird uses in traps, such
as traps that issue break/continue/return to cause the loop/function
executing when the trap occurred to break/continue/return, and
generating the correct exit code from the shell including when a
signal is caught, but the trap handler for it exits.

All that from FreeBSD.

Also make
T=$(trap)
work as it is supposed to (also trap -p).

For now this is handled by the same technique as $(jobs) - rather
than clearing the traps in subshells, just mark them invalid, and
then whenever they're invalid, clear them before executing anything
other than the special blessed "trap" command. Eventually we will
handle these using non-subshell command substitution instead (not
creating a subshell environ when the commands in a command-sub alter
nothing in the environment).
 1.167 03-Dec-2018  kre Fix "export -x" (and its consequences) to behave as originally
intended (and as documented) rather than how it has been behaving
(which was not very rational.) Since it is unlikely that anyone
is using this, the change should be mostly invisible.

While here, a couple of other minor cleanups:
. One call of geteuid() is enough in choose_ps1()
. Fix a typo in a comment
. Improve appearance (whitspace changes) in find_var()
 1.166 03-Dec-2018  kre Revamp aliases - as dumb an idea as they are, if we're going
to have them, they should work as documented, not cause core
dumps, reference after free, incorrect replacements, failing
to implement alias after alias, ...

The big comment that ended:
This is a good idea ------- ***NOT***
and the hack it was describing are gone.

Note that most of this was from original CVS version 1.1
code (ie: came from the original import, even before 4.4-Lite
was merged. That is, May 1994. And no-one in 24.5 years
noticed (or at least complained about) all the bugs (or at
least, most of them)).

With these changes, aliases ought to work (if you can call it
that) as they are expected to by POSIX. Now if only we could
get POSIX to delete them (or make them optional)...

Changes partly inspired by similar changes made by FreeBSD,
(as was the previous change to alias.c, forgot ack in commit
log for that one, apologies) but done a little differently,
and perhaps with a slightly better outcome.
 1.165 30-Nov-2018  kre It is not only the EXIT trap we need to check for when deciding no
fork is required, but any trap (dumb mistake...)

XXX - include in 48875 pullup to -8
 1.164 26-Nov-2018  kre Make it be that an empty command is treated as a regular builtin
for the purposes of any redirects it might have -- ie: as posix
requires, make the redirects appear to have been executed in a subshell
environment, so if one fails, aside from a diagnositc msg, all the
running script sees is a command that failed ($? != 0), rather
that having the shell exit which used to happen (the empty command was
being treated as a special builtin).

Continue to treat the empty command as special for the purposes of
var assigns it might contain (those are not executed in a sub-shell
and persist) - an error there (eg: assigning to a readonly var) will
continue to cause the shell (non-interactive shell) to exit.

This makes the NetBSD shell behave like all other (reasonably modern)
shells - fix method (not the implementation, details differ) taken from
FreeBSD who fixed this back in early 2010. Problem pointed out
in (non-list) mail by Martijn Dekker.
 1.163 23-Nov-2018  kre Handle eval $'continue\ncommand' (and similar) in a loop correctly ...
"command" should not be executed. (The issue affects multi-line
eval strings only - ie: commands after the next \n are not skipped).

Bug noted by Martijn Dekker in off-list e-mail.

Fix from FreeBSD:
src/bin/sh/eval.c: Revision 272983 Sun Oct 12 13:12:06 2014 UTC by jilles
 1.162 09-Oct-2018  kre When (about to) send the -x output for the end of a compound command
(which has redirects, and so is included in -x output) use the -x/+x
setting that existed when the comoound started, so if the state of
xtrace changes during the command we don't end up with just half of
the -x output (either the intro, or the conclusion, depending on
which way the change happened). [this also happens to avoid a core
dump in the previous code, but that could have been done other ways,
this way actually simplifies things (less code)]
 1.161 25-Aug-2018  kre PR bin/53548

Deal with the new shell internal exit reason EXEXIT in the case of
a shell which has vfork()'d. It takes a peculiar set of circumstances
to get into a situation where this is ever relevant, but it can be
done. See the PR for details.
 1.160 22-Aug-2018  kre Fix (hopefully) the problem reported on current-users by Patrick Welche.
we had incorrect usage of setstackmark()/popstackmark()

There was an ancient idiom (imported from CSRG in 1993) where code
can do:
setstackmark(&smark); loop until whatever condition {
/* do lots of code */ popstackmark(&smark);
} popstackmark(&smark);

The 1st (inner) popstackmark() resets the stack, conserving memory,
The 2nd one is needed just in case the "whatever condition" was never
true, and the first one was never executed.

This is (was) safe as all popstackmark() did was reset the stack.
That could be done over and over again with no harm.

That is, until 2000 when a fix from FreeBSD for another problem was
imported. That connected all the stack marks as a list (so they can be
located). That caused the problem, as the idiom was not changed, now
there is this list of marks, and popstackmark() was removing an entry.

It rarely (never?) caused any problems as the idiom was rarely used
(the shell used to do loops like above, mostly, without the inner
popstackmark()). Further, the stack mark list is only ever used when
a memory block is realloc'd.

That is, until last weekend - with the recent set of changes.

Part of that copied code from FreeBSD introduced the idiom above
into more functions - functions used much more, and with a greater
possibility of stack marks being set on blocks that are realloc'd
and so cause the problem. In the FreeBSD code, they changed the idiom,
and always do a setstackmark() immediately after the inner popstackmark().
But not for reasons related to a list of stack marks, as in the
intervening period, FreeBSD deleted that, but for another reason.

We do not have their issue, and I did not believe that their
updated idiom was needed (I did some analysis of exactly this issue -
just missed the important part!), and just continued using the old one.
Hence Patrick's core dump....

The solution used here is to split popstackmark() into 2 halves,
popstackmark() continues to do what it has (recently) done,
but is now implemented as a call of (a new func) rststackmark()
which does all the original work of popstackmark - but not removing
the entry from the stack mark list (which remains in popstackmark()).
Then in the idiom above, the inner popstackmark() turns into a call of
rststackmark() so the stack is reset, but the stack mark list is
unchanged. Tail recursion elimination makes this essentially free.
 1.159 19-Aug-2018  kre PR bin/48875 (is related, and ameliorated, but not exactly "fixed")

Import a whole set of tree evaluation enhancements from FreeBSD.

With these, before forking, the shell predicts (often) when all it will
have to do after forking (in the parent) is wait for the child and then
exit with the status from the child, and in such a case simply does not
fork, but rather allows the child to take over the parent's role.

This turns out to handle the particular test case from PR bin/48875 in
such a way that it works as hoped, rather than as it did (the delay there
was caused by an extra copy of the shell hanging around waiting for the
background child to complete ... and keeping the command substitution
stdout open, so the "real" parent had to wait in case more output appeared).

As part of doing this, redirection processing for compound commands gets
moved out of evalsubshell() and into a new evalredir(), which allows us
to properly handle errors occurring while performing those redirects,
and not mishandle (as in simply forget) fd's which had been moved out
of the way temporarily.

evaltree() has its degree of recursion reduced by making it loop to
handle the subsequent operation: that is instead of (for any binop
like ';' '&&' (etc)) where it used to
evaltree(node->left);
evaltree(node->right);
return;
it now does (kind of)
next = node;
while ((node = next) != NULL) {
next = NULL;

if (node is a binary op) {
evaltree(node->left);
if appropriate /* if && test for success, etc */
next = node->right;
continue;
}
/* similar for loops, etc */
}
which can be a good saving, as while the left side (now) tends to be
(usually) a simple (or simpleish) command, the right side can be many
commands (in a command sequence like a; b; c; d; ... the node at the
top of the tree will now have "a" as its left node, and the tree for
b; c; d; ... as its right node - until now everything was evaluated
recursively so it made no difference, and the tree was constructed
the other way).

if/while/... statements are done similarly, recurse to evaluate the
condition, then if the (or one of the) body parts is to be evaluated,
set next to that, and loop (previously it recursed).

There is more to do in this area (particularly in the way that case
statements are processed - we can avoid recursion there as well) but
that can wait for another day.

While doing all of this we keep much better track of when the shell is
just going to exit once the current tree is evaluated (with a new
predicate at_eof() to tell us that we have, for sure, reached the end
of the input stream, that is, this shell will, for certain, not be reading
more command input) and use that info to avoid unneeded forks. For that
we also need another new predicate (have_traps()) to determine of there
are any caught traps which might occur - if there are, we need to remain
to (potentially) handle them, so these optimisations will not occur (to
make the issue in PR 48875 appear again, run the same code, but with a
trap set to execute some code when a signal (or EXIT) occurs - note that
the trap must be set in the appropriate level of sub-shell to have this
effect, any caught traps are cleared in a subshell whenever one is created).

There is still work to be done to handle traps properly, whatever
weirdness they do (some of which is related to some of this.)

These changes do not need man page updates, but 48875 does - an update
to sh.1 will be forthcoming once it is decided what it should say...

Once again, all the heavy lifting for this set of changes comes directly
(with thanks) from the FreeBSD shell.

XXX pullup-8 (but not very soon)
 1.158 19-Aug-2018  kre PR bin/48875

Revert the changes that were made 19 May 2016 (principally eval.c 1.125)
and the bug fixes in subsequent days (eval.c 1.126 and 1.127) and also
update some newer code that was added more recently which acted in
accordance with those changes (make that code be as it would have been
if the changes now being reverted had never been made).

While the changes made did solve the problem, in a sense, they were
never correct (see the PR for some discussion) and it had always been
intended that they be reverted. However, in practical sh code, no
issues were reported - until just recently - so nothing was done,
until now...

After this commit, the validate_fn_redirects test case of the sh ATF
test t_redir will fail. In particular, the subtest of that test
case which is described in the source (of the test) as:
This one is the real test for PR bin/48875
will fail.

Alternative changes, not to "fix" the problem in the PR, but to
often avoid it will be coming very soon - after which that ATF
test will succeed again.

XXX pullup-8
 1.157 14-Aug-2018  kre PR bin/42184 PR bin/52687 (detailing the same bug).

Fix "command not found" handling so that the error message
goes to stderr (after any redirections are applied).

More importantly, in

foo > /tmp/junk

/tmp/junk should be created, before any attempt is made
to execute (the assumed non-existing) "foo".

All this was always true for any command (not found command)
containing a / in its name

foo/bar >/tmp/junk 2>>/tmp/errs

would have created /tmp/junk, then complained (in /tmp/errs)
about foo/bar not being found. Now that happens for ordinary
commands as well.

The fix (which I found when I saw differences between our
code and FreeBSD's, where, for the benefit of PR 42184,
this has been fixed, sometime in the past 9 years) is
frighteningly simple. Simply do not short circuit execution
(or print any error) when the initial lookup fails to
find the command - it will fail anyway when we actually
try running it. The cost is a (seemingly unnecessary,
except that it really is) fork in this case.

This is what I had been planning, but I expected it would
be much more difficult than it turned out....

XXX pullup-8
 1.156 25-Jul-2018  kre Fix several bugs in the command / type builtin ( including PR bin/48499 )

1. Make command -pv (and -pV) work (which is not as easy as the PR
suggests it might be (the "check and cause error" was there because
it did not work, not in order to prevent it from working).

2. Stop -v and -V being both used (that makes no sense).

3. Stop the "type" builtin inheriting the args (-pvV) that "command" has
(which it did, as when -v -or -V is used with command, it and type are
implemented using the same code).

4. make "command -v word" DTRT for sh keywords (was treating them as an error).

5. Require at least one arg for "command -[vV]" or "type" else usage & error.
Strictly this should also apply to "command" and "command -p" (no -v)
but that's handled elsewhere, so perhaps some other time. Perhaps
"command -v" (and -V) should be limited to 1 command name (where "type"
can have many) as in the POSIX definitions, but I don't think that matters.

6. With "command -V alias", (or "type alias" which is the same thing),
(but not "command -v alias") alter the output format, so we get
ll is an alias for: ls -al
instead of the old
ll is an alias for
ls -al
(and note there was a space, for some reason, after "for")

That is, unless the alias value contains any \n characters, in which
case (something approximating) the old multi-line format is retained.
Also note: that if code wants to parse/use the value of an alias, it
should be using the output of "alias name", not command or type.

Note that none of the above affects "command [-p] cmd" (no -v or -V options)
only "command -[vV]" and "type".

Note also that the changes to eval.[ch] are merely to make syspath()
visible in exec.c rather than static in eval.c
 1.155 22-Jun-2018  kre branches: 1.155.2;
Deal with ref after free found by ASAN when a function redefines
itself, or some other function which is still active.
This was a long known bug (fixed ages ago in the FreeBSD sh) which
hadn't been fixed as in practice, the situation that causes the
problem simply doesn't arise .. ASAN found it in the sh dotcmd
tests which do have this odd "feature" in the way they are written
(but where it never caused a problem, as the tests are so simple
that no mem is ever allocated between when the old version of the
function was deleted, and when it finished executing, so its code
all remained intact, despite having been freed.)

The fix is taken from the FreeBSD sh.

XXX -- pullup-8 (after a while to ensure no other problems arise).
 1.154 17-Jun-2018  kre NFC: correct typo in a comment.
 1.153 19-Nov-2017  kre branches: 1.153.2;
Implement the -X option - an apparent variant of -x which sends all trace
output to the stderr which existed when the -X option was (last) enabled.
It also enables tracing by enabling -x (and when reset, +X, also resets
the 'x' flag (+x)). Note that it is still -x/+x which actually
enables/disables the trace output. Hence "apparent variant" - what -X
actually does (aside from setting -x) is just to lock the trace output,
rather than having it follow wherever stderr is later redirected.
 1.152 29-Sep-2017  kre DEBUG only changes (non-debug, ie: normal, shell unaffected)
Add a little extra info in a few of the trace messages.
 1.151 30-Jun-2017  kre Include redirections in trace output from "set -x"
 1.150 19-Jun-2017  kre Another fix from FreeBSD (this one from April 2009).

When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.

That is:
sh -c 'false

'
echo $?
should produce 1, not 0.
 1.149 19-Jun-2017  kre Fix from FreeBSD (applied there in July 2008...)

Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
 1.148 17-Jun-2017  kre NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
 1.147 17-Jun-2017  kre Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).

Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)

From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
 1.146 08-Jun-2017  kre Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
 1.145 08-Jun-2017  kre I am an idiot... revert the previous unintended commit.
 1.144 08-Jun-2017  kre Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
 1.143 07-Jun-2017  kre A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)

This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)

The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.

This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).

I would not call the results of this perfect yet, but it is close.
 1.142 07-Jun-2017  kre An initial attempt at implementing LINENO to meet the specs.

Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.

Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)

This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.

POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)

This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.

This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).

Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
 1.141 04-Jun-2017  kre Make cd (really) do cd -P, and not just claim that is what it is doing
while doing a half-hearted, broken, partial, version of cd -L instead.
The latter (as the manual says) is not supported, what's more, it is an
abomination, and should never be supported (anywhere.)

Fix the doc so that the pretense that we notice when a path given crosses
a symlink (and turns on printing of the destination directory) is claimed
no more (that used to be true until late Dec 2016, but was changed). Now
the print happens if -o cdprint is set, or if an entry from CDPATH that is
not "" or "." is used (or if the "cd dest repl" cd cmd variant is used.)

Fix CDPATH processing: avoid the magic '%' processing that is used for
PATH and MAILPATH from corrupting CDPATH. The % magic (both variants)
remains undocumented.

Also, don't double the '/' if an entry in PATH or CDPATH ends in '/'
(as in CDPATH=":/usr/src/"). A "cd usr.bin" used to do
chdir("/usr/src//usr.bin"). No more. This is almost invisible,
and relatively harmless, either way....

Also fix a bug where if a plausible destination directory in CDPATH
was located, but the chdir() failed (eg: permission denied) and then
a later "." or "" CDPATH entry succeeded, "print" mode was turned on.
That is:
cd /tmp; mkdir bin
mkdir -p P/bin; chmod 0 P/bin
CDPATH=/tmp/P:
cd bin
would cd to /tmp/bin (correctly) but print it (incorrectly).

Also when in "cd dest replace" mode, if the result of the replacement
generates '-' as the path named, as in:
cd $PWD -
then simply change to '-' (or attempt to, with CDPATH search), rather
than having this being equivalent to "cd -")

Because of these changes, the pwd command (and $PWD) essentially
always acts as pwd -P, even when called as pwd -L (which is still
the default.) That is, even more than it did before.

Also fixed a (kind of minor) mem management error (CDPATH related)
"whosoever shall padvance must stunalloc before repeating" (and the
same for MAILPATH).
 1.140 13-May-2017  kre branches: 1.140.2;

The beginnings of the great shell DEBUG (tracing) upgrade of 2017...

First, be aware that the DEBUG spoken of here has nothing whatever to
do with MKDEBUG=true type builds of NetBSD. The only way to get a
DEBUG shell is to build it yourself manually.

That said, for non-DEBUG shells, this change makes only one slight
(trivial really) difference, which should affect nothing.

Previously some code was defined like ...

function(args)
{
#ifdef DEBUG
/* function code goes here */
#endif
}

and called like ...

#ifdef DEBUG
function(params);
#endif

resulting in several empty functions that are never called being
defined in non-DEBUG shells. Those are now gone. If you can detect
the difference any way other than using "nm" or similar, I'd be very
surprised...

For DEBUG shells, this introduces a whole new TRACE() setup to use
to assist in debugging the shell.

I have had this locally (uncommitted) for over a year... it helps.

By itself this change is almost useless, nothing really changes, but
it provides the framework to allow other TRACE() calls to be updated
over time. This is why I had not committed this earlier, my previous
version required a flag day, with all the shell's internal tracing
being updated a once - which I had done, but that shell version has
bit-rotted so badly now it is almost useless...

Future updates will add the mechanism to allow the new stuff to actually
be used in a productive way, and following that, over time, gradual
conversion of all the shell tracing to the updated form (as required,
or when I am bored...)

The one useful change that we do get now is that the fd that the shell
uses for tracing (which was usually 3, but not any more) is now protected
from user/script interference, like all the other shell inernal fds.

There is no doc (nor will there be) on any of this, if you are not reading
the source code it is useless to you, if you are, you know how it works.
 1.139 09-May-2017  kre If we are going to permit
! ! pipeline
(And for now the other places where ! is permitted)
we should at least generate the logically correct exit
status:
! ! (exit 5); echo $?
should print 1, not 5. ksh and bosh do it this way - and it makes sense.
bash and the FreeBSD sh echo "5" (as did we until now.)
dash, zsh, yash all enforce the standard syntax, and prohibit this.
 1.138 09-May-2017  kre Remove a now unnecessary (ater the changes in 1.136) clearing of EV_EXIT.
(NFC, but should save a byte or two of code space.)
 1.137 09-May-2017  kre NFC: whitespace (indentation).
 1.136 09-May-2017  kre Fix some bogus usage of EV_EXIT in evaltree(). Fix (somewhat) inspired
by FreeBSD sh (though different, for other reasons) - but the bug discovered
while searching for why a (nonsense) attempted test of the forthcoming
code to handle "! ! pipeline" properly wasn't working... (it was how I was
testing it that was broken, but until I achieved enlightenment, I was bug
hunting, and found this...)

Most likely the bugs here wouldn't have affected any real code (no bug
reports anyway), but ...
 1.135 07-May-2017  kre POSIX says that the arg to break or continue is to be a positive integer
(by which they mean > 0). We were checking for negative numbers, but
not for 0. More by chance of the implementation than any specific design
(I suspect) "break 0" was being treated the same as "break" or "break 1".
Since 3 ways to achieve the same thing is overkill, let's do what posix
wants and forbid "break 0" and "continue 0".
 1.134 04-May-2017  kre Implement the ';&' (used instead of ';;') case statement list terminator
which causes fall through the to command list of the following pattern
(wuthout evaluating that pattern). This has been approved for inclusion
in the next major version of the POSIX standard (Issue 8), and is
implemented by most other shells.

Now all form a circle and together attempt to summon the great wizd
in the hopes that his magic spells can transform the poor attempt
at documenting this feature into something rational...
 1.133 03-May-2017  kre So sayeth posix (of the special builtin "eval"):
If there are no arguments, or only null arguments,
eval shall return a zero exit status;

Make it so. Now:
false; eval; echo $?
produces 0 instead of 1.
 1.132 03-May-2017  kre Correct a dsl comment relating to setting $_ - I thought I had done
this ages ago, but apparently not...
 1.131 22-Apr-2017  kre branches: 1.131.2;

When -x is set, show assignments to the loop variable in a for loop.
 1.130 02-Feb-2017  christos Who Ride Wit Us?
 1.129 10-Jan-2017  christos branches: 1.129.2;
add missing <sys/stat.h>
 1.128 01-Jun-2016  kre branches: 1.128.2;

PR bin/43639

Redo earlier fix to only prohibit sourcing directories and block special files.
char specials (/dev/tty, /dev/null, ... incl /dev/rwd0a) and fifos are OK.

Posix actually requires that we find only readable files - that is not yet
implemented (doing it sanely, without opening the file twice, is going to
take some more modifications to code elsewhere).
 1.127 13-May-2016  kre More fallout from the fix for PR bin/48875 - this one found just by
code reading, rather than any actual real use case failing.

With this script
f()
{
echo hello $1
}

exec 3>&1
echo $(
for i in a b c
do
echo @$i
f >&3
done >/tmp/foo
)
echo foo= $(cat /tmp/foo)

what should be output is

hello
hello
hello

foo= @a @b @c

but since the (my) 48875 fix the other day, we've been getting

hello
@b
hello
@c
hello

foo= @a

This fixes that. I think (hope) this is the last of these fixes...
 1.126 10-May-2016  kre PR bin/48875 - minor correction (well, not so minor) - commands in loops
must be assumed to have something following, even if the loop itself doesn't,
so redirected fd's around func calls need to be saved. Should fix etcupdate
 1.125 09-May-2016  kre PR bin/48875 - avoid holding (replaced) file descriptors open when running a
command in the current shell (so they can be restored for the next command)
in cases where it is obvious that there is not going to be a following
command to use them. This fixes the problem reported in the PR (though
there are still plenty of situations where a FD could be closed but isn't,
we do not do full fd flow eveluation to determine whether a fd will be
used or not).

This is the change that was just committed and then backed out again...

OK christos@
 1.124 09-May-2016  kre Revert previous. These changes are intended to get made (and will
be in a minute or two) but not as part of that commit... The log
entry certainly does not apply.
 1.123 09-May-2016  kre Finish the fd reassignment fixes from 1.43 and 1.45 ... if we are moving
a fd to an unspecified high fd number, we certainly do not want to hand
that high fd off to other processes after an exec, so always set close-on-exec
on the result (even if lack of fd's means no fd alteration happens.)
This will (eventually) allow some other code that sets close-on-exec to
be removed, but for now, doing it twice won't hurt. Also, in a N>&M
type redirection, do not set close-on-exec if we don't want it.

OK christos@
 1.122 03-May-2016  kre Fix things so that STATIC can me made static (-DSTATIC=static)
and have the shell still compile, link, and run...

ok christos@
 1.121 03-May-2016  kre PR bin/43639 - check that a file being read by the '.' command
is a regular file, even when it is given as a full pathname.
 1.120 02-May-2016  christos Fix handing of user file descriptors outside the 0..9 range.
Also, move (most of) the shell's internal use fd's to much
higher values (depending upon what ulimit -n allows) so they
are less likely to clash with user supplied fd numbers. A future
patch will (hopefully) avoid this problem completely by dynamically
moving the shell's internal fds around as needed. (From kre@)
 1.119 16-Mar-2016  christos Keep redirs for subshells.
 1.118 13-Mar-2016  christos We want this to work too:
$ cat sep1
#!/bin/sh
{ ./sep2; } 3>out

$ cat sep2
#!/bin/sh
echo sep2 >&3

$ ./sep1
 1.117 12-Mar-2016  christos Don't close-on-exec redirections created explicitly for the command being
ran; i.e. we want this to work:
$ cat succ1
#!/bin/sh
./succ2 6>out

$ cat succ2
#!/bin/sh
echo succ2 >&6

$ ./succ1

And this to fail:
$ cat fail1
#!/bin/sh
exec 6> out
echo "fail1" >&6
./fail2
exec 6>&-

$ cat fail2
#!obj.amd64/sh
echo "fail2" >&6

$ ./fail1
./fail2: 6: Bad file descriptor

XXX: Do we want a -k (keep flag on exec to make redirections not close-on-exec?
 1.116 12-Mar-2016  christos Improve quoting in the output from sh -x - use less unnecessary
quotes ('_' and '.' do not need quoting) and never quote the '=' in
an assignment (or it would not be one.) From kre, with some refactoring
to be blamed to me.
 1.115 29-Feb-2016  christos Complete implementation of the noexec option (-n) including
disabling noexec, if the shell is interactive, each time that
a new command is about to be read. Also correct the -I
(ignoreeof) option so that it only applies to interactive shells,
as required by posix. (from kre)
 1.114 27-Feb-2016  christos Improve debugging, from kre (I hooked it to the build).
 1.113 24-Feb-2016  christos PR/46327: David Mandelberg: Fix exit codes of background jobs (from kre)
 1.112 22-Feb-2016  christos PR/43255: Make -n apply to the -c string so sh -n -c 'commands' works
as it should. Also, other places where the shell parses strings of
commands are also now controlled by -n (traps, eval, ...) (from kre)
 1.111 04-Jan-2016  christos Don't leak redirected rescriptors to exec'ed processes. This is what ksh
does, but bash does not. For example:

$ cat test1
#!/bin/sh
exec 6> out
echo "test" >&6
sh ./test2
exec 6>&-
$ cat test2
echo "test2" >&6
$ ./test1
./test2: 6: Bad file descriptor

This fixes by side effect the problem of the rc system leaking file descriptors
7 and 8 to all starting daemons:

$ fstat -p 1359
USER CMD PID FD MOUNT INUM MODE SZ|DV R/W
root powerd 1359 wd / 2 drwxr-xr-x 512 r
root powerd 1359 0 / 63029 crw-rw-rw- null rw
root powerd 1359 1 / 63029 crw-rw-rw- null rw
root powerd 1359 2 / 63029 crw-rw-rw- null rw
root powerd 1359 3* kqueue pending 0
root powerd 1359 4 / 64463 crw-r----- power r
root powerd 1359 7 flags 0x80034<ISTTY,MPSAFE,LOCKSWORK,CLEAN>
root powerd 1359 8 flags 0x80034<ISTTY,MPSAFE,LOCKSWORK,CLEAN>
root powerd 1359 9* pipe 0xfffffe815d7bfdc0 -> 0x0 w

Note fd=7,8 pointing to the revoked pty from the parent rc process.
 1.110 02-Jan-2015  christos Define an undocumented -F option to only use fork instead of vfork for
debugging purposes.
 1.109 31-May-2014  christos PR/48843: Jarmo Jaakkola: dot commands mess up scope nesting tracking

Evaluation of commands goes completely haywire if a file containing
a break/continue/return command outside its "intended" scope is sourced
using a dot command inside its "intended" scope. The main symptom is
not exiting from the sourced file when supposed to, leading to evaluation
of commands that were not supposed to be evaluated. A secondary symptom
is that these extra commands are not evaluated correctly, as some of them
are skipped. Some examples are listed in the How-To-Repeat section.

According to the POSIX standard, this is how it should work:
dot:
The shell shall execute commands from the file in the current
environment.
break:
The break utility shall exit from the smallest enclosing for, while,
or until loop, [...]
continue:
The continue utility shall return to the top of the smallest
enclosing for, while, or until loop, [...]
return:
The return utility shall cause the shell to stop executing
the current function or dot script. If the shell is not currently
executing a function or dot script, the results are unspecified.

It is clear that return should return from a sourced file, which
it does not do. Whether break and continue should work from the sourced
file might be debatable. Because the dot command says "in the current
environment", I'd say yes. In any case, it should not fail in weird
ways like it does now!

The problems occur with return (a) and break/continue (b) because:
1) dotcmd() does not record the function nesting level prior to
sourcing the file nor does it touch the loopnest variable,
leading to either
2 a) returncmd() being unable to detect that it should not set
evalskip to SKIPFUNC but SKIPFILE, or
b) breakcmd() setting evalskip to SKIPCONT or SKIPBREAK,
leading to
3) cmdloop() not detecting that it should skip the rest of
the file, due to only checking for SKIPFILE.
The result is that cmdloop() keeps executing lines from the file
whilst evalskip is set, which is the main symptom. Because
evalskip is checked in multiple places in eval.c, the secondary
symptom appears.
>How-To-Repeat:
Run the following script:

printf "break\necho break1; echo break2" >break
printf "continue\necho continue1; echo continue2" >continue
printf "return\necho return1; echo return2" >return

while true; do . ./break; done

for i in 1 2; do . ./continue; done

func() {
. ./return
}
func

No output should be produced, but instead this is the result:
break1
continue1
continue1
return1

The main symptom is evident from the unexpected output and the secondary
one from the fact that there are no lines with '2' in them.
>Fix:
Here is patch to src/bin/sh to fix the above problems. It keeps
track of the function nesting level at the beginning of a dot command
to enable the return command to work properly.

I also changed the undefined-by-standard functionality of the return
command when it's not in a dot command or function from (indirectly)
exiting the shell to being silently ignored. This was done because
the previous way has at least one bug: the shell exits without asking
for confirmation when there are stopped jobs.

Because I read the standard to mean that break and continue should have
an effect outside the sourced file, that's how I implemented it. For what
it's worth, this also seems to be what bash does. Also laziness, because
this way required no changes to loopnesting tracking. If this is not
wanted, it might make sense to move the nesting tracking to the inputfile
stack.

The patch also does some clean-up to reduce the amount of global
variables by moving the dotcmd() and the find_dot_file() functions from
main.c to eval.c and making in_function() a proper function.
 1.108 26-Jan-2014  christos branches: 1.108.2;
explain why forks fail
 1.107 27-Jun-2013  yamt fix descriptor leaks. PR/47805

this fix was taken from FreeBSD SVN rev 199953 (Jilles Tjoelker)
------------------------------------------------------------------------
r199953 | jilles | 2009-11-30 07:33:59 +0900 (Mon, 30 Nov 2009) | 16 lines

Fix some cases where file descriptors from redirections leak to programs.

- Redirecting fds that were not open before kept two copies of the
redirected file.
sh -c '{ :; } 7>/dev/null; fstat -p $$; true'
(both fd 7 and 10 remained open)
- File descriptors used to restore things after redirection were not
set close-on-exec, instead they were explicitly closed before executing
a program normally and before executing a shell procedure. The latter
must remain but the former is replaced by close-on-exec.
sh -c 'exec 7</; { exec fstat -p $$; } 7>/dev/null; true'
(fd 10 remained open)

The examples above are simpler than the testsuite because I do not want to
use fstat or procstat in the testsuite.
 1.106 02-Mar-2013  christos PR/47608: Robert Elz: ``var=value func-call'' does not export var in the
function (+FIX)
 1.105 02-Jan-2013  dsl include limits.h for CHAR_MIN
 1.104 14-Jun-2012  joerg branches: 1.104.2;
Make sure temp_path is always initialised, even if mklocal fails.
Make sure to restore localvars, even if possibly leaking memory.
Discussed with christos@
 1.103 14-Nov-2011  christos PR/45613: Aleksey Cheusov: /bin/sh: 'set -e' + 'if eval false' problem
Fixed from: http://www.freebsd.org/cgi/query-pr.cgi?pr=134881&cat=
 1.102 31-Aug-2011  plunky branches: 1.102.2;
NULL does not need a cast
 1.101 17-Feb-2011  pooka Tell copyfd if the caller wants the exact tofd to just fd >= tofd.
Fixes "echo foo > /rump/bar" in a rump hijacked shell.

reviewed by christos
 1.100 03-Jun-2010  christos branches: 1.100.2;
need errno for the debug build.
 1.99 03-Jun-2010  christos set -e is supposed to work inside eval; skip EV_TESTED.
 1.98 07-Oct-2009  christos only for when trap if we are going to exit.
 1.97 06-Oct-2009  christos fix regression exit1: Don't exec the last command in a subshell if it has
trap[0] (trap EXIT) set. Fork instead to give the shell a chance to execute
the trap when it is done.
 1.96 19-Jan-2009  christos Revert previous commit that fixes PR/36079 (shell misses exit trap), because
the fix causes $! to point to the wrong process in pipelines, which is worse.
 1.95 21-Dec-2008  christos PR/36079: M. Levinson: Disable the optimization of not forking for the last
command in a subshell, otherwise we miss the exit trap.
 1.94 31-Oct-2008  christos show better quoting output for sh -x, from Aleksey Cheusov
 1.93 26-May-2008  tron Revert revisions 1.91 and 1.92. The POSIX spec about the correct behaviour
is contradictory at best. And these changes seem to cause more problems
that they are worth.
 1.92 24-May-2008  tron Fix two more cases of bad handling of "set -e":
- false && false
- false || false
 1.91 24-May-2008  tron Fix another problem with "set -e": "! true" should terminate the shell.
 1.90 24-May-2008  tron Port revision 1.44 of "src/bin/sh/eval.c" from FreeBSD to fix PR bin/38584.
Reviewed by Michael van Elst.
 1.89 15-Feb-2008  matt branches: 1.89.4; 1.89.6;
Fix inconsistent definitions
 1.88 16-Oct-2006  christos branches: 1.88.2; 1.88.4; 1.88.8;
sprinkle volatile.
 1.87 13-May-2006  christos Coverity CID 3384: Don't close -1.
 1.86 18-Apr-2006  christos PR/33281: Martin J. Laubach: Prevent core-dump on "echo abc | { }". bash
prints and error and ksh prints nothing. We go the ksh way.
 1.85 17-Mar-2006  christos Coverity CID 2479: Clarify confusion about uninitialized variable in the
presence of setjmp/vfork.
 1.84 23-Jun-2005  christos Revert part of the previous commit. We cannot fix the problem by not waiting.
The problem is that the subshell code is not doing redirections properly.
 1.83 22-Jun-2005  christos Don't wait for a background job in a subshell when we are set to EV_EXIT.
While I am here, call forkshell() explicitly FORK_FOO flags instead of
depending in FORK_FG == 0 and FORK_BG == 1.
 1.82 01-Jun-2005  lukem Mark temp_path volatile so that it won't get clobbered after longjmp.
(Also appeases gcc -Wuninitialized.)
 1.81 02-Mar-2005  dsl branches: 1.81.2;
Fix printing of invalid commandname after certain types of errors on builtins.
Fixes bug bin/29410 in head.
All of /bin/sh needs pulling up into 2.0
 1.80 30-Oct-2004  christos Pass WARNS=3
 1.79 30-Jun-2004  mycroft Make "set -e" once again provide the behavior documented in the man page,
which was unnecessarily changed in revision 1.50 while fixing other bugs.
That is, exit the shell if the last command in a || or && compound statement
is not short-circuited, and exits with a false status. I.e., the following
will cause the shell to exit:

set -e
false || false

While this is not the prescribed behavior in SUSv3, it is what our man page
documents, and it is what all of the following implementations do:

NetBSD /bin/ksh (pdksh)
bash
zsh
Solaris 9 /bin/sh
Solaris 9 /usr/xpg4/bin/sh
Solaris 9 /usr/bin/ksh
Tru64 /bin/sh
HP/UX 11 /bin/sh

The "standard" seems to be wrong in this instance.
 1.78 26-Jun-2004  dsl Correctly apply IFS to unquoted text in ${x-text}.
Fixes PR/26058 and the 'for i in ${x-a b c}; do ...' and ${x-'a b' c}.
I can't find a PR for the latter problem.
Regression test goind in shortly.
 1.77 26-Jun-2004  dsl No functional changes (intended).
Rename some variables, add some comments, and restructure a little.
In preparation for fixing "set ${x-a b c}" and friends.
 1.76 30-Apr-2004  dsl Ensure that fd 0, 1 and 2 are not used for the local end of pipelines.
Fixes PR bin/25395
 1.75 14-Nov-2003  dsl Add '\n' to "fork failed" trace messages.
 1.74 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.73 13-Jul-2003  itojun use bounded string op
 1.72 23-Jan-2003  agc Make this build on platforms where size_t != int, i.e. sparc, arm, ppc, ...
 1.71 23-Jan-2003  rafal Make this build again.
 1.70 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.69 25-Nov-2002  agc Include <stdio.h> to get the prototype for sprintf(3) - macppc needs this.
 1.68 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.67 23-Oct-2002  christos From David Laight
> The wrong process is aborting when variable assignment fails
> in the vfork path. So the following command fails to execute
> the second echo (shown here with the correct output).
>
> $ (readonly r; r= /bin/echo a; echo b)
> r: is read only
> b
>
> fix: defer the mklocal() to the child shell.
 1.66 23-Oct-2002  christos Fix interrupt problam from David Laight

$ /fred # non existant command
$ ^C # stops working

He says:
Ok the extra INTOFF is the one in exverror().
In almost all cases this doesn't matter because the longjmp()s
all end up in main() and the FORCEINTON call sorts it out
for the next command.
(There are a significant number of INTON/OFF mismatches through
the error paths...)

In any case the above failure can be 'fixed' by changing 2 (I think
they are both needed) INTON calls to FORCEINTON within evalcommand.
The following patch seems to work:

We should really look in the code and fix the INTON->INTOFF pairs.
 1.65 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.64 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.63 27-Sep-2002  mycroft Clean up INTOFF/INTON usage a little -- none of fork{shell,parent,child}()
screw with them now, only their callers.
 1.62 27-Sep-2002  christos Put back charles' fixes from -r1.60
 1.61 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.60 27-Sep-2002  mycroft In evalpipe(), move the INTOFF after the waitforjob(), to prevent possible
race conditions -- now we always synchronously wait for the job to finish.
In evalcommand(), add the same INTOFF/INTON locking as evalpipe(), to prevent
leaving internal state inconsistent, and also to insure that we synchronously
wait for the job.
 1.59 15-May-2002  christos implement noclobber. From Ben Harris, with minor tweaks from me. Two
unimplemented comments to go. Go Ben!
 1.58 14-Feb-2002  christos branches: 1.58.2;
PR/11542: Back-out previous change that caused
set -e
for x in a; do
BAR="foo"
false && echo true
echo mumble
done

not to echo mumble...
 1.57 04-Feb-2001  christos remove redundant declarations and nexted externs.
 1.56 22-May-2000  elric branches: 1.56.4;
Back out previous vfork changes.
 1.55 17-May-2000  elric When vforking ensure that the environment passed to exec is built before
vforking as a set of local variables which can be popped by the parent.

Addresses bin/10124.
 1.54 15-May-2000  elric INTON and FORCEINTON modify global variables, and so should not be
executed while we are vforked.
 1.53 13-May-2000  elric Added includes for waitpid, sys/types.h and sys/wait.h.
 1.52 13-May-2000  elric Now we use vfork(2) instead of fork(2) when we can.
 1.51 09-Feb-2000  christos Fix problem where commands that caused exitstatus != 0 inside loops did
not cause the shell to exit when -e was set.
 1.50 27-Jan-2000  christos Fix bin/9184, bin/9194, bin/9265, bin/9266
Exitcode and negation problems (From Martin Husemann)
 1.49 13-Oct-1999  mrg back out previous; it causes /etc/rc to break on my alpha and other lossage as reported in PR#8614
 1.48 10-Oct-1999  pk Backtrack `exitstatus' to make the shell really ignore the status
of `tested commands' as in this example:

set -e
true; false && echo "not reached"
 1.47 09-Jul-1999  christos branches: 1.47.2;
compile with WARNS = 2
 1.46 26-Jun-1999  christos PR/7814: Matthias Scheler: shell does not fork for builtins in backquotes,
leading to unexpected behaviour. Disable the no-fork optimization for now.
We need to revisit this and keep enough state around to recover from such
changes.
 1.45 04-Feb-1999  christos branches: 1.45.2;
PR/4966: Joel Reicher: Implement <> redirections which are documented in
the man page.
 1.44 28-Jul-1998  mycroft Be more retentive about use of NOTREACHED and noreturn.
 1.43 28-Jul-1998  mycroft Delint.
 1.42 05-Feb-1998  christos Re-enabled EXP_RECORD
 1.41 04-Feb-1998  mikel back out last change until christos fixes EXP_RECORD; PR 4932
 1.40 31-Jan-1998  christos PR/4851: Benjamin Lorenz: In the "for <var> in <args>" construct <args>
was not marked as a region to be handled by ifsbreakup. Add EXP_RECORD
to indicate that the argument string needs to be recorded.
 1.39 26-Aug-1997  thorpej branches: 1.39.2;
Avoid a segv in bltinlookup() reported by Ronald Khoo <ronald@demon.net>
in PR #3929, fix submitted by hiroy@NETCOM.COM (Hiroyuki Ito).
 1.38 20-Jul-1997  christos PR/3888: Chris Demetriou: type command-with-slash prints
$PATH[0]/command-with-slash...
 1.37 15-Jul-1997  christos PR/3866: bayer@informatik.uni-leipzig.de: core dump using xon script.
cmdenviron is pointing to varlist.list; varlist gets reset everytime
you enter evalcommand, but cmdenviron does not. The wonders of global
variables...
 1.36 04-Jul-1997  christos Fix compiler warnings.
 1.35 14-Mar-1997  christos NO_HISTORY->SMALL
 1.34 11-Jan-1997  tls kill 'register'
 1.33 09-Nov-1996  christos remove a debugging printf that was left from the last POSIX error code fixes.
 1.32 06-Nov-1996  christos Fix miscellaneous getopts problems:
- the 3 argument version of getopts would not reset properly
- OPTARG did not get cleared after a non argument option was found
- OPTIND was not set properly after a non argument option.
 1.31 16-Oct-1996  christos PR/287: Exit with 127/126 when command is not found/permission denied.
PR/2808: don't bomb out on "set -e; false && true"
 1.30 03-Jun-1996  christos Fix PR/2504: return with no args returns 0 instead of the return value of
the previous command in functions
 1.29 06-Mar-1996  pk branches: 1.29.4;
Return zero status if `else' clause is empty.
 1.28 05-Mar-1996  christos - parser.c: Fix prompting in old style backquote expansion. Fixes PR/2139
and many user complaints why the shell hangs in echo "`"
- eval.c: Fix exitstatus invalid resetting in `if' statements were:
if (exit 3); then
echo foo $?
else
echo bar $?
fi
printed 'bar 0' instead of bar 3
 1.27 11-Sep-1995  christos Fix return builtin to work like it does in ksh:
When not in a function, it skips the rest of the current input file.
Instances of `return' outside function definitions were previously ignored.
What does joe posix have to say about this?
[fixes PR/1444]
 1.26 09-Jun-1995  christos Changed so that 'PATH=newpath command' works, instead of looking at the
old path. Synced input.c with vangogh.
 1.25 19-May-1995  christos Changed so that syntax errors (EXERROR) set the exit status to 2,
and commands that are not found set the exit status to 1 like all
other bourne shells.
[It used to be 0 and 2 respectively]
 1.24 15-May-1995  cgd re-add an #endif that was (apprently) clobbered.
 1.23 15-May-1995  christos Fixed new bug the previous fix introduced:

false
foo=bar
echo $?

would print 1
Also fixed the long standing bug:

false
echo `echo $?`

would print 0
The exitstatus needs rethinking and rewriting. The trial and error method
is not very efficient
 1.22 14-May-1995  christos Fixed bug caused by previous x=`false` not preserving the exit status fix.
The if statement exit status broke...
 1.21 11-May-1995  christos Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.20 31-Mar-1995  christos 1. Don't core dump on 'fc -l' (From Gerard J van der Grinten)
2. PATH=xxx ls, does the PATH assignment first and then tries to find ls in xxx
3. VAR=xxx exec ls, does the variable assignment.
 1.19 21-Mar-1995  cgd convert to new RCS id conventions.
 1.18 23-Dec-1994  cgd be more careful with casts.
 1.17 05-Dec-1994  cgd clean up further. more patches from Jim Jegers
 1.16 04-Dec-1994  cgd from James Jegers <jimj@miller.cs.uwm.edu>: quiet -Wall, and squelch
some of the worst style errors.
 1.15 24-Aug-1994  mycroft Fix a core dump and another parse error related to null commands.
 1.14 14-Jun-1994  jtc branches: 1.14.2;
From Christos:
1. Fix `-' quoting in [ ] expressions.
2. Fix expansion of variables in redirections
 1.13 12-Jun-1994  jtc Set the status variable ($?) to 0 after a successful variable assignment.
 1.12 11-Jun-1994  mycroft Add RCS ids.
 1.11 21-May-1994  cgd a few more things to omit when NO_HISTORY defined. from noel@cs.oberlin.edu
 1.10 14-May-1994  cgd add back in support for building w/o obj dir. also, add NO_HISTORY
define, which (if you invoke mkbuiltins properly) gets you a sh w/o
history of command line editing (for floppy sh).
 1.9 12-May-1994  jtc Include appropriate header files to bring function prototypes into scope.
 1.8 11-May-1994  jtc reintegrate NetBSD's false builtin
 1.7 11-May-1994  jtc sync with 4.4lite
 1.6 09-Sep-1993  cgd fix from Jim Wilson <wilson@cygnus.com> for nothing-between-backquotes core
 1.5 01-Aug-1993  mycroft Add RCS identifiers.
 1.4 07-Jul-1993  jtc IEEE 1003.2 (D11.2.2.3) requires that the system's true and false be accessed
instead of searching $PATH. The best way to satisfy this requirement is to
make them builtins.

True was allready builtin, this patch adds false.
 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.14.2.1 24-Aug-1994  mycroft update from trunk
 1.29.4.2 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.29.4.1 10-Jun-1996  jtc pulled up from version 1.30 at christos' request
 1.39.2.1 08-May-1998  mycroft Sync with trunk, per request of christos.
 1.45.2.1 01-Jul-1999  perry pullup 1.45->1.46 (christos)
 1.47.2.1 27-Dec-1999  wrstuden Pull up to last week's -current.
 1.56.4.1 23-Feb-2002  he Pull up revision 1.58 (requested by christos):
When ``-e'' is in effect, do not exit if the failing command is
part of an && or || list, or preceded by the ``!'' reserved word.
Fixes PR#11542.
 1.58.2.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.81.2.1 13-Jun-2005  tron Pull up revision 1.82 (requested by lukem in ticket #397):
Mark temp_path volatile so that it won't get clobbered after longjmp.
(Also appeases gcc -Wuninitialized.)
 1.88.8.1 23-Mar-2008  matt sync with HEAD
 1.88.4.1 04-Sep-2008  skrll Sync with netbsd-4.
 1.88.2.1 08-Jun-2008  bouyer Pull up following revision(s) (requested by tron in ticket #1157):
bin/sh/eval.c: revision 1.90
Port revision 1.44 of "src/bin/sh/eval.c" from FreeBSD to fix PR bin/38584.
Reviewed by Michael van Elst.
 1.89.6.1 23-Jun-2008  wrstuden Sync w/ -current. 34 merge conflicts to follow.
 1.89.4.1 04-Jun-2008  yamt sync with head
 1.100.2.1 05-Mar-2011  bouyer Sync with HEAD
 1.102.2.4 22-May-2014  yamt sync with head.

for a reference, the tree before this commit was tagged
as yamt-pagecache-tag8.

this commit was splitted into small chunks to avoid
a limitation of cvs. ("Protocol error: too many arguments")
 1.102.2.3 23-Jan-2013  yamt sync with head
 1.102.2.2 30-Oct-2012  yamt sync with head
 1.102.2.1 17-Apr-2012  yamt sync with head
 1.104.2.3 19-Aug-2014  tls Rebase to HEAD as of a few days ago.
 1.104.2.2 23-Jun-2013  tls resync from head
 1.104.2.1 25-Feb-2013  tls resync with head
 1.108.2.1 10-Aug-2014  tls Rebase.
 1.128.2.2 26-Apr-2017  pgoyette Sync with HEAD
 1.128.2.1 20-Mar-2017  pgoyette Sync with HEAD
 1.129.2.1 21-Apr-2017  bouyer Sync with HEAD
 1.131.2.2 19-May-2017  pgoyette Resolve conflicts from previous merge (all resulting from $NetBSD
keywork expansion)
 1.131.2.1 11-May-2017  pgoyette Sync with HEAD
 1.140.2.7 25-Aug-2018  martin Fix merge mishap due to #983 / #989 pullup order.
 1.140.2.6 25-Aug-2018  martin Pull up following revision(s) (requested by kre in ticket #989):

bin/sh/eval.c: revision 1.156
bin/sh/eval.h: revision 1.20
bin/sh/exec.c: revision 1.53

Fix several bugs in the command / type builtin ( including PR bin/48499 )

1. Make command -pv (and -pV) work (which is not as easy as the PR
suggests it might be (the "check and cause error" was there because
it did not work, not in order to prevent it from working).

2. Stop -v and -V being both used (that makes no sense).

3. Stop the "type" builtin inheriting the args (-pvV) that "command" has
(which it did, as when -v -or -V is used with command, it and type are
implemented using the same code).

4. make "command -v word" DTRT for sh keywords (was treating them as an error).

5. Require at least one arg for "command -[vV]" or "type" else usage & error.
Strictly this should also apply to "command" and "command -p" (no -v)
but that's handled elsewhere, so perhaps some other time. Perhaps
"command -v" (and -V) should be limited to 1 command name (where "type"
can have many) as in the POSIX definitions, but I don't think that matters.

6. With "command -V alias", (or "type alias" which is the same thing),
(but not "command -v alias") alter the output format, so we get
ll is an alias for: ls -al
instead of the old
ll is an alias for
ls -al
(and note there was a space, for some reason, after "for")
That is, unless the alias value contains any \n characters, in which
case (something approximating) the old multi-line format is retained.
Also note: that if code wants to parse/use the value of an alias, it
should be using the output of "alias name", not command or type.

Note that none of the above affects "command [-p] cmd" (no -v or -V options)
only "command -[vV]" and "type".

Note also that the changes to eval.[ch] are merely to make syspath()
visible in exec.c rather than static in eval.c
 1.140.2.5 25-Aug-2018  martin Pull up following revision(s) (requested by kre in ticket #983):

bin/sh/eval.c: revision 1.158
bin/sh/eval.h: revision 1.21
bin/sh/main.c: revision 1.74

PR bin/48875

Revert the changes that were made 19 May 2016 (principally eval.c 1.125)
and the bug fixes in subsequent days (eval.c 1.126 and 1.127) and also
update some newer code that was added more recently which acted in
accordance with those changes (make that code be as it would have been
if the changes now being reverted had never been made).

While the changes made did solve the problem, in a sense, they were
never correct (see the PR for some discussion) and it had always been
intended that they be reverted. However, in practical sh code, no
issues were reported - until just recently - so nothing was done,
until now...

After this commit, the validate_fn_redirects test case of the sh ATF
test t_redir will fail. In particular, the subtest of that test
case which is described in the source (of the test) as:

This one is the real test for PR bin/48875

will fail.

Alternative changes, not to "fix" the problem in the PR, but to
often avoid it will be coming very soon - after which that ATF
test will succeed again.

XXX pullup-8
 1.140.2.4 25-Aug-2018  martin Pull up following revision(s) (requested by kre in ticket #982):

bin/sh/eval.c: revision 1.157

PR bin/42184 PR bin/52687 (detailing the same bug).

Fix "command not found" handling so that the error message
goes to stderr (after any redirections are applied).

More importantly, in

foo > /tmp/junk

/tmp/junk should be created, before any attempt is made
to execute (the assumed non-existing) "foo".

All this was always true for any command (not found command)
containing a / in its name

foo/bar >/tmp/junk 2>>/tmp/errs

would have created /tmp/junk, then complained (in /tmp/errs)
about foo/bar not being found. Now that happens for ordinary
commands as well.

The fix (which I found when I saw differences between our
code and FreeBSD's, where, for the benefit of PR 42184,
this has been fixed, sometime in the past 9 years) is
frighteningly simple. Simply do not short circuit execution
(or print any error) when the initial lookup fails to
find the command - it will fail anyway when we actually
try running it. The cost is a (seemingly unnecessary,
except that it really is) fork in this case.

This is what I had been planning, but I expected it would
be much more difficult than it turned out....

XXX pullup-8
 1.140.2.3 13-Jul-2018  martin Pull up following revision(s) (requested by kre in ticket #906):

bin/sh/eval.c: revision 1.155
bin/sh/mknodes.sh: revision 1.3
bin/sh/nodes.c.pat: revision 1.14
bin/sh/exec.h: revision 1.27
bin/sh/exec.c: revision 1.52

Deal with ref after free found by ASAN when a function redefines
itself, or some other function which is still active.

This was a long known bug (fixed ages ago in the FreeBSD sh) which
hadn't been fixed as in practice, the situation that causes the
problem simply doesn't arise .. ASAN found it in the sh dotcmd
tests which do have this odd "feature" in the way they are written
(but where it never caused a problem, as the tests are so simple
that no mem is ever allocated between when the old version of the
function was deleted, and when it finished executing, so its code
all remained intact, despite having been freed.)

The fix is taken from the FreeBSD sh.

XXX -- pullup-8 (after a while to ensure no other problems arise).
 1.140.2.2 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.140.2.1 05-Jun-2017  snj Pull up following revision(s) (requested by kre in ticket #5):
bin/sh/cd.c: revision 1.48
bin/sh/eval.c: revision 1.141
bin/sh/exec.c: revision 1.48
bin/sh/exec.h: revision 1.25
bin/sh/mail.c: revisions 1.17, 1.18
bin/sh/sh.1: revision 1.147
Make cd (really) do cd -P, and not just claim that is what it is doing
while doing a half-hearted, broken, partial, version of cd -L instead.
The latter (as the manual says) is not supported, what's more, it is an
abomination, and should never be supported (anywhere.)
Fix the doc so that the pretense that we notice when a path given crosses
a symlink (and turns on printing of the destination directory) is claimed
no more (that used to be true until late Dec 2016, but was changed). Now
the print happens if -o cdprint is set, or if an entry from CDPATH that is
not "" or "." is used (or if the "cd dest repl" cd cmd variant is used.)
Fix CDPATH processing: avoid the magic '%' processing that is used for
PATH and MAILPATH from corrupting CDPATH. The % magic (both variants)
remains undocumented.
Also, don't double the '/' if an entry in PATH or CDPATH ends in '/'
(as in CDPATH=":/usr/src/"). A "cd usr.bin" used to do
chdir("/usr/src//usr.bin"). No more. This is almost invisible,
and relatively harmless, either way....
Also fix a bug where if a plausible destination directory in CDPATH
was located, but the chdir() failed (eg: permission denied) and then
a later "." or "" CDPATH entry succeeded, "print" mode was turned on.
That is:
cd /tmp; mkdir bin
mkdir -p P/bin; chmod 0 P/bin
CDPATH=/tmp/P:
cd bin
would cd to /tmp/bin (correctly) but print it (incorrectly).
Also when in "cd dest replace" mode, if the result of the replacement
generates '-' as the path named, as in:
cd $PWD -
then simply change to '-' (or attempt to, with CDPATH search), rather
than having this being equivalent to "cd -")
Because of these changes, the pwd command (and $PWD) essentially
always acts as pwd -P, even when called as pwd -L (which is still
the default.) That is, even more than it did before.
Also fixed a (kind of minor) mem management error (CDPATH related)
"whosoever shall padvance must stunalloc before repeating" (and the
same for MAILPATH).
--
If we are going to keep the MAILPATH % hack, then at least do something
rational. Since it isn't documented, what "rational" is is up for
discussion, but what it did before was not it (it was nonsense...).
 1.153.2.8 26-Jan-2019  pgoyette Sync with HEAD
 1.153.2.7 18-Jan-2019  pgoyette Synch with HEAD
 1.153.2.6 26-Dec-2018  pgoyette Sync with HEAD, resolve a few conflicts
 1.153.2.5 26-Nov-2018  pgoyette Sync with HEAD, resolve a couple of conflicts
 1.153.2.4 20-Oct-2018  pgoyette Sync with head
 1.153.2.3 06-Sep-2018  pgoyette Sync with HEAD

Resolve a couple of conflicts (result of the uimin/uimax changes)
 1.153.2.2 28-Jul-2018  pgoyette Sync with HEAD
 1.153.2.1 25-Jun-2018  pgoyette Sync with HEAD
 1.155.2.4 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.155.2.3 21-Apr-2020  martin Sync with HEAD
 1.155.2.2 08-Apr-2020  martin Merge changes from current as of 20200406
 1.155.2.1 10-Jun-2019  christos Sync with HEAD
 1.175.2.4 14-Jan-2024  martin Pull up following revision(s) (requested by kre in ticket #1787):

bin/sh/eval.c: revision 1.191
bin/sh/expand.c: revision 1.144

PR bin/57773

Fix a bug reported by Jarle Fredrik Greipsland in PR bin/57773,
where a substring expansion where the substring to be removed from
a variable expansion is itself a var expansion where the value
contains one (or more) of sh's CTLxxx chars - the pattern had
CTLESC inserted, the string to be matched against did not. Fail.

We fix that by always inserting CTLESC in var assign expansions.
See the PR for all the gory details.

Thanks for the PR.

PR bin/57773

Fix another bug reported by Jarle Fredrik Greipsland and added
to PR bin/57773, which relates to calculating the length of a
positional parameter which contains CTL chars -- yes, this one
really is that specific, though it would also affect the special
param $0 if it were to contain CTL chars, and its length was
requested - that is fixed with the same change. And note: $0
is not affected because it looks like a positional param (it
isn't, ${00} would be, but is always unset, ${0} isn't) all
special parame would be affected the same way, but the only one
that can ever contain a CTL char is $0 I believe. ($@ and $*
were affected, but just because they're expanding the positional
params ... ${#@} and ${#*} are both technically unspecified
expansions - and different shells produce different results.

See the PR for the details of this one (and the previous).

Thanks for the PR.
 1.175.2.3 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
 1.175.2.2 26-Dec-2019  martin Pull up following revision(s) (requested by kre in ticket #582):

bin/sh/eval.c: revision 1.177

Use fork() rather than vfork() when forking to run a background
process with redirects. If we use vfork() and a redirect hangs
(eg: opening a fifo) which the parent was intended to unhang,
then the parent never gets to continue to unhang the child.
eg: mkfifo f; cat <f &; echo foo>f

The parent should not be waiting for a background process, even
just for its exec() to complete. if there are no redirects there
is (should be) nothing left that might be done that will cause any
noticeable delay, so vfork() should be safe in all other cases.
 1.175.2.1 11-Dec-2019  martin Pull up following revision(s) (requested by kre in ticket #542):

bin/sh/eval.c: revision 1.176
bin/sh/trap.c: revision 1.53

PR bin/54743

Having traps set should not enforce a fork for the next command,
whatever that command happens to be, only for commands which would
normally fork if they weren't the last command expected to be
executed (ie: builtins and functions shouldn't be exexuted in a
sub-shell merely because a trap is set).

As it was (for example)
trap 'whatever' SIGANY; wait $anypid
was guaranteed to fail the wait, as the subshell it was executed
in could not have any children.

XXX pullup -9

PR bin/54743

If a builtin command or function is the final command intended to be
executed, and is interrupted by a caught signal, the trap handler for
that signal was not executed - the shell simply exited (an exit trap
handler would still have been run - if there was one the handler
for the signal may have been invoked during the execution of the
exit trap handler, which, if it happened, is incorrect sequencing).

Now, if we're exiting, and there are pending signals, run their handlers
just before running the EXIT trap handler, if any.
There are almost certainly plenty more issues with traps that need
solving. Later,

XXX pullup -9
(-8 is too different in this area, and this problem suitably obscure,
that we won't bother) (the -7 sh is simply obsolete).
 1.188.2.2 25-Nov-2024  martin Apply patch, requested by kre in ticket #1016:

bin/sh/eval.c (apply patch)

Fix "exec cmd" redirections to never close-on-exec

Correct the bug reported by Edgar Fu� in:
https://mail-index.netbsd.org/tech-userlevel/2024/11/05/msg014588.html
where when /bin/sh evaluates
exec command 3>/some/file
fd 3 (any redirection for any fd > 2) gets "close on exec" set
(inappropriately) causing the redirection to be evaluated, then
immediately closed when the exec happens.
 1.188.2.1 14-Jan-2024  martin Pull up following revision(s) (requested by kre in ticket #535):

bin/sh/eval.c: revision 1.191
bin/sh/expand.c: revision 1.144

PR bin/57773

Fix a bug reported by Jarle Fredrik Greipsland in PR bin/57773,
where a substring expansion where the substring to be removed from
a variable expansion is itself a var expansion where the value
contains one (or more) of sh's CTLxxx chars - the pattern had
CTLESC inserted, the string to be matched against did not. Fail.

We fix that by always inserting CTLESC in var assign expansions.
See the PR for all the gory details.

Thanks for the PR.

PR bin/57773

Fix another bug reported by Jarle Fredrik Greipsland and added
to PR bin/57773, which relates to calculating the length of a
positional parameter which contains CTL chars -- yes, this one
really is that specific, though it would also affect the special
param $0 if it were to contain CTL chars, and its length was
requested - that is fixed with the same change. And note: $0
is not affected because it looks like a positional param (it
isn't, ${00} would be, but is always unset, ${0} isn't) all
special parame would be affected the same way, but the only one
that can ever contain a CTL char is $0 I believe. ($@ and $*
were affected, but just because they're expanding the positional
params ... ${#@} and ${#*} are both technically unspecified
expansions - and different shells produce different results.

See the PR for the details of this one (and the previous).

Thanks for the PR.
 1.192.2.1 02-Aug-2025  perseant Sync with HEAD
 1.24 03-Aug-2024  kre Change the "string" argument to evalstring() and setinputstring()
from being "char *" to being "const char *".

This is needed for a forthcoming change which needs to pass a const char *
to evalstring (and through it to setinputstring) and be assured that
nothing will alter the characters in the string supplied.

This is (aside from the additional compile time protection provided)
a no-op change, all evalstring() does with its string is pass it to
setinputstring() and all that does with it is determine its length
(strlen() which expects a const char *) and assign the string pointer
to parsenextc which is already a const char * - there never has been
any reason for these two functions to not include the "const" in
the arg declaration -- except that when originally written (early
1990's) I suspect "const" either didn't exist at all, or wasn't
supported by relevant compilers.

NFCI. Most probably (though I didn't check) no binary change at all.
 1.23 04-Feb-2019  kre branches: 1.23.12;
PR bin/53919

Suppress shell error messages while expanding $ENV (which also causes
errors while expanding $PS1 $PS2 and $PS4 to be suppressed as well).

This allows any random garbage that happens to be in ENV to not
cause noise when the shell starts (which is effectively all it did).

On a parse error (for any of those vars) we also use "" as the result,
which will be a null prompt, and avoid attempting to open any file for ENV.

This does not in any way change what happens for a correctly parsed command
substitution (either when it is executed when permitted for one of the
prompts, or when it is not (which is always for ENV)) and commands run
from those can still produce error output (but shell errors remain suppressed).
 1.22 03-Dec-2018  kre Cleanup traps a bit - attempt to handle weird uses in traps, such
as traps that issue break/continue/return to cause the loop/function
executing when the trap occurred to break/continue/return, and
generating the correct exit code from the shell including when a
signal is caught, but the trap handler for it exits.

All that from FreeBSD.

Also make
T=$(trap)
work as it is supposed to (also trap -p).

For now this is handled by the same technique as $(jobs) - rather
than clearing the traps in subshells, just mark them invalid, and
then whenever they're invalid, clear them before executing anything
other than the special blessed "trap" command. Eventually we will
handle these using non-subshell command substitution instead (not
creating a subshell environ when the commands in a command-sub alter
nothing in the environment).
 1.21 19-Aug-2018  kre PR bin/48875

Revert the changes that were made 19 May 2016 (principally eval.c 1.125)
and the bug fixes in subsequent days (eval.c 1.126 and 1.127) and also
update some newer code that was added more recently which acted in
accordance with those changes (make that code be as it would have been
if the changes now being reverted had never been made).

While the changes made did solve the problem, in a sense, they were
never correct (see the PR for some discussion) and it had always been
intended that they be reverted. However, in practical sh code, no
issues were reported - until just recently - so nothing was done,
until now...

After this commit, the validate_fn_redirects test case of the sh ATF
test t_redir will fail. In particular, the subtest of that test
case which is described in the source (of the test) as:
This one is the real test for PR bin/48875
will fail.

Alternative changes, not to "fix" the problem in the PR, but to
often avoid it will be coming very soon - after which that ATF
test will succeed again.

XXX pullup-8
 1.20 25-Jul-2018  kre Fix several bugs in the command / type builtin ( including PR bin/48499 )

1. Make command -pv (and -pV) work (which is not as easy as the PR
suggests it might be (the "check and cause error" was there because
it did not work, not in order to prevent it from working).

2. Stop -v and -V being both used (that makes no sense).

3. Stop the "type" builtin inheriting the args (-pvV) that "command" has
(which it did, as when -v -or -V is used with command, it and type are
implemented using the same code).

4. make "command -v word" DTRT for sh keywords (was treating them as an error).

5. Require at least one arg for "command -[vV]" or "type" else usage & error.
Strictly this should also apply to "command" and "command -p" (no -v)
but that's handled elsewhere, so perhaps some other time. Perhaps
"command -v" (and -V) should be limited to 1 command name (where "type"
can have many) as in the POSIX definitions, but I don't think that matters.

6. With "command -V alias", (or "type alias" which is the same thing),
(but not "command -v alias") alter the output format, so we get
ll is an alias for: ls -al
instead of the old
ll is an alias for
ls -al
(and note there was a space, for some reason, after "for")

That is, unless the alias value contains any \n characters, in which
case (something approximating) the old multi-line format is retained.
Also note: that if code wants to parse/use the value of an alias, it
should be using the output of "alias name", not command or type.

Note that none of the above affects "command [-p] cmd" (no -v or -V options)
only "command -[vV]" and "type".

Note also that the changes to eval.[ch] are merely to make syspath()
visible in exec.c rather than static in eval.c
 1.19 09-May-2016  kre branches: 1.19.8; 1.19.14; 1.19.16;

PR bin/48875 - avoid holding (replaced) file descriptors open when running a
command in the current shell (so they can be restored for the next command)
in cases where it is obvious that there is not going to be a following
command to use them. This fixes the problem reported in the PR (though
there are still plenty of situations where a FD could be closed but isn't,
we do not do full fd flow eveluation to determine whether a fd will be
used or not).

This is the change that was just committed and then backed out again...

OK christos@
 1.18 09-May-2016  kre Revert previous. These changes are intended to get made (and will
be in a minute or two) but not as part of that commit... The log
entry certainly does not apply.
 1.17 09-May-2016  kre Finish the fd reassignment fixes from 1.43 and 1.45 ... if we are moving
a fd to an unspecified high fd number, we certainly do not want to hand
that high fd off to other processes after an exec, so always set close-on-exec
on the result (even if lack of fd's means no fd alteration happens.)
This will (eventually) allow some other code that sets close-on-exec to
be removed, but for now, doing it twice won't hurt. Also, in a N>&M
type redirection, do not set close-on-exec if we don't want it.

OK christos@
 1.16 31-May-2014  christos PR/48843: Jarmo Jaakkola: dot commands mess up scope nesting tracking

Evaluation of commands goes completely haywire if a file containing
a break/continue/return command outside its "intended" scope is sourced
using a dot command inside its "intended" scope. The main symptom is
not exiting from the sourced file when supposed to, leading to evaluation
of commands that were not supposed to be evaluated. A secondary symptom
is that these extra commands are not evaluated correctly, as some of them
are skipped. Some examples are listed in the How-To-Repeat section.

According to the POSIX standard, this is how it should work:
dot:
The shell shall execute commands from the file in the current
environment.
break:
The break utility shall exit from the smallest enclosing for, while,
or until loop, [...]
continue:
The continue utility shall return to the top of the smallest
enclosing for, while, or until loop, [...]
return:
The return utility shall cause the shell to stop executing
the current function or dot script. If the shell is not currently
executing a function or dot script, the results are unspecified.

It is clear that return should return from a sourced file, which
it does not do. Whether break and continue should work from the sourced
file might be debatable. Because the dot command says "in the current
environment", I'd say yes. In any case, it should not fail in weird
ways like it does now!

The problems occur with return (a) and break/continue (b) because:
1) dotcmd() does not record the function nesting level prior to
sourcing the file nor does it touch the loopnest variable,
leading to either
2 a) returncmd() being unable to detect that it should not set
evalskip to SKIPFUNC but SKIPFILE, or
b) breakcmd() setting evalskip to SKIPCONT or SKIPBREAK,
leading to
3) cmdloop() not detecting that it should skip the rest of
the file, due to only checking for SKIPFILE.
The result is that cmdloop() keeps executing lines from the file
whilst evalskip is set, which is the main symptom. Because
evalskip is checked in multiple places in eval.c, the secondary
symptom appears.
>How-To-Repeat:
Run the following script:

printf "break\necho break1; echo break2" >break
printf "continue\necho continue1; echo continue2" >continue
printf "return\necho return1; echo return2" >return

while true; do . ./break; done

for i in 1 2; do . ./continue; done

func() {
. ./return
}
func

No output should be produced, but instead this is the result:
break1
continue1
continue1
return1

The main symptom is evident from the unexpected output and the secondary
one from the fact that there are no lines with '2' in them.
>Fix:
Here is patch to src/bin/sh to fix the above problems. It keeps
track of the function nesting level at the beginning of a dot command
to enable the return command to work properly.

I also changed the undefined-by-standard functionality of the return
command when it's not in a dot command or function from (indirectly)
exiting the shell to being silently ignored. This was done because
the previous way has at least one bug: the shell exits without asking
for confirmation when there are stopped jobs.

Because I read the standard to mean that break and continue should have
an effect outside the sourced file, that's how I implemented it. For what
it's worth, this also seems to be what bash does. Also laziness, because
this way required no changes to loopnesting tracking. If this is not
wanted, it might make sense to move the nesting tracking to the inputfile
stack.

The patch also does some clean-up to reduce the amount of global
variables by moving the dotcmd() and the find_dot_file() functions from
main.c to eval.c and making in_function() a proper function.
 1.15 15-Feb-2008  matt branches: 1.15.32; 1.15.46;
Fix inconsistent definitions
 1.14 07-Aug-2003  agc branches: 1.14.22;
Move UCB-licensed code from 4-clause to 3-clause licence.

Patches provided by Joel Baker in PR 22249, verified by myself.
 1.13 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.12 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.11 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.10 27-Jan-2000  christos Fix bin/9184, bin/9194, bin/9265, bin/9266
Exitcode and negation problems (From Martin Husemann)
 1.9 11-Sep-1995  christos Fix return builtin to work like it does in ksh:
When not in a function, it skips the rest of the current input file.
Instances of `return' outside function definitions were previously ignored.
What does joe posix have to say about this?
[fixes PR/1444]
 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.14.22.1 23-Mar-2008  matt sync with HEAD
 1.15.46.1 10-Aug-2014  tls Rebase.
 1.15.32.1 19-Aug-2014  tls Rebase to HEAD as of a few days ago.
 1.19.16.3 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.19.16.2 21-Apr-2020  martin Sync with HEAD
 1.19.16.1 10-Jun-2019  christos Sync with HEAD
 1.19.14.3 26-Dec-2018  pgoyette Sync with HEAD, resolve a few conflicts
 1.19.14.2 06-Sep-2018  pgoyette Sync with HEAD

Resolve a couple of conflicts (result of the uimin/uimax changes)
 1.19.14.1 28-Jul-2018  pgoyette Sync with HEAD
 1.19.8.2 25-Aug-2018  martin Pull up following revision(s) (requested by kre in ticket #989):

bin/sh/eval.c: revision 1.156
bin/sh/eval.h: revision 1.20
bin/sh/exec.c: revision 1.53

Fix several bugs in the command / type builtin ( including PR bin/48499 )

1. Make command -pv (and -pV) work (which is not as easy as the PR
suggests it might be (the "check and cause error" was there because
it did not work, not in order to prevent it from working).

2. Stop -v and -V being both used (that makes no sense).

3. Stop the "type" builtin inheriting the args (-pvV) that "command" has
(which it did, as when -v -or -V is used with command, it and type are
implemented using the same code).

4. make "command -v word" DTRT for sh keywords (was treating them as an error).

5. Require at least one arg for "command -[vV]" or "type" else usage & error.
Strictly this should also apply to "command" and "command -p" (no -v)
but that's handled elsewhere, so perhaps some other time. Perhaps
"command -v" (and -V) should be limited to 1 command name (where "type"
can have many) as in the POSIX definitions, but I don't think that matters.

6. With "command -V alias", (or "type alias" which is the same thing),
(but not "command -v alias") alter the output format, so we get
ll is an alias for: ls -al
instead of the old
ll is an alias for
ls -al
(and note there was a space, for some reason, after "for")
That is, unless the alias value contains any \n characters, in which
case (something approximating) the old multi-line format is retained.
Also note: that if code wants to parse/use the value of an alias, it
should be using the output of "alias name", not command or type.

Note that none of the above affects "command [-p] cmd" (no -v or -V options)
only "command -[vV]" and "type".

Note also that the changes to eval.[ch] are merely to make syspath()
visible in exec.c rather than static in eval.c
 1.19.8.1 25-Aug-2018  martin Pull up following revision(s) (requested by kre in ticket #983):

bin/sh/eval.c: revision 1.158
bin/sh/eval.h: revision 1.21
bin/sh/main.c: revision 1.74

PR bin/48875

Revert the changes that were made 19 May 2016 (principally eval.c 1.125)
and the bug fixes in subsequent days (eval.c 1.126 and 1.127) and also
update some newer code that was added more recently which acted in
accordance with those changes (make that code be as it would have been
if the changes now being reverted had never been made).

While the changes made did solve the problem, in a sense, they were
never correct (see the PR for some discussion) and it had always been
intended that they be reverted. However, in practical sh code, no
issues were reported - until just recently - so nothing was done,
until now...

After this commit, the validate_fn_redirects test case of the sh ATF
test t_redir will fail. In particular, the subtest of that test
case which is described in the source (of the test) as:

This one is the real test for PR bin/48875

will fail.

Alternative changes, not to "fix" the problem in the PR, but to
often avoid it will be coming very soon - after which that ATF
test will succeed again.

XXX pullup-8
 1.23.12.1 02-Aug-2025  perseant Sync with HEAD
 1.59 12-Jul-2024  kre Improve safety in var imports from the environment.

Add a new var flag VUNSAFE - set on all vars imported from the environment.

Add setvareqsafe() (which is to setvareq() as setvarsafe() is to setvar())
and use that instead of setvareq() when processing the environment, so
errors don't cause the shell to abort. Use VUNSAFE in that call.

Add flags arguments to all var callback functions which are used when setting
variables, and pass the flags given to the setvar*() functions to those
functions, so they can act differently in different situations (if desired).
Most of them just ignore the flags.

When unsetting a variable, call setvar() to clear things (and call the
callback function) both when the variable had a value which needs to be freed,
and when unsetting a variable which wasn't unset previously, so the VUNSET
flag can be seen by that callback func.

When setting HISTSIZE, use the flags passed to determine whether to ignore
bad values (if VUNSAFE) or treat them as an error. This replaces the
earlier temporary hack to always ignore bad data there (histedit.c 1.68).

Miscellaneous associated minor changes.

These changes should largely be invisible in normal use.
 1.58 19-Mar-2023  kre branches: 1.58.2;

Do a better job handling EACCES errors from exec() calls. If the
EACCES is from the namei(), treat it just like ENOENT or ENOTDIR
(and if that is the final error, the exit status from a failed exec
will be 127). If the EACCES is from the exec() itself, that indicates
the file to be run exists, but has no 'x' permission. That's a
meaningful error (as distinct from just "yet another PATH element
search failure").

While here, return the first meaingful error we encountered while
searching PATH, rather than the last (and ENOENT if there are none
of those).

This change results in some failed command executions returning status
127 now, where they returned 126 before - which better reflects the
intent of those values (127 is simply "not found" whereas 126 is "found
but couldn't be executed").

We still do nothing to distinguish errors encountered looking up the
command name give, with errors encountered (by the kernel) attempting to
run an interpreter needed for the exec to succeed (#! line path, or
/libexec/ld.elf_so and similar - or anything else of a similar nature).
 1.57 16-Nov-2021  kre PR bin/56491

Make "hash" exit(!=0) (ie: exit(1)) if it writes an error message to
stderr as required by POSIX (it was writing "not found" errors, yet
still doing exit(0)).

Whether, when doing "hash foobar", and "foobar" is not found as a command
(not a built-in, not a function, and not found via a PATH search), that
should be considered an error differs between shells. All of the ksh
descendant shells say "no", write no error message in this case, and
exit(0) if no other errors occur. Other shells (essentially all) do
consider it an error, write a message to stderr, and exit(1) when this happens.

POSIX isn't clear, the bug report:
https://austingroupbugs.net/view.php?id=1460
which is not yet resolved, suggests that the outcome will be that
this is to be unspecified. Given the diversity, there might be no
other choice.

Have a foot in both camps - default to the "other shell" behaviour,
but add a -e option (no errors ... applies only to these "not found"
errors) to generate the ksh behaviour. Without other errors (like an
unknown option, etc) "hash -e anyname" will always exit(0).

See the PR for details on how it all works now, or read the updated man page.

While here, when hash is in its other mode (reporting what is in the
table) check for I/O errors on stdout, and exit(1) (with an error
message!) if any occurred. This does not apply to output generated
by the -v option when command names are given (that output is incidental).

In sh.1 document all of this. Also add documentation for a bunch of
other options the hash command has had for years, but which were never
documented. And while there, clean up some other sections I noticed
needed improving (either formatting or content or both).
 1.56 10-Oct-2021  rillig sh: make find_command simpler

Lint complained about the do-while-0 loop that contained a continue. It
didn't state the reason for it, but indeed the code looked complicated.
Rewrite the code to be less verbose and to use common coding patterns.

No functional change.
 1.55 16-Feb-2021  kre PR bin/55979

This fixes the MSAN detected reference to an unitialised variable
(an unitialised field in a struct) which happens when a command is
not found after a PATH search.

Aside from skipping some known to be going to fail exec*() calls
in some cases, the setting of the relevant field is irrelevant,
so this problem makes no practical difference to the shell, or any
shell script.

XXX (maybe) pullup -9
 1.54 01-Aug-2020  kre PR bin/55526

Fix a bug that has existed since the "command" command was added in
2003. "command foo" would cause the definition of a function "foo"
to be lost (not freed, simply discarded) if "foo" is (in addition to
being a function) a filesystem command. The case where "foo" is
a builtin was handled.

For now, when a function exists with the same name as a filesystem
command, the latter can never appear in the command hash table, and
when used (which can only be via "command foo", just "foo" finds
the function) will always result in a full PATH search.

XXX pullup everything (from NetBSD 2.0 onwards). (really -8 and -9)
 1.53 25-Jul-2018  kre branches: 1.53.2;
Fix several bugs in the command / type builtin ( including PR bin/48499 )

1. Make command -pv (and -pV) work (which is not as easy as the PR
suggests it might be (the "check and cause error" was there because
it did not work, not in order to prevent it from working).

2. Stop -v and -V being both used (that makes no sense).

3. Stop the "type" builtin inheriting the args (-pvV) that "command" has
(which it did, as when -v -or -V is used with command, it and type are
implemented using the same code).

4. make "command -v word" DTRT for sh keywords (was treating them as an error).

5. Require at least one arg for "command -[vV]" or "type" else usage & error.
Strictly this should also apply to "command" and "command -p" (no -v)
but that's handled elsewhere, so perhaps some other time. Perhaps
"command -v" (and -V) should be limited to 1 command name (where "type"
can have many) as in the POSIX definitions, but I don't think that matters.

6. With "command -V alias", (or "type alias" which is the same thing),
(but not "command -v alias") alter the output format, so we get
ll is an alias for: ls -al
instead of the old
ll is an alias for
ls -al
(and note there was a space, for some reason, after "for")

That is, unless the alias value contains any \n characters, in which
case (something approximating) the old multi-line format is retained.
Also note: that if code wants to parse/use the value of an alias, it
should be using the output of "alias name", not command or type.

Note that none of the above affects "command [-p] cmd" (no -v or -V options)
only "command -[vV]" and "type".

Note also that the changes to eval.[ch] are merely to make syspath()
visible in exec.c rather than static in eval.c
 1.52 22-Jun-2018  kre branches: 1.52.2;
Deal with ref after free found by ASAN when a function redefines
itself, or some other function which is still active.
This was a long known bug (fixed ages ago in the FreeBSD sh) which
hadn't been fixed as in practice, the situation that causes the
problem simply doesn't arise .. ASAN found it in the sh dotcmd
tests which do have this odd "feature" in the way they are written
(but where it never caused a problem, as the tests are so simple
that no mem is ever allocated between when the old version of the
function was deleted, and when it finished executing, so its code
all remained intact, despite having been freed.)

The fix is taken from the FreeBSD sh.

XXX -- pullup-8 (after a while to ensure no other problems arise).
 1.51 05-Jul-2017  kre branches: 1.51.4;

DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
 1.50 17-Jun-2017  kre Many internal memory management type fixes.

PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)

echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)

(Recently added) Problems with ~ expansion fixed (mem management related).

Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)

And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.

Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,

More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.

[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]

More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).

User visible changes:

Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in

cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END

(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)

With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)

POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).

Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
 1.49 07-Jun-2017  kre A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)

This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)

The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.

This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).

I would not call the results of this perfect yet, but it is close.
 1.48 04-Jun-2017  kre Make cd (really) do cd -P, and not just claim that is what it is doing
while doing a half-hearted, broken, partial, version of cd -L instead.
The latter (as the manual says) is not supported, what's more, it is an
abomination, and should never be supported (anywhere.)

Fix the doc so that the pretense that we notice when a path given crosses
a symlink (and turns on printing of the destination directory) is claimed
no more (that used to be true until late Dec 2016, but was changed). Now
the print happens if -o cdprint is set, or if an entry from CDPATH that is
not "" or "." is used (or if the "cd dest repl" cd cmd variant is used.)

Fix CDPATH processing: avoid the magic '%' processing that is used for
PATH and MAILPATH from corrupting CDPATH. The % magic (both variants)
remains undocumented.

Also, don't double the '/' if an entry in PATH or CDPATH ends in '/'
(as in CDPATH=":/usr/src/"). A "cd usr.bin" used to do
chdir("/usr/src//usr.bin"). No more. This is almost invisible,
and relatively harmless, either way....

Also fix a bug where if a plausible destination directory in CDPATH
was located, but the chdir() failed (eg: permission denied) and then
a later "." or "" CDPATH entry succeeded, "print" mode was turned on.
That is:
cd /tmp; mkdir bin
mkdir -p P/bin; chmod 0 P/bin
CDPATH=/tmp/P:
cd bin
would cd to /tmp/bin (correctly) but print it (incorrectly).

Also when in "cd dest replace" mode, if the result of the replacement
generates '-' as the path named, as in:
cd $PWD -
then simply change to '-' (or attempt to, with CDPATH search), rather
than having this being equivalent to "cd -")

Because of these changes, the pwd command (and $PWD) essentially
always acts as pwd -P, even when called as pwd -L (which is still
the default.) That is, even more than it did before.

Also fixed a (kind of minor) mem management error (CDPATH related)
"whosoever shall padvance must stunalloc before repeating" (and the
same for MAILPATH).
 1.47 15-May-2017  kre branches: 1.47.2;

(Perhaps temporarary) updated "hash" command. New options, and
more flexible behaviour.
 1.46 03-May-2016  christos branches: 1.46.6;
add missing forward declaration for the STATIC= case.
 1.45 01-Nov-2013  christos PR/48312: Dieter Roelands: According to TOG, unset should not return an error
for functions are variables that were not previously set:
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
 1.44 31-Dec-2012  dsl Add support for '%n' being a shorthand for 'fg %n'.
 1.43 20-Mar-2012  matt branches: 1.43.2;
Use C89 function definitions
 1.42 16-Oct-2008  dholland branches: 1.42.18; 1.42.20;
Wrap declaration of a STATIC function that's only conditionally defined
in a suitable ifdef, so things still compile if STATIC is defined as
"static", which is for some reason not the default.

(In the long run STATIC should go away - it might have once been a
portability hack but now definitely serves no purpose.)
 1.41 15-Feb-2008  matt Fix inconsistent definitions
 1.40 24-Jun-2007  christos branches: 1.40.4;
PR/36531: Greg A. Woods: another very helpful DEBUG TRACE() call for execve()
failures in /bin/sh
 1.39 18-Mar-2006  christos Coverity CID 890: Possible NULL pointer deref.
 1.38 18-Mar-2006  christos Coverity CID 1329: Possible NULL deref.
 1.37 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.36 04-Feb-2003  dsl Fix bin/20185 - builtin called from function of same name mustn't be hashed.
Make 'hash' only report utilities that are not builtins (posix), the
non-posix 'hash -v' will report everything.
(agreed by christos)
 1.35 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.34 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.33 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.32 04-Feb-2001  christos branches: 1.32.2;
remove redundant declarations and nexted externs.
 1.31 01-Nov-2000  christos handle type command on names that contain slashes, and print a : in the not
found case. From FreeBSD.
 1.30 03-Jul-2000  matt include <stdlib.h>, <string.h>, or whatever as appropriate to shut up
gcc 2.96
 1.29 22-May-2000  elric branches: 1.29.4;
Back out previous vfork changes.
 1.28 13-May-2000  elric Now we use vfork(2) instead of fork(2) when we can.
 1.27 09-Jul-1999  christos compile with WARNS = 2
 1.26 28-Jul-1998  mycroft Be more retentive about use of NOTREACHED and noreturn.
 1.25 28-Jul-1998  mycroft Delint.
 1.24 20-Jul-1997  christos PR/3888: Chris Demetriou: type command-with-slash prints
$PATH[0]/command-with-slash...
 1.23 04-Jul-1997  christos Fix compiler warnings.
 1.22 06-Feb-1997  christos add type builtin.
 1.21 11-Jan-1997  tls kill 'register'
 1.20 19-Oct-1996  abrown Remove leftover printf("here") from last change.
 1.19 16-Oct-1996  christos PR/287: Shell does not exit with 126/127 when permission denied/
command not found. Add extra exception type and generalize
error handling routines to take that exception type. Use
a global variable exerrno to keep the last exec error.
 1.18 25-Jun-1996  christos const poisoning.
 1.17 09-Jun-1995  christos branches: 1.17.6;
Changed so that 'PATH=newpath command' works, instead of looking at the
old path. Synced input.c with vangogh.
 1.16 11-May-1995  christos Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.15 21-Mar-1995  cgd convert to new RCS id conventions.
 1.14 30-Jan-1995  mycroft Use S_IS*().
 1.13 15-Jan-1995  mycroft Remove the gratuitous `security' warning.
 1.12 05-Dec-1994  cgd clean up further. more patches from Jim Jegers
 1.11 23-Sep-1994  mycroft Eliminate uses of some obsolete functions.
 1.10 11-Jun-1994  mycroft Add RCS ids.
 1.9 12-May-1994  jtc Include appropriate header files to bring function prototypes into scope.
 1.8 11-May-1994  jtc sync with 4.4lite
 1.7 01-Apr-1994  jtc Getgroup's second argument is now a gid_t ptr.
 1.6 23-Sep-1993  mycroft Root can execute anything with at least one execute bit set.
 1.5 01-Aug-1993  mycroft Add RCS identifiers.
 1.4 10-Apr-1993  cgd from "Andrew A. Chernov, Black Mage" <ache@astral.msk.su>
When sh tried to find_command() for execution (without full path),
it checked ONLY ONE current effective group execution permissions,
but didn't check another valid groups from /etc/group.
 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.17.6.2 04-Mar-1997  mycroft Pull up latest sh(1). Fixes yet more bugs.
 1.17.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.29.4.1 03-Nov-2000  tv Pullup 1.31 [hubertf]:
Fixes bug in 'type' command WRT slashes.
 1.32.2.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.40.4.1 23-Mar-2008  matt sync with HEAD
 1.42.20.1 16-Nov-2016  snj Pull up following revision(s) (requested by dholland in ticket #1412):
bin/sh/exec.c: revision 1.45
bin/sh/var.c: revision 1.43
PR/48312: Dieter Roelants: According to TOG, unset should not return an error
for functions are variables that were not previously set:
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
 1.42.18.3 22-May-2014  yamt sync with head.

for a reference, the tree before this commit was tagged
as yamt-pagecache-tag8.

this commit was splitted into small chunks to avoid
a limitation of cvs. ("Protocol error: too many arguments")
 1.42.18.2 23-Jan-2013  yamt sync with head
 1.42.18.1 17-Apr-2012  yamt sync with head
 1.43.2.2 19-Aug-2014  tls Rebase to HEAD as of a few days ago.
 1.43.2.1 25-Feb-2013  tls resync with head
 1.46.6.1 19-May-2017  pgoyette Resolve conflicts from previous merge (all resulting from $NetBSD
keywork expansion)
 1.47.2.5 07-Dec-2020  martin Pull up following revision(s) (requested by kre in ticket #1629):

bin/sh/exec.c: revision 1.54

PR bin/55526

Fix a bug that has existed since the "command" command was added in
2003. "command foo" would cause the definition of a function "foo"
to be lost (not freed, simply discarded) if "foo" is (in addition to
being a function) a filesystem command. The case where "foo" is
a builtin was handled.

For now, when a function exists with the same name as a filesystem
command, the latter can never appear in the command hash table, and
when used (which can only be via "command foo", just "foo" finds
the function) will always result in a full PATH search.

XXX pullup everything (from NetBSD 2.0 onwards). (really -8 and -9)
 1.47.2.4 25-Aug-2018  martin Pull up following revision(s) (requested by kre in ticket #989):

bin/sh/eval.c: revision 1.156
bin/sh/eval.h: revision 1.20
bin/sh/exec.c: revision 1.53

Fix several bugs in the command / type builtin ( including PR bin/48499 )

1. Make command -pv (and -pV) work (which is not as easy as the PR
suggests it might be (the "check and cause error" was there because
it did not work, not in order to prevent it from working).

2. Stop -v and -V being both used (that makes no sense).

3. Stop the "type" builtin inheriting the args (-pvV) that "command" has
(which it did, as when -v -or -V is used with command, it and type are
implemented using the same code).

4. make "command -v word" DTRT for sh keywords (was treating them as an error).

5. Require at least one arg for "command -[vV]" or "type" else usage & error.
Strictly this should also apply to "command" and "command -p" (no -v)
but that's handled elsewhere, so perhaps some other time. Perhaps
"command -v" (and -V) should be limited to 1 command name (where "type"
can have many) as in the POSIX definitions, but I don't think that matters.

6. With "command -V alias", (or "type alias" which is the same thing),
(but not "command -v alias") alter the output format, so we get
ll is an alias for: ls -al
instead of the old
ll is an alias for
ls -al
(and note there was a space, for some reason, after "for")
That is, unless the alias value contains any \n characters, in which
case (something approximating) the old multi-line format is retained.
Also note: that if code wants to parse/use the value of an alias, it
should be using the output of "alias name", not command or type.

Note that none of the above affects "command [-p] cmd" (no -v or -V options)
only "command -[vV]" and "type".

Note also that the changes to eval.[ch] are merely to make syspath()
visible in exec.c rather than static in eval.c
 1.47.2.3 13-Jul-2018  martin Pull up following revision(s) (requested by kre in ticket #906):

bin/sh/eval.c: revision 1.155
bin/sh/mknodes.sh: revision 1.3
bin/sh/nodes.c.pat: revision 1.14
bin/sh/exec.h: revision 1.27
bin/sh/exec.c: revision 1.52

Deal with ref after free found by ASAN when a function redefines
itself, or some other function which is still active.

This was a long known bug (fixed ages ago in the FreeBSD sh) which
hadn't been fixed as in practice, the situation that causes the
problem simply doesn't arise .. ASAN found it in the sh dotcmd
tests which do have this odd "feature" in the way they are written
(but where it never caused a problem, as the tests are so simple
that no mem is ever allocated between when the old version of the
function was deleted, and when it finished executing, so its code
all remained intact, despite having been freed.)

The fix is taken from the FreeBSD sh.

XXX -- pullup-8 (after a while to ensure no other problems arise).
 1.47.2.2 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.47.2.1 05-Jun-2017  snj Pull up following revision(s) (requested by kre in ticket #5):
bin/sh/cd.c: revision 1.48
bin/sh/eval.c: revision 1.141
bin/sh/exec.c: revision 1.48
bin/sh/exec.h: revision 1.25
bin/sh/mail.c: revisions 1.17, 1.18
bin/sh/sh.1: revision 1.147
Make cd (really) do cd -P, and not just claim that is what it is doing
while doing a half-hearted, broken, partial, version of cd -L instead.
The latter (as the manual says) is not supported, what's more, it is an
abomination, and should never be supported (anywhere.)
Fix the doc so that the pretense that we notice when a path given crosses
a symlink (and turns on printing of the destination directory) is claimed
no more (that used to be true until late Dec 2016, but was changed). Now
the print happens if -o cdprint is set, or if an entry from CDPATH that is
not "" or "." is used (or if the "cd dest repl" cd cmd variant is used.)
Fix CDPATH processing: avoid the magic '%' processing that is used for
PATH and MAILPATH from corrupting CDPATH. The % magic (both variants)
remains undocumented.
Also, don't double the '/' if an entry in PATH or CDPATH ends in '/'
(as in CDPATH=":/usr/src/"). A "cd usr.bin" used to do
chdir("/usr/src//usr.bin"). No more. This is almost invisible,
and relatively harmless, either way....
Also fix a bug where if a plausible destination directory in CDPATH
was located, but the chdir() failed (eg: permission denied) and then
a later "." or "" CDPATH entry succeeded, "print" mode was turned on.
That is:
cd /tmp; mkdir bin
mkdir -p P/bin; chmod 0 P/bin
CDPATH=/tmp/P:
cd bin
would cd to /tmp/bin (correctly) but print it (incorrectly).
Also when in "cd dest replace" mode, if the result of the replacement
generates '-' as the path named, as in:
cd $PWD -
then simply change to '-' (or attempt to, with CDPATH search), rather
than having this being equivalent to "cd -")
Because of these changes, the pwd command (and $PWD) essentially
always acts as pwd -P, even when called as pwd -L (which is still
the default.) That is, even more than it did before.
Also fixed a (kind of minor) mem management error (CDPATH related)
"whosoever shall padvance must stunalloc before repeating" (and the
same for MAILPATH).
--
If we are going to keep the MAILPATH % hack, then at least do something
rational. Since it isn't documented, what "rational" is is up for
discussion, but what it did before was not it (it was nonsense...).
 1.51.4.2 28-Jul-2018  pgoyette Sync with HEAD
 1.51.4.1 25-Jun-2018  pgoyette Sync with HEAD
 1.52.2.3 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.52.2.2 21-Apr-2020  martin Sync with HEAD
 1.52.2.1 10-Jun-2019  christos Sync with HEAD
 1.53.2.2 06-Apr-2021  martin Pull up following revision(s) (requested by kre in ticket #1242):

bin/sh/input.c: revision 1.72
bin/sh/exec.c: revision 1.55

PR bin/55979

This fixes the MSAN detected reference to an unitialised variable
(an unitialised field in a struct) which happens when a command is
not found after a PATH search.
Aside from skipping some known to be going to fail exec*() calls
in some cases, the setting of the relevant field is irrelevant,
so this problem makes no practical difference to the shell, or any
shell script.

XXX (maybe) pullup -9


PR bin/55979

Correctly handle (ie: ignore completely) \0 chars (nuls) in the
shell command input stream (script, dot file, or stdin).
Previously nul chars were ignored correctly in the line in which
they occurred, but would cause trailing chars of that line to reappear
as the start of the following line. If there was just one \0 skipped,
this would generally result in an extra \n in the sh input, which in
most cases has no effect. With multiple \0's in a single line, more
of the end of that line was duplicated into the following one. This
usually manifested as a weird "command not found" error.

Note that any \0 chars in the sh input make the script non-conforming,
so fixing this is not crucial (no \0's should really ever be seen) but
it was an obvious bug in the code, which was attempting to ignore nul
chars (as do many other shells), so let it be fixed.

XXX pullup -9
 1.53.2.1 27-Aug-2020  martin Pull up following revision(s) (requested by kre in ticket #1064):

bin/sh/exec.c: revision 1.54

PR bin/55526

Fix a bug that has existed since the "command" command was added in
2003. "command foo" would cause the definition of a function "foo"
to be lost (not freed, simply discarded) if "foo" is (in addition to
being a function) a filesystem command. The case where "foo" is
a builtin was handled.

For now, when a function exists with the same name as a filesystem
command, the latter can never appear in the command hash table, and
when used (which can only be via "command foo", just "foo" finds
the function) will always result in a full PATH search.

XXX pullup everything (from NetBSD 2.0 onwards). (really -8 and -9)
 1.58.2.1 02-Aug-2025  perseant Sync with HEAD
 1.28 12-Jul-2024  kre Improve safety in var imports from the environment.

Add a new var flag VUNSAFE - set on all vars imported from the environment.

Add setvareqsafe() (which is to setvareq() as setvarsafe() is to setvar())
and use that instead of setvareq() when processing the environment, so
errors don't cause the shell to abort. Use VUNSAFE in that call.

Add flags arguments to all var callback functions which are used when setting
variables, and pass the flags given to the setvar*() functions to those
functions, so they can act differently in different situations (if desired).
Most of them just ignore the flags.

When unsetting a variable, call setvar() to clear things (and call the
callback function) both when the variable had a value which needs to be freed,
and when unsetting a variable which wasn't unset previously, so the VUNSET
flag can be seen by that callback func.

When setting HISTSIZE, use the flags passed to determine whether to ignore
bad values (if VUNSAFE) or treat them as an error. This replaces the
earlier temporary hack to always ignore bad data there (histedit.c 1.68).

Miscellaneous associated minor changes.

These changes should largely be invisible in normal use.
 1.27 22-Jun-2018  kre branches: 1.27.2; 1.27.14;
Deal with ref after free found by ASAN when a function redefines
itself, or some other function which is still active.
This was a long known bug (fixed ages ago in the FreeBSD sh) which
hadn't been fixed as in practice, the situation that causes the
problem simply doesn't arise .. ASAN found it in the sh dotcmd
tests which do have this odd "feature" in the way they are written
(but where it never caused a problem, as the tests are so simple
that no mem is ever allocated between when the old version of the
function was deleted, and when it finished executing, so its code
all remained intact, despite having been freed.)

The fix is taken from the FreeBSD sh.

XXX -- pullup-8 (after a while to ensure no other problems arise).
 1.26 07-Jun-2017  kre branches: 1.26.4;
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)

This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)

The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.

This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).

I would not call the results of this perfect yet, but it is close.
 1.25 04-Jun-2017  kre Make cd (really) do cd -P, and not just claim that is what it is doing
while doing a half-hearted, broken, partial, version of cd -L instead.
The latter (as the manual says) is not supported, what's more, it is an
abomination, and should never be supported (anywhere.)

Fix the doc so that the pretense that we notice when a path given crosses
a symlink (and turns on printing of the destination directory) is claimed
no more (that used to be true until late Dec 2016, but was changed). Now
the print happens if -o cdprint is set, or if an entry from CDPATH that is
not "" or "." is used (or if the "cd dest repl" cd cmd variant is used.)

Fix CDPATH processing: avoid the magic '%' processing that is used for
PATH and MAILPATH from corrupting CDPATH. The % magic (both variants)
remains undocumented.

Also, don't double the '/' if an entry in PATH or CDPATH ends in '/'
(as in CDPATH=":/usr/src/"). A "cd usr.bin" used to do
chdir("/usr/src//usr.bin"). No more. This is almost invisible,
and relatively harmless, either way....

Also fix a bug where if a plausible destination directory in CDPATH
was located, but the chdir() failed (eg: permission denied) and then
a later "." or "" CDPATH entry succeeded, "print" mode was turned on.
That is:
cd /tmp; mkdir bin
mkdir -p P/bin; chmod 0 P/bin
CDPATH=/tmp/P:
cd bin
would cd to /tmp/bin (correctly) but print it (incorrectly).

Also when in "cd dest replace" mode, if the result of the replacement
generates '-' as the path named, as in:
cd $PWD -
then simply change to '-' (or attempt to, with CDPATH search), rather
than having this being equivalent to "cd -")

Because of these changes, the pwd command (and $PWD) essentially
always acts as pwd -P, even when called as pwd -L (which is still
the default.) That is, even more than it did before.

Also fixed a (kind of minor) mem management error (CDPATH related)
"whosoever shall padvance must stunalloc before repeating" (and the
same for MAILPATH).
 1.24 03-May-2016  kre branches: 1.24.8;

Fix things so that STATIC can me made static (-DSTATIC=static)
and have the shell still compile, link, and run...

ok christos@
 1.23 15-Mar-2012  joerg Add __printflike attribution to use vprintf and friends with an argument
as format string.
 1.22 18-Jun-2011  christos branches: 1.22.2;
PR/45069: Henning Petersen: Use prototypes from builtins.h .
 1.21 07-Aug-2003  agc branches: 1.21.52;
Move UCB-licensed code from 4-clause to 3-clause licence.

Patches provided by Joel Baker in PR 22249, verified by myself.
 1.20 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.19 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.18 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.17 22-May-2000  elric branches: 1.17.6;
Back out previous vfork changes.
 1.16 13-May-2000  elric Now we use vfork(2) instead of fork(2) when we can.
 1.15 09-Jul-1999  christos compile with WARNS = 2
 1.14 28-Jul-1998  mycroft Be more retentive about use of NOTREACHED and noreturn.
 1.13 20-Jul-1997  christos PR/3888: Chris Demetriou: type command-with-slash prints
$PATH[0]/command-with-slash...
 1.12 06-Feb-1997  christos add type builtin.
 1.11 16-Oct-1996  christos PR/287: Shell does not exit with 126/127 when permission denied/
command not found. Add extra exception type and generalize
error handling routines to take that exception type. Use
a global variable exerrno to keep the last exec error.
 1.10 25-Jun-1996  christos const poisoning.
 1.9 09-Jun-1995  christos branches: 1.9.6;
Changed so that 'PATH=newpath command' works, instead of looking at the
old path. Synced input.c with vangogh.
 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.9.6.2 04-Mar-1997  mycroft Pull up latest sh(1). Fixes yet more bugs.
 1.9.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.17.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.21.52.1 23-Jun-2011  cherry Catchup with rmind-uvmplock merge.
 1.22.2.1 17-Apr-2012  yamt sync with head
 1.24.8.3 13-Jul-2018  martin Pull up following revision(s) (requested by kre in ticket #906):

bin/sh/eval.c: revision 1.155
bin/sh/mknodes.sh: revision 1.3
bin/sh/nodes.c.pat: revision 1.14
bin/sh/exec.h: revision 1.27
bin/sh/exec.c: revision 1.52

Deal with ref after free found by ASAN when a function redefines
itself, or some other function which is still active.

This was a long known bug (fixed ages ago in the FreeBSD sh) which
hadn't been fixed as in practice, the situation that causes the
problem simply doesn't arise .. ASAN found it in the sh dotcmd
tests which do have this odd "feature" in the way they are written
(but where it never caused a problem, as the tests are so simple
that no mem is ever allocated between when the old version of the
function was deleted, and when it finished executing, so its code
all remained intact, despite having been freed.)

The fix is taken from the FreeBSD sh.

XXX -- pullup-8 (after a while to ensure no other problems arise).
 1.24.8.2 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.24.8.1 05-Jun-2017  snj Pull up following revision(s) (requested by kre in ticket #5):
bin/sh/cd.c: revision 1.48
bin/sh/eval.c: revision 1.141
bin/sh/exec.c: revision 1.48
bin/sh/exec.h: revision 1.25
bin/sh/mail.c: revisions 1.17, 1.18
bin/sh/sh.1: revision 1.147
Make cd (really) do cd -P, and not just claim that is what it is doing
while doing a half-hearted, broken, partial, version of cd -L instead.
The latter (as the manual says) is not supported, what's more, it is an
abomination, and should never be supported (anywhere.)
Fix the doc so that the pretense that we notice when a path given crosses
a symlink (and turns on printing of the destination directory) is claimed
no more (that used to be true until late Dec 2016, but was changed). Now
the print happens if -o cdprint is set, or if an entry from CDPATH that is
not "" or "." is used (or if the "cd dest repl" cd cmd variant is used.)
Fix CDPATH processing: avoid the magic '%' processing that is used for
PATH and MAILPATH from corrupting CDPATH. The % magic (both variants)
remains undocumented.
Also, don't double the '/' if an entry in PATH or CDPATH ends in '/'
(as in CDPATH=":/usr/src/"). A "cd usr.bin" used to do
chdir("/usr/src//usr.bin"). No more. This is almost invisible,
and relatively harmless, either way....
Also fix a bug where if a plausible destination directory in CDPATH
was located, but the chdir() failed (eg: permission denied) and then
a later "." or "" CDPATH entry succeeded, "print" mode was turned on.
That is:
cd /tmp; mkdir bin
mkdir -p P/bin; chmod 0 P/bin
CDPATH=/tmp/P:
cd bin
would cd to /tmp/bin (correctly) but print it (incorrectly).
Also when in "cd dest replace" mode, if the result of the replacement
generates '-' as the path named, as in:
cd $PWD -
then simply change to '-' (or attempt to, with CDPATH search), rather
than having this being equivalent to "cd -")
Because of these changes, the pwd command (and $PWD) essentially
always acts as pwd -P, even when called as pwd -L (which is still
the default.) That is, even more than it did before.
Also fixed a (kind of minor) mem management error (CDPATH related)
"whosoever shall padvance must stunalloc before repeating" (and the
same for MAILPATH).
--
If we are going to keep the MAILPATH % hack, then at least do something
rational. Since it isn't documented, what "rational" is is up for
discussion, but what it did before was not it (it was nonsense...).
 1.26.4.1 25-Jun-2018  pgoyette Sync with HEAD
 1.27.14.1 02-Aug-2025  perseant Sync with HEAD
 1.27.2.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.27.2.1 21-Apr-2020  martin Sync with HEAD
 1.147 07-May-2025  kre Obliterate the global var herefd

For the past several years (since Nov 2021) the global var "herefd"
has led a rather meaningless existence.

It gets statically init'd to -1 (at compile time), and several
times its value is carefully saved, set to -1, then restored later.
(Lots of copying around of -1 going on there!)

The only use of its value was removed in the immediately previous update
to memalloc.c, where it was tested, and if its value were >= 0 ...
(no point mentioning what would happen, since its value is always -1,
since Nov 2021).

Bye bye herefd, it was nice knowing you. May we never meet again.
 1.146 21-Oct-2024  kre Fix processing of unknown variable expansion types.

Our shell is (was) one of the last not to do this correctly.

Expansions are supposed to happen only when the command in which
they occur is being executed, not while it is being parsed.
If the expansion only happens them, errors should only be
detected then.

Make it work like that (I saw after I fixed this that FreeBSD
had done it, long ago, almost the same way - it is kind of an
obvious thing to do).

This will allow code like

if test it is shell X
then
commands using shell X specific expansion ops
else if it is shell Y
then
commands using shell Y specific expansion ops
else ...
fi

Previously expansion errors were detected while parsing, so
if we're not shell X, and don't implement something that it
does (some extension to the standard) that would have generated
a parser syntax error, and the script could not be executed
(despite the line with the error never being executed).

Note that this change does not handle all such possible
extensions, just this one. Others are much harder.

One side effect of this change is that sh will now continue
reading a variable expansion until it locates the terminating
'}' (in ${var} forms) regardless of how broken it obviously
is (to our shell) whereas previously it would have bailed out
as soon as an oddity was spotted.
 1.145 03-Oct-2024  rillig bin: fix lint warning "effectively discards 'const'"

For example: src/bin/ed/io.c(339): warning: call to 'strchr' effectively
discards 'const' from argument [346]

No binary change.
 1.144 29-Dec-2023  kre branches: 1.144.2;
PR bin/57773

Fix another bug reported by Jarle Fredrik Greipsland and added
to PR bin/57773, which relates to calculating the length of a
positional parameter which contains CTL chars -- yes, this one
really is that specific, though it would also affect the special
param $0 if it were to contain CTL chars, and its length was
requested - that is fixed with the same change. And note: $0
is not affected because it looks like a positional param (it
isn't, ${00} would be, but is always unset, ${0} isn't) all
special parame would be affected the same way, but the only one
that can ever contain a CTL char is $0 I believe. ($@ and $*
were affected, but just because they're expanding the positional
params ... ${#@} and ${#*} are both technically unspecified
expansions - and different shells produce different results.

See the PR for the details of this one (and the previous).

Thanks for the PR.

XXX pullup to everything.
 1.143 25-Dec-2023  kre Correct a bizarre piece of source formatting that crept in by
accident several years ago (change a space into newline tab).

NFC
 1.142 06-Mar-2023  kre Adjust tilde expansion as will be documented in the forthcoming
version of the POSIX standard (Issue 8). I believe we were already
compliant with what is to be required, but POSIX is now encouraging
(and will likely require in a later version) that if a tilde expansion
produces a string which ends in a '/' and the '~' that was expanded
is immediately followed by a '/' in the input word, that one of those
two slashes be omitted. The worst (current) example of this is
when HOME=/ and we expand ~/foo - previously producing //foo which is
(in POSIX) a path with implementation defined semantics, and so not
what we should be generating by accident. Change that, so now if
the ~ prefix expansion ends in a '/' and there is a '/' following
immediately after, the resulting word contains only one of those
chars (in the example just given, we will now produce /foo instead).

POSIX is also making it clear that the expansion that results from
the tilde expansion is treated as quoted (not subject to pathname
expansion, or field splitting, or any var/arith/command substitutions)
and that if HOME="" the expansion of ~ must generate "" (not nothing).
Our implementation did all of that already (though older versions
used to treat an empty expansion of HOME the same as if HOME was
unset - that was fixed some time ago).

The actual modification made here is probably smaller than this log entry,
and without added comments, certainly is!
 1.141 22-Nov-2021  kre branches: 1.141.2;

PR bin/53550

Here we go again... One more time to redo how here docs are
processed (it has been a few years since the last time!)

This is actually a relatively minor change, mostly to timimg
(to just when things happen). Now here docs are expanded at the
same time the "filename" word in a redirect is expanded, rather than
later when the heredoc was being sent to its process. This actually
makes things more consistent - but does break one of the ATF tests
which was testing that we were (effectively) internally inconsistent
in this area.

Not all shells agree on the context in which redirection expansions
should happen, some make any side effects visible to the parent shell
(the majority do) others do the redirection expansions in a subshell
so any side effcts are lost. We used to have a foot in each camp,
with the majority for everything but here docs, and the minority for
here docs. Now we're all the way with LBJ ... (or something like that).
 1.140 10-Nov-2021  kre DEBUG mode changes only. NFC (NC) for any normally compiled shell.

Mostly adding DEBUG mode tracing (when appropriate verbose tracing
is enabled generally) whenever a shell (including sushell) process
exits, so shells that the tracing should indicate why ehslls that
vanish did that.

Note for future investigators: if the relevant tracing is enabled,
and a (sub-)shell still simply seems to have vanished without trace,
the likely cause is that it was killed by a signal - and of those,
the most common that occurs is SIGPIPE.
 1.139 10-Sep-2021  rillig bin: remove unnecessary lint comment CONSTCOND

Since 2021-01-31, lint no longer warns about 'do ... while (0)'.

No functional change.
 1.138 01-Aug-2020  kre Remove a redundant set of parentheses that were added (along with a
extra && or || or something ... forgotten now) as part a failed attempt
to fix an earlier bug (later fixed a better way) - when the extra
test (never committed) was removed, the now-redundant parentheses got
forgotten...

NFC.
 1.137 13-Feb-2020  kre When expanding a here-doc (NXHERE - the type with an unquoted end delim)
the output will not be further processed (at all) so there is no need
to escape magic chars in the output, and doing so leaves stray CTLESC
chars in the here doc text. Not good. So don't do that...

To save a strlen() of the result, to determine the size of the here doc,
make rmescapes() return the length of the resulting string (this isn't
needed for other uses, so didn't happen previously).

Reported on current-users@ (2020-02-06) by Jun Ebihara

XXX pullup -9
 1.136 14-Oct-2019  christos remove masking and cast (requested by kre@)
 1.135 13-Oct-2019  christos prevent sign extension from making expression always false.
 1.134 08-Oct-2019  kre Remove a (completely harmless) duplicate assignment introduced in a
code merge from FreeBSD in 2017. NFC.

Pointed out by Roland Illig.
 1.133 08-Oct-2019  kre Open code the validity test & copy of the character class name in
a bracket expression in a pattern (ie: [[:THISNAME:]]). Previously
the code used strspn() to look for invalid chars in the name, and
then memcpy(), now we do the test and copy a character at a time.
This might, or might not, be faster, but it now correctly handles
\ quoted characters in the name (' and " quoting were already
dealt with, \ was too in an earlier version, but when the \ handling
changes were made, this piece of code broke).

Not exactly a vital bug fix (who writes [[:\alpha:]] or similar?)
but it should work correctly regardless of how obscure the usage is.

Problem noted by Harald van Dijk

XXX pullup -9
 1.132 10-Apr-2019  kre branches: 1.132.2;
PR bin/54112

Fix handling of "$@" (that is, double quoted dollar at), when it
appears in a string which will be subject to field splitting.

Eg:
${0+"$@" }

More common usages, like the simple "$@" or ${0+"$@"} end up
being entirely quoted, so no field splitting happens, and the
problem was avoided.

See the PR for more details.

This ends up making a bunch of old hack code (and some that was
relatively new) vanish - for now it is just #if 0'd or commented out.
Cleanups of that stuff will happen later.

That some of the worst $@ hacks are now gone does not mean that processing
of "$@" does not retain a very special place in every hackers heart.
RIP extreme ugliness - long live the merely ordinary ugly.

Added a new bin/sh ATF test case to verify that all this remains fixed.
 1.131 27-Feb-2019  kre Finish the fixes from Feb 4 for handling of random data that
matches the internal CTL* chars.

The earlier fixes handled CTL* char values in var expansions,
but not in various other places they can occur (positional
parameters, $@ $* -- even potentially $0 and ~ expansions,
as well as byte strings generated from a \u in a $'' string).

These should all be correctly handled now. There is a new
ISCTL() macro to make the test, rather than using the old
BASESYNTAX[c]==CCTL form (which us still a viable alternative)
as the new way allows compiler optimisations, and less mem
references, so it should be smaller and faster.

Also, be sure in all cases to remove any CTLESC (or other)
CTL* chars from all strings before they are made available
for any external use (there was one case missed - which didn't
matter when we weren't bothering to escape the CTL* chars at
all.)

XXX pullup-8 (will need to be via a patch) along with the Feb 4 fixes.
 1.130 04-Feb-2019  kre Fix an old bug (very old) that was made worse in 1.128 (the "${1+$@}"
fixes) where a variable containing a CTL char (the only possibility used
to be CTLESC (0x81)) would lose that character if the variable was expanded
when "set -f" (noglob) was in effect.

1.128 made this worse by adding more 0x8z values (a couple more) which would
see the same behaviour, and one of those was noticed by Martijn Dekker.

The reasoning was that when noglob is on, when a var is expanded, there are
no magic chars, so (apparently) no need to escape anything. Hence nothing
was escaped .. including any CTL chars that happened to be present. When
we later rmescapes() the CTL chars that we expect might occur are summarily
removed - even if they weren't really CTL chars, but just data masquerading.

We must *always* escape any CTL char clones that are in the var value,
no matter what other conditions apply, and what we expect to happen next.

While here, fix rmescapes() (and its $(()) clone, rmescapes_nl()) to
be more robust, less likely to forget to delete anything (which was
not the issue here, just the reverse) and in a DEBUG shell, have the
shell abort() if it encounters something in rmescapes() it is not
anticipating, so the code can be made to handle it, or if it should
not happen, we can find out why it did.

XXX pullup -8 (but will need to be via patch, code is quite different).
 1.129 03-Dec-2018  kre Yet another foray into the mysterious world of $@ -- this time
to fix the (unusual) idiom "${1+$@}" (the quotes are part of it).
This seems to have broken about 5 or 6 years ago (somewhere
between -6 and -7), I believe.

Note this is not the same as "$@" and also not the same as ${1+"$@"}
(much more common idioms) which both worked.

Also attempt to deal with "" more correctly, especially when it
appears adjacent to "$@" (or one of the similar constructs.)

This stuff is still all as ugly and hackish (and fragile) as is
possible to imagine, but in an effort to allow some of the weirdness
to eventually go away, the parser output has been made more
regular and all quoted (parts of) words always now start with
CTLQUOTEMARK and end with CTLQUOTEEND regardless of where the
quotes appear.

This allows us to tell the difference between """$@" and "$@"
which was impossible before - yet they are required to generate
different output when there are no args (when "$@" simply vanishes).

Needless to say that change had ramifications all over the place.
To simplify any similar change in the future, there are some new
macros that can generally be used to detect the "noise" data when
processing words, rather than open coding that every time (which
meant that there would *always* be one which missed getting
updated...)

Several other bugs (of my making, and older ones) are also fixed.

The aim is that (aside from anything that is detecting the cases
that were broken before - which were all unlikely uses of sh
syntax) these changes should have no external visible impact.

Sure...
 1.128 18-Nov-2018  kre Rationalise (slightly) the way that expansions are processed
to hide meta-characters in the result when the expansion was
in (double) quotes, and so should not be further processed.

Most of this has been OK for a long while, but \ needs hiding
as well, which complicates things, as \ cannot simply be hidden
in the syntax tables as one of the group of random special characters.

This was fixed earlier for simple variable expansions, but
every variety has its own code path ($var uses different code
than $n which is different than $(...), which is different
again from ~ expansions, and also from what $'...' produces).

This could be fixed by moving them all to a common code path,
but that's harder than it seems. The form in which the data
is made available differs, so one common routine would need
a whole bunch of different "get the next char or indicate end"
methods - probably via passing in an accessor function.
That's all a lot of churn, and would probably slow the shell.

Instead, just make macros for doing the standard tests, and
use those instead of open coding (differently) each time.
This way some of the code paths don't end up forgetting to
handle '\' (which is different than all the others).

This removes one optimisation ... when no escaping is needed
(like just $var (unquoted) where magic chars (think '*') in
the value are intended to remain magic), the code avoided doing
two tests for each char ("do we need escapes" and "is this char
one that needs escaping") by choosing two different syntax
tables (choice made outside the loop) - one of which never
returns the magic "needs escaping" result, and the other does
when appropriate, and then just avoiding the "do we need escapes"
test for each character processed. Then when '\' was fixed,
there needed to be another test for it, as it cannot (for other
reasons) be the same as all the others for which "this char
need escaping" is true. So that added a 2nd test for each char...
Not all the code paths were updated. Hence the bugs...

nb: this is all rarely seen in the wild, so it is no big
surprised that no-one ever noticed.

Now the "use two different syntax tables" is gone (the two
returned the same for '\' which is why '\' needed special
processing) - and in order to avoid two tests for each
char (plus the \ test) we duplicate the loops, one of which
tests each char to see if it needs an escape, the 2nd just
copies them. This should be faster in the "no escapes"
code path (though that is not the point) and perhaps also
in the "escapes needed" path (no indirect reference to
the syntax table - though that would probably be in a
register) but makes the code slightly bigger. For /bin/sh
the text segment (on amd64) has grown by 48 bytes. But
it still uses the same number of 512 byte pages (and hence
also any bigger page size). The resulting file size
(/bin/sh) is identical before and after. So is /rescue/sh
(or /rescue/anything-else).
 1.127 22-Jul-2018  kre Part 2 of pattern matching (glob etc) fixes.

Attempt to correctly deal with \ (both when it is a literal,
in appropriate cases, and when it appears as CTLESC when it was
detected as a quoting character during parsing).

In a pattern, in sh, no quoted character can ever be anything other
than a literal character. This is quite different than regular
expressions, and even different than other uses of glob matching,
where shell quoting is not an issue.

In something like

ls ?\*.c

the ? is a meta-character, the * is a literal (it was quoted). This
is nothing new, sh has handled that properly for ever.

But the same happens with
VAR='?\*.c'
and
ls $VAR

which has not always been handled correctly. Of course, in

ls "$VAR"

nothing in VAR is a meta-character (the entire expansion is quoted)
so even the '\' must match literally (or more accurately, no matching
happens - VAR simply contains an "unusual" filename). But if it had
been

ls *"$VAR"

then we would be looking for filenames that end with the literal 5
characters that make up $VAR.

The same kinds of things are requires of matching patterns in case
statements, and sub-strings with the % and # operators in variable
expansions.

While here, the final remnant of the ancient !! pattern matching
hack has been removed (the code that actually implemented it was
long gone, but one small piece remained, not doing any real harm,
but potentially wasting time - if someone gave a pattern which would
once have invoked that hack.)
 1.126 22-Jul-2018  kre NFC: Whitespace cleanups
 1.125 22-Jul-2018  kre DEBUG mode only change (ie: no effect to any normal shell).

Add tracing of pattern matching (aid in debugging various issues.)
 1.124 20-Jul-2018  kre First pass at fixing some of the more arcane pattern matching
possibilities that we do not currently handle all that well.

This mostly means (for now) making sure that quoted pattern
magic characters (as well as quoted sh syntax magic chars)
are properly marked, so they remain known as being quoted,
and do not turn into pattern magic. Also, make sure that an
unquoted \ in a pattern always quotes whatever comes next
(which, unlike in regular expressions, includes inside []
matches),
 1.123 22-Jun-2018  kre branches: 1.123.2;

When processing character classes ([:xxx:] inside []), treat a class name
that is longer than we can handle the same way we treat an unknown
class name (as a valid char class which contains nothing, so never
matches). Previously a "too long" class name invalidated the
class, so [:very-long-name:] would match any of '[' ':' 'v' ...
(note: "very-long-name" is not long enough to trigger this, but you
get the idea!)

However, the name itself has a restricted syntax ([[:***:]] is not a
character class, it is a match for one of a '[' ':' or '*', followed by
a ']') which we did not implement - check the syntax of the name before
treating it as a character class (but we do add '_' to alphanumerics
as legal class name characters).
 1.122 22-Jun-2018  kre When matching a char class ([[:name:]]) in a pattern (for filename
expansion, case patterrns, etc) do not force '[' to be a member of
every class.

Before this fix, try:
case [ in [[:alpha:]]) echo Huh\?;; esac

XXX pullup-8 (Perhaps -7 as well, though that shell version has
much more relevant bugs than this one.) This bug is not in -6 as
that has no charclass support.
 1.121 06-Oct-2017  kre branches: 1.121.2;
Three fixes and a change to ~ expansions

1. A serious bug introduced 3 1/2 months ago (approx) (rev 1.116) which
broke all but the simple cases of ~ expansions is fixed (amazingly,
given the magnitude of this problem, no-one noticed!)

2. An ancient bug (probably from when ~ expansion was first addedin 1994, and
certainly is in NetBSD-6 vintage shells) where ${UnSeT:-~} (and similar)
does not expand the ~ is fixed (note that ${UnSeT:-~/} does expand,
this should give a clue to the cause of the problem.

3. A fix/change to make the effects of ~ expansions on ${UnSeT:=whatever}
identical to those in UnSeT=whatever In particular, with HOME=/foo
${UnSeT:=~:~} now assigns, and expands to, /foo:/foo rather than ~:~
just as VAR=~:~ assigns /foo:/foo to VAR. Note this is even after the
previous fix (ie: appending a '/' would not change the results here.)

It is hard to call this one a bug fix for certain (though I believe it is)
as many other shells also produce different results for the ${V:=...}
expansions than they do for V=... (though not all the same as we did).

POSIX is not clear about this, expanding ~ after : in VAR=whatever
assignments is clear, whether ${U:=whatever} assignments should be
treated the same way is not stated, one way or the other.

4. Change to make ':' terminate the user name in a ~ expansion in all cases,
not only in assignments. This makes sense, as ':' is one character that
cannot occur in user names, no matter how otherwise weird they become.
bash (incl in posix mode) ksh93 and bosh all act this way, whereas most
other shells (and POSIX) do not. Because this is clearly an extension
to POSIX, do this one only when not in posix mode (not set -o posix).
 1.120 21-Aug-2017  kre Add support for $'...' quoting (based upon C "..." strings, with \ expansions.)

Implementation largely obtained from FreeBSD, with adaptations to meet the
needs and style of this sh, some updates to agree with the current POSIX spec,
and a few other minor changes.

The POSIX spec for this ( http://austingroupbugs.net/view.php?id=249 )
[see note 2809 for the current proposed text] is yet to be approved,
so might change. It currently leaves several aspects as unspecified,
this implementation handles those as:

Where more than 2 hex digits follow \x this implementation processes the
first two as hex, the following characters are processed as if the \x
sequence was not present. The value obtained from a \nnn octal sequence
is truncated to the low 8 bits (if a bigger value is written, eg: \456.)
Invalid escape sequences are errors. Invalid \u (or \U) code points are
errors if known to be invalid, otherwise can generate a '?' character.
Where any escape sequence generates nul ('\0') that char, and the rest of
the $'...' string is discarded, but anything remaining in the word is
processed, ie: aaa$'bbb\0ccc'ddd produces the same as aaa'bbb'ddd.

Differences from FreeBSD:
FreeBSD allows only exactly 4 or 8 hex digits for \u and \U (as does C,
but the current sh proposal differs.) reeBSD also continues consuming
as many hex digits as exist after \x (permitted by the spec, but insane),
and reject \u0000 as invalid). Some of this is possibly because that
their implementation is based upon an earlier proposal, perhaps note 590 -
though that has been updated several times.

Differences from the current POSIX proposal:
We currently always generate UTF-8 for the \u & \U escapes. We should
generate the equivalent character from the current locale's character set
(and UTF8 only if that is what the current locale uses.)
If anyone would like to correct that, go ahead.

We (and FreeBSD) generate (X & 0x1F) for \cX escapes where we should generate
the appropriate control character (SOH for \cA for example) with whatever
value that has in the current character set. Apart from EBCDIC, which
we do not support, I've never seen a case where they differ, so ...
 1.119 30-Jun-2017  kre Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
 1.118 19-Jun-2017  kre Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
 1.117 18-Jun-2017  kre NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
 1.116 17-Jun-2017  kre Many internal memory management type fixes.

PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)

echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)

(Recently added) Problems with ~ expansion fixed (mem management related).

Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)

And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.

Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,

More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.

[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]

More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).

User visible changes:

Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in

cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END

(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)

With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)

POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).

Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
 1.115 07-Jun-2017  kre PR bin/52280

removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
 1.114 07-Jun-2017  kre Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
 1.113 07-Jun-2017  kre A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)

This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)

The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.

This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).

I would not call the results of this perfect yet, but it is close.
 1.112 05-Jun-2017  kre Another arithmetic expansion recordregion() fix, this time
calculate the lenght (used to calculate the end) based upon the
correct starting point.

Thanks to John Klos for finding and reporting this one.
 1.111 04-Jun-2017  kre PR bin/52272 - fix an off-by one that broke ~ expansions.
 1.110 03-Jun-2017  kre branches: 1.110.2;

DEBUG mode only change. Convert old trace style to new, and add some more.
NFC for any non-DEBUG shell.
 1.109 03-Jun-2017  kre NFC: Code style only. Rather than being perverse and adding the
negative of a negative number, just add a positive number instead...
(the previous version came about purely as an accident of the way the
relevant piece of code was added and debugged.... that's my story anyway!)
 1.108 03-Jun-2017  kre The correct usage of recordregion() is (begin, end) not (begin, length).

Fixing this fixes a regression introduced earlier today (UTC) where
arithmetic expressions would be split correctly when the arithmetic
started at the beginning of a word:
echo $(( expression ))
where "begin" is 0, and so (begin, length) is the same as (begin, begin+length)
(aka: (begin,end) - and yes, "end" means 1 after last to consider).
but did not work correctly when the usage was
echo XXX$( expression ))
(begin !+ 0) and would only split (some part of) the result of the expression.

This regression was also foung by the new t_fsplit:split_arith
test case added earlier to the ATF tests for sh.
 1.107 03-Jun-2017  kre Fixes to shell expand (that is, $ stuff) from FreeBSD (implemented
differently...)

In particular ${01} is now $1 not $0 (for ${0any-digits})

${4294967297} is most probably now ""
(unless you have a very large number of params)
it is no longer an alias for $1 (4294967297 & 0xFFFFFFFF) == 1

$(( expr $(( more )) stuff )) is no longer the same as
$(( expr (( more )) stuff )) which was sometimes OK, as in:
$(( 3 + $(( 2 - 1 )) * 3 ))
but not always as in:
$(( 1$((1 + 1))1 ))
which should be 121, but was an arith syntax error as
1((1 + 1))1
is meaningless.

Probably some more. This also sprinkles a little const, splits a big
func that had 2 (kind of unrelated) purposes into two simpler ones,
and avoids some (semi-dubious) modifications (and restores) in the input
string to insert \0's when they were needed.
 1.106 28-May-2017  kre Arrange for set -o and $- output to be sorted, rather than more
or less random (and becoming worse as more options are added.)
Since the data is known at compile time, sort at compile time,
rather than at run time.
 1.105 26-Apr-2017  christos Convert the pattern matcher from recursive to backtracking (from FreeBSD).
 1.104 20-Mar-2017  kre branches: 1.104.2;

PR bin/52090 - fix expansion of unquoted $*
 1.103 20-Mar-2017  kre Finish support for all required $(( )) (shell arithmetic) operators,
closing PR bin/50958

That meant adding the assignment operators ('=', and all of the +=, *= ...)
Currently, ++, --, and ',' are not implemented (none of those are required
by posix) but support for them (most likely ',' first) might be added later.

To do this, I removed the yacc/lex arithmetic parser completely, and
replaced it with a hand written recursive descent parser, that I obtained
from FreeBSD, who earlier had obtained it from dash (Herbert Xu).

While doing the import, I cleaned up the sources (changed some file names
to avoid requiring a clean build, or signifigant surgery to the obj
directories if "build.sh -u" was to be used - "build.sh -u" should work
fine as it is now) removed some dashisms, applied some KNF, ...
 1.102 12-Mar-2017  kre Fix for the "${unset-var#$(cmd1)}$(cmd2)" runs the wrong command bug.
... From FreeBSD
 1.101 31-Mar-2016  christos branches: 1.101.2; 1.101.4;
Implement the NETBSD_SHELL readonly unexportable unimportable
variable (with its current value set at 20160401) as discussed on
current-users and tech-userlevel. This also includes the necessary
support to implement it properly (particularly the unexportable
part) and adds options to the export command to support unexportable
variables. Also implement the "posix" option (no single letter
equivalent) which gets its default value from whether or not
POSIXLY_CORRECT is set in the environment when the shell starts
(but can be changed just like any other option using -o and +o on
the command line, or the set builtin command.) While there, fix
all uses of options so it is possible to have options that have a
short (one char) name, and no long name, just as it has been possible
to have options with a long name and no short name, though there
are currently none (with no long name). For now, the only use of
the posix option is to control whether ${ENV} is read at startup
by a non-interactive shell, so changing it with set is not usful
- that might change in the future. (from kre@)
 1.100 31-Mar-2016  christos After discussions with Jilles Tjoelker (FreeBSD shell) and following
a suggestion from him, the way the fix to PR bin/50993 was implemented
has changed a little. There are three steps involved in processing
a here document, reading it, parsing it, and then evaluating it
before applying it to the correct file descriptor for the command
to use. The third of those is not related to this problem, and
has not changed. The bug was caused by combining the first two
steps into one (and not doing it correctly - which would be hard
that way.) The fix is to split the first two stages into separate
events. The original fix moved the 2nd stage (parsing) to just
immediately before the 3rd stage (evaluation.) Jilles pointed out
some unwanted side effects from doing it that way, and suggested
moving the 2nd stage to immediately after the first. This commit
makes that change. The effect is to revert the changes to expand.c
and parser.h (which are no longer needed) and simplify slightly
the change to parser.c. (from kre@)
 1.99 27-Mar-2016  christos PR bin/50993 - this is a significant rewrite of the way that here
documents are processed. Now, when first detected, they are
simply read (the only change made to the text is to join lines
ended with a \ to the subsequent line, otherwise end marker detection
does not work correctly (for here docs with an unquoted endmarker
only of course.) This patch also moves the "internal subroutine"
for looking for the end marker out of readtoken1() (which had to
happen as readtoken1 is no longer reading the here doc when it is
needed) - that uses code mostly taken from FreeBSD's sh (thanks!)
and along the way results in some restrictions on what the end
marker can be being removed. We still do not allow all we should.
(from kre@)
 1.98 27-Mar-2016  christos General KNF and source code cleanups, avoid scattering the
magic string " \t\n" all over the place, slightly improved
syntax error messages, restructured some of the code for
clarity, don't allow IFS to be imported through the environment,
and remove the (never) conditionally compiled ATTY option.
Apart from one or two syntax error messages, and ignoring IFS
if present in the environment, this is intended to have no
user visible changes. (from kre@)
 1.97 16-Mar-2016  christos PR/19832, PR/35423: Fix handling 0x81 and 0x82 characters in expansions
($VAR etc) that are used to generate filenames for redirections. (from kre)
 1.96 08-Mar-2016  christos PR bin/50834o: fix expansions of (unquoted) ${unset_var-} and ""$@ (from kre)
 1.95 27-Feb-2016  christos remove useless casts
 1.94 22-Feb-2016  christos PR bin/43469 - correctly handle quoting of the pattern part of ${var%pat}
type expansions. (from kre)
 1.93 27-Aug-2015  christos PR/50179: Timo Buhrmester: sh(1) variable expansion bug
 1.92 06-Jun-2015  joerg Use an explicit body for a "until not EINTR" loop.
 1.91 20-Jan-2014  roy branches: 1.91.4;
Add wctype(3) support to Shell Patterns.
Obtained from FreeBSD.
 1.90 06-Oct-2013  ast Fix PR bin/48202 [non-critical/low]:
sh +nounset and `for X; do` iteration fails if parameter set empty
by applying and testing FreeBSD's patch of Oct 24 2009 for this; see
http://svnweb.freebsd.org/base/head/bin/sh/expand.c?r1=198453&r2=198454
Also created an ATF test in tests/bin/sh/t_expand.sh for this error and
corrected a space->tabs problem there as well.
 1.89 02-Oct-2013  christos add crude $LINENO support for FreeBSD
 1.88 22-Dec-2012  dsl Fix the expansion of "$(foo-$bar}" so that IFS isn't applied when
expanding $bar.
Noted by Greg Troxel on tech-userlevel running some 'git' tests.
Should fix PR bin/47361
 1.87 28-Mar-2012  christos branches: 1.87.2;
include <limits.h> for CHAR_MIN/CHAR_MAX
 1.86 31-Aug-2011  plunky branches: 1.86.2; 1.86.4;
NULL does not need a cast
 1.85 23-Aug-2011  christos PR/45269: Andreas Gustafsson: Instead of falling off the edge when eating trailing newlines
if the block has moved, arrange so that trailing newlines are never placed in the string
in the first place, by accumulating them and adding them only after we've encountered a
non-newline character. This allows also for more efficient appending since we know how much
we need beforehand. From FreeBSD.
 1.84 18-Jun-2011  christos PR/45069: Henning Petersen: Use prototypes from builtins.h .
 1.83 27-Nov-2009  tsutsui branches: 1.83.4;
Use %zu in printf format for size_t value.
 1.82 18-Jan-2009  lukem fix -Wsign-compare issues
 1.81 21-Dec-2008  christos use EXP_CASE only when trimming and unquoted.
 1.80 20-Dec-2008  christos PR/36954: Roland Illig: don't eat backlash escapes in variable patterns.
Makes ${line%%\**} work.
 1.79 16-Oct-2008  dholland branches: 1.79.2;
The field width passed for a %.*s printf format is supposed to be int, not
ptrdiff_t; on 64-bit platforms the latter will be too wide.
Adjust accordingly.
 1.78 25-Mar-2007  apb Make /bin/sh use intmax_t (instead of int) for arithmetic in $((...)).
 1.77 24-Nov-2006  wiz branches: 1.77.2;
s/apparant/apparent/, from Zafer.
 1.76 22-Aug-2006  dsl Set the 'not a parameter' flag when we skip initial whitespace.
Otherwise:
./sh -c 'x=" "; for a in $x; do echo a${a}a; done'
is processed as a single empty parameter (instead of no parameters).
Should fix the breakage I introdiced in rev 1.75 and PR/34256 and PR/34254
 1.75 21-Aug-2006  dsl Rework the code changes from revisions 1.69, 1.70 and 1.74 so that the code
behaves correctly.
As far as I can tell, "x$@y" now expands correctly, as does IFS=:; set -$IFS.
Fixes PR/33472 (again) and PR/33956
 1.74 20-May-2006  dsl branches: 1.74.2;
When expanding "$@" add a \0 byte after the last argument (as well as all
the earlier ones) so that a separator is added before it when it is empty.
This wasn't needed before a recent change that chenged the behaviour of
trailing whitespace IFS characters.
Fixed PR/33472
 1.73 18-Mar-2006  christos Coverity CID 620: Remove dead code.
 1.72 13-Dec-2005  dsl TOG require that 'set +o' output the options in a form suitable for
restoring them - make it so.
 1.71 01-Jun-2005  lukem appease gcc -Wuninitialized
 1.70 19-Mar-2005  dsl Check quoting before merging ifs regions.
sh -c 'set -- a; x="b c"; set -- "$@"$x'
now correctly gives $1=ab, $2=c
 1.69 19-Mar-2005  dsl Don't merge ifs regions with different quoting requirements
 1.68 14-Feb-2005  dsl branches: 1.68.2;
expbackq() was incorrectly backing up a temporary buffer when removing \n
from the end of output of commands inside $(...) substitutions.
If the program output is n*128+1 bytes long (ending in a \n) then the code
checks buf[-1] for another \n - looking an uninitialised stack.
On a big-endian system an integer of value 10 will satisfy this (unlikely
on little endian) and can happen depending on the last code path to use
a lot of stack!
This caused the problem with newvers.sh on sparc64 after ', 2005' was
added to the date list.
Fixed PR/28852
 1.67 13-Jul-2004  seb Add new builtin `wordexp' to support wordexp(3).

From FreeBSD.
Provided in PR lib/26123.
Approved by kleink@.
 1.66 26-Jun-2004  dsl Correctly apply IFS to unquoted text in ${x-text}.
Fixes PR/26058 and the 'for i in ${x-a b c}; do ...' and ${x-'a b' c}.
I can't find a PR for the latter problem.
Regression test goind in shortly.
 1.65 26-Jun-2004  dsl Remove a broken optimistion that crept in earlier today.
 1.64 26-Jun-2004  dsl Kill a diagnostic I accidentally left in.
 1.63 26-Jun-2004  dsl No functional changes (intended).
Rename some variables, add some comments, and restructure a little.
In preparation for fixing "set ${x-a b c}" and friends.
 1.62 09-Jun-2004  christos Undo previous fix, breaks:
#!/bin/sh
echo ${1+"$@"}
./sh.new foo.sh a b c
a b c b c
I'll revisit this when I have some more time.
 1.61 08-Jun-2004  christos "for i in ${x-a b c}; do echo $i; done" should print "a\nb\nc\n" not "a b c\n"
like other shells do. mark the expansion for ifs splitting. XXX: linux has a
very complicated fix for this. I wonder why.
 1.60 21-Dec-2003  jdolecek branches: 1.60.2; 1.60.4;
minor optimization in evalvar()
change sent in bin/23813 by VaX#n8
 1.59 22-Sep-2003  dsl Fix 'set "*" b; case "* b" in "$@") ...' and 'set "*"; case 1 in "${#1}") ...'
Which got broken by the previous fix.
 1.58 17-Sep-2003  christos PR/22640: Paul Jarc: sh mishandles positional parameters in case. Fixed
from FreeBSD PR 56147.
 1.57 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.56 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.55 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.54 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.53 15-May-2002  christos Implement unset variable error messages from Ben Harris.
 1.52 19-Sep-2001  itojun make sure we do not truncate arith expresssion > 10 digits.
freebsd bin/sh/expand.c revision 1.15. NetBSD PR 13943.
 1.51 30-Mar-2001  mycroft Globbing should match broken symlinks. stat()->lstat() to fix this.
 1.50 04-Feb-2001  christos remove redundant declarations and nexted externs.
 1.49 13-Mar-2000  soren branches: 1.49.4;
Fix doubled 'the' in comment.
 1.48 09-Jul-1999  christos compile with WARNS = 2
 1.47 30-Apr-1999  he Fix for bin/7502, from Tor Egge / FreeBSD. Their commit message:
> During variable expansion, the internal representation of the expression
> might be relocated. Handle this case.
 1.46 06-Apr-1999  he Correct a rather obvious typo (once Tor Egge pointed it out to me)
in the last change.
 1.45 26-Mar-1999  christos branches: 1.45.2;
PR/7231: Havard Eidnes: Shell quoting/trimming problem
 1.44 06-Feb-1999  christos Fix off-by-one error in the starting point to search for an arithmetic
expression.
 1.43 05-Feb-1999  christos PR/5577: Craig M. Chase: sh does not build with PARALLEL set.
- Added YHEADER in Makefile, removed arith.h and adjusted the sources.
 1.42 25-Jan-1999  mycroft Patches from Tor Egge (via Havard Eidnes) to fix various bugs in field
splitting and combining.
(Note: Some of this are not strictly bugs, but differences between traditional
Bourne shell and POSIX.)
 1.41 28-Jul-1998  mycroft Be more retentive about use of NOTREACHED and noreturn.
 1.40 26-Jul-1998  mycroft const poisoning.
 1.39 29-Mar-1998  mrg - change "extern" variables into int's
- remove extern'd variables not actually referenced
- don't use char as an array index
 1.38 23-Mar-1998  christos Fix the VSTRIMRIGHT* bugs... The problem was not the string length computation,
but lack of '\0' termination. Factor this segment out as common code too, while
I am there.
 1.37 10-Mar-1998  christos off by one error in ${%%}
 1.36 17-Feb-1998  christos Previous fix broke $var quoting. Try again differently :-)
 1.35 05-Feb-1998  christos Fix bug introduced by EXP_RECORD, where in case there was a variable expansion
involved in the `for' list, the list was recorded twice, leading to incorrect
argument expansion.
Introduce ifsfree() function that free's the IFS region list, GC'ing duplicated
code.
 1.34 31-Jan-1998  christos PR/4851: Benjamin Lorenz: In the "for <var> in <args>" construct <args>
was not marked as a region to be handled by ifsbreakup. Add EXP_RECORD
to indicate that the argument string needs to be recorded.
 1.33 01-Dec-1997  christos Unfortunately (as I expected) the previous change broke:

sleep
cmd='set `type "sleep"`; eval echo \$$#'
which=`eval $cmd`
echo $which

because the region did not get recorded at all, and it was interpreted as
a single word. I modified the code to keep track when the result of a
backquote expansion has been recorded to avoid recording it twice. I still
feel that this is not the right fix... More to come.
 1.32 30-Nov-1997  christos PR/4547: Joern Clausen: Incorrect argument expansion in backquote variable
assignment. E.g.
echo ${foo:=`echo 1 2 3 4`}
prints:
1 2 3 1 2 3 4
because when the arquments are not quoted, the backquote result
gets recorded twice. The fix right now is to comment out the
record_region() call in expbackq(). I hope that it does not break
anything else.
 1.31 07-Jul-1997  phil branches: 1.31.2;
Make code agree with man page in processing expansion of "$*".
Fix from PR 2647.
 1.30 04-Jul-1997  christos Fix compiler warnings.
 1.29 18-Mar-1997  christos PR/3352: From Hiroyuki Ito: ${#1} was not being expanded properly if there
was a need to allocated another stack block.
 1.28 03-Mar-1997  christos varisset fixes:
- treat $0 specially since it is not in shellparams
- check the number of parameters instead of walking
the parameters array to avoid checking against the
null terminated element.
 1.27 01-Mar-1997  christos PR/3269: Off by one in varisset(), caused variable substitution not to
count the last positional parameter as set.
 1.26 24-Jan-1997  christos - varisset(): In positional arguments, take into account VSNUL so that:
set -- ""; echo ${1:-wwww} works.
- when expanding arithmetic, discard previous ifs recorded regions, since we
are doing our own scanning. x=ab; echo $((${#x}+1)) now works.
- in ${var#word} fix two bugs:
* if there was an exact match, there was an off-by-one bug in the
comparison of the words. x=abcd; echo ${x#abcd}
* if there was no match, the stack region was not adjusted and the rest
of the word was getting written in the wrong place. x=123; echo ${x#abc}X
 1.25 11-Jan-1997  tls kill 'register'
 1.24 02-Nov-1996  christos A correction to the previous patch from Todd Miller.
 1.23 02-Nov-1996  christos echo ${1:-empty} did not do the substitution; from Todd Miller (OpenBSD)
 1.22 16-Oct-1996  christos PR/2808: Fix parsing of $n where n > 9 (from FreeBSD)
 1.21 02-Sep-1996  christos Don't infinite loop with:
unset var
echo ${var:=}
 1.20 12-Feb-1996  christos branches: 1.20.4;
Fix PR/2070: Ksh style variable modifiers were broken in /bin/sh, from
enami tsugutomo
 1.19 15-May-1995  christos Fixed new bug the previous fix introduced:

false
foo=bar
echo $?

would print 1
Also fixed the long standing bug:

false
echo `echo $?`

would print 0
The exitstatus needs rethinking and rewriting. The trial and error method
is not very efficient
 1.18 11-May-1995  christos Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.17 21-Mar-1995  cgd convert to new RCS id conventions.
 1.16 28-Feb-1995  christos Oops... typo in the IFS previous fix.
 1.15 28-Feb-1995  christos Changed so that backquote expansion eats all trailing newlines, not just
the last one.
Reported by guido@gvr.win.tue.nl (Guido van Rooij).
Repeat By:

echo "`cat file-with-many-newlines`"
 1.14 28-Feb-1995  christos Changed IFS string-splitting so that it breaks spaces even when IFS does not
begin with a space, but contains one. Fixes PR bin/809.

#!/bin/sh
list="a b c "
echo "With ordinary IFS"
for i in $list;do
echo $i
done
IFS=":${IFS}"
echo "With changed IFS"
for i in $list;do
echo $i
done

Note that before the fix ":${IFS}" behaved differently than "${IFS}:".
 1.13 23-Jan-1995  christos I added the documented in the manual but not implemented variable expansions:

${#WORD}
${WORD%PAT}
${WORD%%PAT}
${WORD#PAT}
${WORD##PAT}
 1.12 04-Dec-1994  cgd from James Jegers <jimj@miller.cs.uwm.edu>: quiet -Wall, and squelch
some of the worst style errors.
 1.11 29-Aug-1994  mycroft Fix problem with character classes matching a terminating NUL, from Henry
Spencer.
 1.10 11-Jun-1994  mycroft branches: 1.10.2;
Add RCS ids.
 1.9 12-May-1994  jtc Include appropriate header files to bring function prototypes into scope.
 1.8 11-May-1994  jtc sync with 4.4lite
 1.7 22-Oct-1993  mycroft Last patch was wrong; just save argbackq around the argstr() call.
 1.6 22-Oct-1993  mycroft evalvar(): If subtype is VSASSIGN (or VSQUESTION), argstr() already rolled
forward the backquote queue. If VSQUESTION it doesn't matter because we
already exited with an error.
 1.5 01-Aug-1993  mycroft Add RCS identifiers.
 1.4 02-May-1993  sef Jim "wilson@moria.cygnus.com" Wilson's patches to make C News (and other
things) work.
 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.10.2.1 29-Aug-1994  mycroft update from trunk
 1.20.4.3 04-Mar-1997  mycroft Pull up latest sh(1). Fixes yet more bugs.
 1.20.4.2 02-Mar-1997  mycroft Pull up off-by-one fix.
 1.20.4.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.31.2.1 08-May-1998  mycroft Sync with trunk, per request of christos.
 1.45.2.2 14-Jan-2002  he Pull up revision 1.52 (requested by itojun):
Do not truncate expr > 10 digits. Fixes PR#13943.
 1.45.2.1 07-Apr-1999  he Pull up 1.45-1.46. Corrects what's obviously a typo.
 1.49.4.1 08-Oct-2001  he Pull up revision 1.52 (requested by itojun):
Do not truncate expr > 10 digits. Fixes PR#13943.
 1.60.4.1 11-May-2005  riz Pull up revision 1.68 (requested by martin in ticket #1418):
expbackq() was incorrectly backing up a temporary buffer when removing \n
from the end of output of commands inside $(...) substitutions.
If the program output is n*128+1 bytes long (ending in a \n) then the code
checks buf[-1] for another \n - looking an uninitialised stack.
On a big-endian system an integer of value 10 will satisfy this (unlikely
on little endian) and can happen depending on the last code path to use
a lot of stack!
This caused the problem with newvers.sh on sparc64 after ', 2005' was
added to the date list.
Fixed PR/28852
 1.60.2.1 28-Oct-2005  riz Pull up following revision(s) (requested by martin in ticket #1418):
bin/sh/expand.c: revision 1.68
expbackq() was incorrectly backing up a temporary buffer when removing \n
from the end of output of commands inside $(...) substitutions.
If the program output is n*128+1 bytes long (ending in a \n) then the code
checks buf[-1] for another \n - looking an uninitialised stack.
On a big-endian system an integer of value 10 will satisfy this (unlikely
on little endian) and can happen depending on the last code path to use
a lot of stack!
This caused the problem with newvers.sh on sparc64 after ', 2005' was
added to the date list.
Fixed PR/28852
 1.68.2.5 02-Sep-2006  ghen Pull up following revision(s) (requested by dsl in ticket #1488):
bin/sh/expand.c: revision 1.76
Set the 'not a parameter' flag when we skip initial whitespace.
Otherwise:
./sh -c 'x=" "; for a in $x; do echo a${a}a; done'
is processed as a single empty parameter (instead of no parameters).
Should fix the breakage I introdiced in rev 1.75 and PR/34256 and PR/34254
 1.68.2.4 02-Sep-2006  ghen Pull up following revision(s) (requested by dsl in ticket #1487):
bin/sh/expand.c: revision 1.75
Rework the code changes from revisions 1.69, 1.70 and 1.74 so that the code
behaves correctly.
As far as I can tell, "x$@y" now expands correctly, as does IFS=:; set -$IFS.
Fixes PR/33472 (again) and PR/33956
 1.68.2.3 12-Jun-2006  tron Pull up following revision(s) (requested by dsl in ticket #1336):
bin/sh/expand.c: revision 1.74
When expanding "$@" add a \0 byte after the last argument (as well as all
the earlier ones) so that a separator is added before it when it is empty.
This wasn't needed before a recent change that chenged the behaviour of
trailing whitespace IFS characters.
Fixed PR/33472
 1.68.2.2 07-Apr-2005  tron branches: 1.68.2.2.2;
Pull up revision 1.70 (requested by dsl in ticket #119):
Check quoting before merging ifs regions.
sh -c 'set -- a; x="b c"; set -- "$@"$x'
now correctly gives $1=ab, $2=c
 1.68.2.1 07-Apr-2005  tron Pull up revision 1.69 (requested by dsl in ticket #118):
Don't merge ifs regions with different quoting requirements
 1.68.2.2.2.1 12-Jun-2006  tron Pull up following revision(s) (requested by dsl in ticket #1336):
bin/sh/expand.c: revision 1.74
When expanding "$@" add a \0 byte after the last argument (as well as all
the earlier ones) so that a separator is added before it when it is empty.
This wasn't needed before a recent change that chenged the behaviour of
trailing whitespace IFS characters.
Fixed PR/33472
 1.74.2.2 01-Sep-2006  tron Pull up following revision(s) (requested by dsl in ticket #84):
bin/sh/expand.c: revision 1.76
Set the 'not a parameter' flag when we skip initial whitespace.
Otherwise:
./sh -c 'x=" "; for a in $x; do echo a${a}a; done'
is processed as a single empty parameter (instead of no parameters).
Should fix the breakage I introdiced in rev 1.75 and PR/34256 and PR/34254
 1.74.2.1 01-Sep-2006  tron Pull up following revision(s) (requested by dsl in ticket #83):
bin/sh/expand.c: revision 1.75
Rework the code changes from revisions 1.69, 1.70 and 1.74 so that the code
behaves correctly.
As far as I can tell, "x$@y" now expands correctly, as does IFS=:; set -$IFS.
Fixes PR/33472 (again) and PR/33956
 1.77.2.1 16-Apr-2007  bouyer Pull up following revision(s) (requested by apb in ticket #570):
bin/sh/expand.c: revision 1.78
bin/sh/arith.y: revision 1.18
bin/sh/expand.h: revision 1.17
regress/bin/sh/expand.sh: revision 1.4
bin/sh/sh.1: revision 1.86
bin/sh/arith_lex.l: revision 1.14
Make /bin/sh use intmax_t (instead of int) for arithmetic in $((...)).
 1.79.2.2 09-Jun-2013  msaitoh Pull up following revision(s) (requested by gdt in ticket #1851):
bin/sh/expand.c: revision 1.88
bin/sh/expand.h: revision 1.19
Fix the expansion of "$(foo-$bar}" so that IFS isn't applied when
expanding $bar.
Noted by Greg Troxel on tech-userlevel running some 'git' tests.
Should fix PR bin/47361
 1.79.2.1 02-Nov-2011  riz Pull up following revision(s) (requested by christos in ticket #1665):
bin/sh/expand.c: revision 1.85
PR/45269: Andreas Gustafsson: Instead of falling off the edge when eating
trailing newlines
if the block has moved, arrange so that trailing newlines are never placed in
the string
in the first place, by accumulating them and adding them only after we've
encountered a
non-newline character. This allows also for more efficient appending since we
know how much
we need beforehand. From FreeBSD.
 1.83.4.1 23-Jun-2011  cherry Catchup with rmind-uvmplock merge.
 1.86.4.1 02-Feb-2013  sborrill Pull up the following revisions(s) (requested by dsl in ticket #773):
bin/sh/expand.c: revision 1.88
bin/sh/expand.h: revision 1.19

Fix the expansion of "$(foo-$bar}" so that IFS isn't applied when
expanding $bar. Should fix PR bin/47361
 1.86.2.3 22-May-2014  yamt sync with head.

for a reference, the tree before this commit was tagged
as yamt-pagecache-tag8.

this commit was splitted into small chunks to avoid
a limitation of cvs. ("Protocol error: too many arguments")
 1.86.2.2 23-Jan-2013  yamt sync with head
 1.86.2.1 17-Apr-2012  yamt sync with head
 1.87.2.2 19-Aug-2014  tls Rebase to HEAD as of a few days ago.
 1.87.2.1 25-Feb-2013  tls resync with head
 1.91.4.1 19-Apr-2017  snj Pull up following revision(s) (requested by kre in ticket #1388):
bin/sh/expand.c: revision 1.102
Fix for the "${unset-var#$(cmd1)}$(cmd2)" runs the wrong command bug.
... From FreeBSD
 1.101.4.1 21-Apr-2017  bouyer Sync with HEAD
 1.101.2.2 26-Apr-2017  pgoyette Sync with HEAD
 1.101.2.1 20-Mar-2017  pgoyette Sync with HEAD
 1.104.2.1 02-May-2017  pgoyette Sync with HEAD - tag prg-localcount2-base1
 1.110.2.5 10-Sep-2018  martin Pull up following revision(s) via patch (requested by kre in ticket #1015):

bin/sh/expand.c: revision 1.124
bin/sh/expand.c: revision 1.127
bin/sh/parser.c: revision 1.148
bin/sh/parser.c: revision 1.149
bin/sh/syntax.c: revision 1.6
bin/sh/syntax.h: revision 1.9 (partial)

First pass at fixing some of the more arcane pattern matching
possibilities that we do not currently handle all that well.

This mostly means (for now) making sure that quoted pattern
magic characters (as well as quoted sh syntax magic chars)
are properly marked, so they remain known as being quoted,
and do not turn into pattern magic. Also, make sure that an
unquoted \ in a pattern always quotes whatever comes next
(which, unlike in regular expressions, includes inside []
matches),

-

Part 2 of pattern matching (glob etc) fixes.
Attempt to correctly deal with \ (both when it is a literal,
in appropriate cases, and when it appears as CTLESC when it was
detected as a quoting character during parsing).

In a pattern, in sh, no quoted character can ever be anything other
than a literal character. This is quite different than regular
expressions, and even different than other uses of glob matching,
where shell quoting is not an issue.

In something like
ls ?\*.c
the ? is a meta-character, the * is a literal (it was quoted). This
is nothing new, sh has handled that properly for ever.

But the same happens with
VAR='?\*.c'
and
ls $VAR
which has not always been handled correctly. Of course, in
ls "$VAR"
nothing in VAR is a meta-character (the entire expansion is quoted)
so even the '\' must match literally (or more accurately, no matching
happens - VAR simply contains an "unusual" filename). But if it had
been
ls *"$VAR"
then we would be looking for filenames that end with the literal 5
characters that make up $VAR.

The same kinds of things are requires of matching patterns in case
statements, and sub-strings with the % and # operators in variable
expansions.

While here, the final remnant of the ancient !! pattern matching
hack has been removed (the code that actually implemented it was
long gone, but one small piece remained, not doing any real harm,
but potentially wasting time - if someone gave a pattern which would
once have invoked that hack.)
 1.110.2.4 13-Jul-2018  martin Pull up following revision(s) (requested by kre in ticket #907):

bin/sh/expand.c: revision 1.122

When matching a char class ([[:name:]]) in a pattern (for filename
expansion, case patterrns, etc) do not force '[' to be a member of
every class.

Before this fix, try:

case [ in [[:alpha:]]) echo Huh\?;; esac

XXX pullup-8 (Perhaps -7 as well, though that shell version has
much more relevant bugs than this one.) This bug is not in -6 as
that has no charclass support.
 1.110.2.3 25-Oct-2017  snj Pull up following revision(s) (requested by kre in ticket #310):
bin/sh/expand.c: revision 1.121
bin/sh/sh.1: revision 1.167 via patch
Three fixes and a change to ~ expansions
1. A serious bug introduced 3 1/2 months ago (approx) (rev 1.116) which
broke all but the simple cases of ~ expansions is fixed (amazingly,
given the magnitude of this problem, no-one noticed!)
2. An ancient bug (probably from when ~ expansion was first addedin 1994, and
certainly is in NetBSD-6 vintage shells) where ${UnSeT:-~} (and similar)
does not expand the ~ is fixed (note that ${UnSeT:-~/} does expand,
this should give a clue to the cause of the problem.
3. A fix/change to make the effects of ~ expansions on ${UnSeT:=whatever}
identical to those in UnSeT=whatever In particular, with HOME=/foo
${UnSeT:=~:~} now assigns, and expands to, /foo:/foo rather than ~:~
just as VAR=~:~ assigns /foo:/foo to VAR. Note this is even after the
previous fix (ie: appending a '/' would not change the results here.)
It is hard to call this one a bug fix for certain (though I believe it is)
as many other shells also produce different results for the ${V:=...}
expansions than they do for V=... (though not all the same as we did).
POSIX is not clear about this, expanding ~ after : in VAR=whatever
assignments is clear, whether ${U:=whatever} assignments should be
treated the same way is not stated, one way or the other.
4. Change to make ':' terminate the user name in a ~ expansion in all cases,
not only in assignments. This makes sense, as ':' is one character that
cannot occur in user names, no matter how otherwise weird they become.
bash (incl in posix mode) ksh93 and bosh all act this way, whereas most
other shells (and POSIX) do not. Because this is clearly an extension
to POSIX, do this one only when not in posix mode (not set -o posix).
 1.110.2.2 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.110.2.1 05-Jun-2017  snj Pull up following revision(s) (requested by kre in ticket #7):
bin/sh/expand.c: revisions 1.111, 1.112
PR bin/52272 - fix an off-by one that broke ~ expansions.
--
Another arithmetic expansion recordregion() fix, this time
calculate the lenght (used to calculate the end) based upon the
correct starting point.
Thanks to John Klos for finding and reporting this one.
 1.121.2.4 26-Dec-2018  pgoyette Sync with HEAD, resolve a few conflicts
 1.121.2.3 26-Nov-2018  pgoyette Sync with HEAD, resolve a couple of conflicts
 1.121.2.2 28-Jul-2018  pgoyette Sync with HEAD
 1.121.2.1 25-Jun-2018  pgoyette Sync with HEAD
 1.123.2.5 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.123.2.4 21-Apr-2020  martin Sync with HEAD
 1.123.2.3 13-Apr-2020  martin Mostly merge changes from HEAD upto 20200411
 1.123.2.2 08-Apr-2020  martin Merge changes from current as of 20200406
 1.123.2.1 10-Jun-2019  christos Sync with HEAD
 1.132.2.3 14-Jan-2024  martin Pull up following revision(s) (requested by kre in ticket #1787):

bin/sh/eval.c: revision 1.191
bin/sh/expand.c: revision 1.144

PR bin/57773

Fix a bug reported by Jarle Fredrik Greipsland in PR bin/57773,
where a substring expansion where the substring to be removed from
a variable expansion is itself a var expansion where the value
contains one (or more) of sh's CTLxxx chars - the pattern had
CTLESC inserted, the string to be matched against did not. Fail.

We fix that by always inserting CTLESC in var assign expansions.
See the PR for all the gory details.

Thanks for the PR.

PR bin/57773

Fix another bug reported by Jarle Fredrik Greipsland and added
to PR bin/57773, which relates to calculating the length of a
positional parameter which contains CTL chars -- yes, this one
really is that specific, though it would also affect the special
param $0 if it were to contain CTL chars, and its length was
requested - that is fixed with the same change. And note: $0
is not affected because it looks like a positional param (it
isn't, ${00} would be, but is always unset, ${0} isn't) all
special parame would be affected the same way, but the only one
that can ever contain a CTL char is $0 I believe. ($@ and $*
were affected, but just because they're expanding the positional
params ... ${#@} and ${#*} are both technically unspecified
expansions - and different shells produce different results.

See the PR for the details of this one (and the previous).

Thanks for the PR.
 1.132.2.2 07-Jun-2020  martin Pull up following revision(s) (requested by kre in ticket #940):

bin/sh/expand.h: revision 1.25
bin/sh/expand.c: revision 1.134
bin/sh/expand.c: revision 1.135
bin/sh/expand.c: revision 1.136
bin/sh/expand.c: revision 1.137

Remove a (completely harmless) duplicate assignment introduced in a
code merge from FreeBSD in 2017. NFC.

Pointed out by Roland Illig.

prevent sign extension from making expression always false.
remove masking and cast (requested by kre@)

When expanding a here-doc (NXHERE - the type with an unquoted end delim)
the output will not be further processed (at all) so there is no need
to escape magic chars in the output, and doing so leaves stray CTLESC
chars in the here doc text. Not good. So don't do that...

To save a strlen() of the result, to determine the size of the here doc,
make rmescapes() return the length of the resulting string (this isn't
needed for other uses, so didn't happen previously).

Reported on current-users@ (2020-02-06) by Jun Ebihara

XXX pullup -9
 1.132.2.1 24-Nov-2019  martin Pull up following revision(s) (requested by kre in ticket #467):

bin/sh/expand.c: revision 1.133

Open code the validity test & copy of the character class name in
a bracket expression in a pattern (ie: [[:THISNAME:]]). Previously
the code used strspn() to look for invalid chars in the name, and
then memcpy(), now we do the test and copy a character at a time.

This might, or might not, be faster, but it now correctly handles
\ quoted characters in the name (' and " quoting were already
dealt with, \ was too in an earlier version, but when the \ handling
changes were made, this piece of code broke).

Not exactly a vital bug fix (who writes [[:\alpha:]] or similar?)
but it should work correctly regardless of how obscure the usage is.

Problem noted by Harald van Dijk

XXX pullup -9
 1.141.2.1 14-Jan-2024  martin Pull up following revision(s) (requested by kre in ticket #535):

bin/sh/eval.c: revision 1.191
bin/sh/expand.c: revision 1.144

PR bin/57773

Fix a bug reported by Jarle Fredrik Greipsland in PR bin/57773,
where a substring expansion where the substring to be removed from
a variable expansion is itself a var expansion where the value
contains one (or more) of sh's CTLxxx chars - the pattern had
CTLESC inserted, the string to be matched against did not. Fail.

We fix that by always inserting CTLESC in var assign expansions.
See the PR for all the gory details.

Thanks for the PR.

PR bin/57773

Fix another bug reported by Jarle Fredrik Greipsland and added
to PR bin/57773, which relates to calculating the length of a
positional parameter which contains CTL chars -- yes, this one
really is that specific, though it would also affect the special
param $0 if it were to contain CTL chars, and its length was
requested - that is fixed with the same change. And note: $0
is not affected because it looks like a positional param (it
isn't, ${00} would be, but is always unset, ${0} isn't) all
special parame would be affected the same way, but the only one
that can ever contain a CTL char is $0 I believe. ($@ and $*
were affected, but just because they're expanding the positional
params ... ${#@} and ${#*} are both technically unspecified
expansions - and different shells produce different results.

See the PR for the details of this one (and the previous).

Thanks for the PR.
 1.144.2.1 02-Aug-2025  perseant Sync with HEAD
 1.26 22-Nov-2021  kre PR bin/53550

Here we go again... One more time to redo how here docs are
processed (it has been a few years since the last time!)

This is actually a relatively minor change, mostly to timimg
(to just when things happen). Now here docs are expanded at the
same time the "filename" word in a redirect is expanded, rather than
later when the heredoc was being sent to its process. This actually
makes things more consistent - but does break one of the ATF tests
which was testing that we were (effectively) internally inconsistent
in this area.

Not all shells agree on the context in which redirection expansions
should happen, some make any side effects visible to the parent shell
(the majority do) others do the redirection expansions in a subshell
so any side effcts are lost. We used to have a foot in each camp,
with the majority for everything but here docs, and the minority for
here docs. Now we're all the way with LBJ ... (or something like that).
 1.25 13-Feb-2020  kre When expanding a here-doc (NXHERE - the type with an unquoted end delim)
the output will not be further processed (at all) so there is no need
to escape magic chars in the output, and doing so leaves stray CTLESC
chars in the here doc text. Not good. So don't do that...

To save a strlen() of the result, to determine the size of the here doc,
make rmescapes() return the length of the resulting string (this isn't
needed for other uses, so didn't happen previously).

Reported on current-users@ (2020-02-06) by Jun Ebihara

XXX pullup -9
 1.24 18-Nov-2018  kre branches: 1.24.2;
Rationalise (slightly) the way that expansions are processed
to hide meta-characters in the result when the expansion was
in (double) quotes, and so should not be further processed.

Most of this has been OK for a long while, but \ needs hiding
as well, which complicates things, as \ cannot simply be hidden
in the syntax tables as one of the group of random special characters.

This was fixed earlier for simple variable expansions, but
every variety has its own code path ($var uses different code
than $n which is different than $(...), which is different
again from ~ expansions, and also from what $'...' produces).

This could be fixed by moving them all to a common code path,
but that's harder than it seems. The form in which the data
is made available differs, so one common routine would need
a whole bunch of different "get the next char or indicate end"
methods - probably via passing in an accessor function.
That's all a lot of churn, and would probably slow the shell.

Instead, just make macros for doing the standard tests, and
use those instead of open coding (differently) each time.
This way some of the code paths don't end up forgetting to
handle '\' (which is different than all the others).

This removes one optimisation ... when no escaping is needed
(like just $var (unquoted) where magic chars (think '*') in
the value are intended to remain magic), the code avoided doing
two tests for each char ("do we need escapes" and "is this char
one that needs escaping") by choosing two different syntax
tables (choice made outside the loop) - one of which never
returns the magic "needs escaping" result, and the other does
when appropriate, and then just avoiding the "do we need escapes"
test for each character processed. Then when '\' was fixed,
there needed to be another test for it, as it cannot (for other
reasons) be the same as all the others for which "this char
need escaping" is true. So that added a 2nd test for each char...
Not all the code paths were updated. Hence the bugs...

nb: this is all rarely seen in the wild, so it is no big
surprised that no-one ever noticed.

Now the "use two different syntax tables" is gone (the two
returned the same for '\' which is why '\' needed special
processing) - and in order to avoid two tests for each
char (plus the \ test) we duplicate the loops, one of which
tests each char to see if it needs an escape, the 2nd just
copies them. This should be faster in the "no escapes"
code path (though that is not the point) and perhaps also
in the "escapes needed" path (no indirect reference to
the syntax table - though that would probably be in a
register) but makes the code slightly bigger. For /bin/sh
the text segment (on amd64) has grown by 48 bytes. But
it still uses the same number of 512 byte pages (and hence
also any bigger page size). The resulting file size
(/bin/sh) is identical before and after. So is /rescue/sh
(or /rescue/anything-else).
 1.23 07-Jun-2017  kre branches: 1.23.4; 1.23.6;
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)

This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)

The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.

This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).

I would not call the results of this perfect yet, but it is close.
 1.22 03-Jun-2017  kre branches: 1.22.2;
Fixes to shell expand (that is, $ stuff) from FreeBSD (implemented
differently...)

In particular ${01} is now $1 not $0 (for ${0any-digits})

${4294967297} is most probably now ""
(unless you have a very large number of params)
it is no longer an alias for $1 (4294967297 & 0xFFFFFFFF) == 1

$(( expr $(( more )) stuff )) is no longer the same as
$(( expr (( more )) stuff )) which was sometimes OK, as in:
$(( 3 + $(( 2 - 1 )) * 3 ))
but not always as in:
$(( 1$((1 + 1))1 ))
which should be 121, but was an arith syntax error as
1((1 + 1))1
is meaningless.

Probably some more. This also sprinkles a little const, splits a big
func that had 2 (kind of unrelated) purposes into two simpler ones,
and avoids some (semi-dubious) modifications (and restores) in the input
string to insert \0's when they were needed.
 1.21 26-Apr-2017  christos Convert the pattern matcher from recursive to backtracking (from FreeBSD).
 1.20 20-Mar-2017  kre branches: 1.20.2;


Finish support for all required $(( )) (shell arithmetic) operators,
closing PR bin/50958

That meant adding the assignment operators ('=', and all of the +=, *= ...)
Currently, ++, --, and ',' are not implemented (none of those are required
by posix) but support for them (most likely ',' first) might be added later.

To do this, I removed the yacc/lex arithmetic parser completely, and
replaced it with a hand written recursive descent parser, that I obtained
from FreeBSD, who earlier had obtained it from dash (Herbert Xu).

While doing the import, I cleaned up the sources (changed some file names
to avoid requiring a clean build, or signifigant surgery to the obj
directories if "build.sh -u" was to be used - "build.sh -u" should work
fine as it is now) removed some dashisms, applied some KNF, ...
 1.19 22-Dec-2012  dsl branches: 1.19.14; 1.19.18;
Fix the expansion of "$(foo-$bar}" so that IFS isn't applied when
expanding $bar.
Noted by Greg Troxel on tech-userlevel running some 'git' tests.
Should fix PR bin/47361
 1.18 18-Jun-2011  christos branches: 1.18.2; 1.18.4; 1.18.8;
PR/45069: Henning Petersen: Use prototypes from builtins.h .
 1.17 25-Mar-2007  apb branches: 1.17.18; 1.17.32;
Make /bin/sh use intmax_t (instead of int) for arithmetic in $((...)).
 1.16 13-Jul-2004  seb branches: 1.16.10;
Add new builtin `wordexp' to support wordexp(3).

From FreeBSD.
Provided in PR lib/26123.
Approved by kleink@.
 1.15 26-Jun-2004  dsl No functional changes (intended).
Rename some variables, add some comments, and restructure a little.
In preparation for fixing "set ${x-a b c}" and friends.
 1.14 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.13 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.12 09-Jul-1999  christos compile with WARNS = 2
 1.11 26-Mar-1999  christos PR/7231: Havard Eidnes: Shell quoting/trimming problem
 1.10 05-Feb-1999  christos PR/5577: Craig M. Chase: sh does not build with PARALLEL set.
- Added YHEADER in Makefile, removed arith.h and adjusted the sources.
 1.9 31-Jan-1998  christos PR/4851: Benjamin Lorenz: In the "for <var> in <args>" construct <args>
was not marked as a region to be handled by ifsbreakup. Add EXP_RECORD
to indicate that the argument string needs to be recorded.
 1.8 11-May-1995  christos branches: 1.8.4;
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.8.4.1 08-May-1998  mycroft Sync with trunk, per request of christos.
 1.16.10.1 16-Apr-2007  bouyer Pull up following revision(s) (requested by apb in ticket #570):
bin/sh/expand.c: revision 1.78
bin/sh/arith.y: revision 1.18
bin/sh/expand.h: revision 1.17
regress/bin/sh/expand.sh: revision 1.4
bin/sh/sh.1: revision 1.86
bin/sh/arith_lex.l: revision 1.14
Make /bin/sh use intmax_t (instead of int) for arithmetic in $((...)).
 1.17.32.1 23-Jun-2011  cherry Catchup with rmind-uvmplock merge.
 1.17.18.1 09-Jun-2013  msaitoh Pull up following revision(s) (requested by gdt in ticket #1851):
bin/sh/expand.c: revision 1.88
bin/sh/expand.h: revision 1.19
Fix the expansion of "$(foo-$bar}" so that IFS isn't applied when
expanding $bar.
Noted by Greg Troxel on tech-userlevel running some 'git' tests.
Should fix PR bin/47361
 1.18.8.1 25-Feb-2013  tls resync with head
 1.18.4.1 02-Feb-2013  sborrill Pull up the following revisions(s) (requested by dsl in ticket #773):
bin/sh/expand.c: revision 1.88
bin/sh/expand.h: revision 1.19

Fix the expansion of "$(foo-$bar}" so that IFS isn't applied when
expanding $bar. Should fix PR bin/47361
 1.18.2.1 23-Jan-2013  yamt sync with head
 1.19.18.1 21-Apr-2017  bouyer Sync with HEAD
 1.19.14.1 26-Apr-2017  pgoyette Sync with HEAD
 1.20.2.1 02-May-2017  pgoyette Sync with HEAD - tag prg-localcount2-base1
 1.22.2.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.23.6.4 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.23.6.3 21-Apr-2020  martin Sync with HEAD
 1.23.6.2 08-Apr-2020  martin Merge changes from current as of 20200406
 1.23.6.1 10-Jun-2019  christos Sync with HEAD
 1.23.4.1 26-Nov-2018  pgoyette Sync with HEAD, resolve a couple of conflicts
 1.24.2.1 07-Jun-2020  martin Pull up following revision(s) (requested by kre in ticket #940):

bin/sh/expand.h: revision 1.25
bin/sh/expand.c: revision 1.134
bin/sh/expand.c: revision 1.135
bin/sh/expand.c: revision 1.136
bin/sh/expand.c: revision 1.137

Remove a (completely harmless) duplicate assignment introduced in a
code merge from FreeBSD in 2017. NFC.

Pointed out by Roland Illig.

prevent sign extension from making expression always false.
remove masking and cast (requested by kre@)

When expanding a here-doc (NXHERE - the type with an unquoted end delim)
the output will not be further processed (at all) so there is no need
to escape magic chars in the output, and doing so leaves stray CTLESC
chars in the here doc text. Not good. So don't do that...

To save a strlen() of the result, to determine the size of the here doc,
make rmescapes() return the length of the resulting string (this isn't
needed for other uses, so didn't happen previously).

Reported on current-users@ (2020-02-06) by Jun Ebihara

XXX pullup -9
 1.4 11-May-1995  christos Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.3 21-Mar-1995  cgd convert to new RCS id conventions.
 1.2 06-Dec-1994  cgd adjust; from jimj.
 1.1 05-Dec-1994  cgd clean up further. more patches from Jim Jegers
 1.73 03-Aug-2024  kre Revert a part of a change made on 1999-07-09 (in rev 1.21).

That change ("compile with WARNS = 2") added "const" qualifiers
in many places.

One of them, in this file, became a const char *, which needed to be
passed to sh function defined as taking a char * arg. (evalstring()).

To do that safely (in 1999), a copy of the original string was made,
and that copy was passed to evalstring() instead of the original.
The copy is simply char *, and if something altered it, no-one would
care. The original string (in some cases) must not be altered.

That was the cause of the bug fixed (a different way) in the
previous commit to this file. To copy the string, space needed
to be allocated, and when that was done, if the string was just
(the right length, its terminating \0 (which previously was stored
outside the string itself) and if the current shell stack memory block
was big enough that a new one wasn't needed, the \0 would be trampled
(then the strcpy() would become overwriting, and havoc result).

Now evalstring() has been updated to take a const char *, and
the string passed to it truly is treated as const data (nothing
ever attempts to alter it) so making a copy of the string isn't
needed, and we can go back to the way the code used to be, pre-1999.

That is, modulo other unrelated changes (or one change actually)
that has been made since, which has nothing to do with the issues here.

The change made in the previous revision could be undone, but won't
be, as it is logically the right thing to do.

NFCI.
 1.72 03-Aug-2024  kre Fix a very old core dump causing bug found by RVP in the history code.
That is, truly very old - it is in rev 1.1 from 1994 (and so is probably
even older than that).

If one uses the (very rarely used)
fc -s string=otherstring
builtin command, to rerun the previous command (or with additional args,
any other command) after replacing the first instance of "string" in that
command with "otherstring" and the resulting command line just happens to
be a length that is a multiple of the shell's memory allocation alignment
constant, then the \0 string terminator that is appended to the result
to mark its end stood a very small chance (in 1994 probably no chance at all,
but made considerably more likely in 1999 when other changes were made -
certain in the right circumstances) of being destroyed by other sh memory
allocation before the string was finished being used.

The fix (also suggested by RVP) is to make that \0 an actual part of
the allocated result string, rather than an extra byte tacked on the
end of it -- in itself, doing the latter is common in sh, and not at all
improper, sometimes even required, but only when the string as a string
will be consumed before more (shell) stack memory allocation is performed.
It 1994 it would have been. Since 1999, it isn't.

The 1999 change is going to be undone in a later commit, but this one
is simpler to pull up to earlier releases, and probably the right thing
to do anyway, even if not strictly essential.

XXX pullup -9, -10 (and everything back to 1.5 - it looks as if 1.4 is OK).
 1.71 13-Jul-2024  kre Implement the HISTFILE and HISTAPPEND variables.

See the (newly updated) sh(1) for details.
Also add the -z option to fc (clear history).

None of this exists in SMALL shells.
 1.70 12-Jul-2024  kre Improve safety in var imports from the environment.

Add a new var flag VUNSAFE - set on all vars imported from the environment.

Add setvareqsafe() (which is to setvareq() as setvarsafe() is to setvar())
and use that instead of setvareq() when processing the environment, so
errors don't cause the shell to abort. Use VUNSAFE in that call.

Add flags arguments to all var callback functions which are used when setting
variables, and pass the flags given to the setvar*() functions to those
functions, so they can act differently in different situations (if desired).
Most of them just ignore the flags.

When unsetting a variable, call setvar() to clear things (and call the
callback function) both when the variable had a value which needs to be freed,
and when unsetting a variable which wasn't unset previously, so the VUNSET
flag can be seen by that callback func.

When setting HISTSIZE, use the flags passed to determine whether to ignore
bad values (if VUNSAFE) or treat them as an error. This replaces the
earlier temporary hack to always ignore bad data there (histedit.c 1.68).

Miscellaneous associated minor changes.

These changes should largely be invisible in normal use.
 1.69 05-Jul-2024  kre Don't emit a user causable "internal error" message.

Non-numeric args to "fc" simply fail to find the string
in an empty history buffer, as they might in a non-empty
history, and generate a reasonable error message.

But normally, as numeric args to the "fc" utility are trimmed
to the bounds of the contents of the history buffer, it
is impossible for them to fail to find an entry, as at the
very least the "fc" command itself should be there.

Hence "sh" claimed such a thing was an "internal error".

But it is possible to run fc commands, not entered from
stdin, and so not eligible for the history buffer, before
any interactive commands are entered. In such a case
the history buffer will be empty, which "sh" has been
reporting as an "internal error". It isn't.
Generate a more meaningful (and less scary) message instead.

No pullups planned - the code has been like this for a
very long time, and no-one ever noticed, as it would be
very (VERY) unusual for the "fc" utility to be invoked
at a time when the history buffer is active & empty, given
the way the code currently exists (unlikely, not impossible).

This change is more in preparation for future possible
changes which would make this error easier to encounter.
 1.68 05-Jul-2024  kre Ignore non-numeric values for HISTSIZE

This is a temporary change (which can be pulled up to -9 and -10)
to avoid having
HISTSIZE=foo /bin/sh
cause sh to fail to start.

A better change, but one requiring far more code changes, so that
bad HISTSIZE is ignored, only when read from the environment, but
will be an error otherwise, will come later.

XXX pullup -9, -10
 1.67 03-Jul-2024  kre General source cleanup, whitespace, KNF, 80-col police, ...

No executable binary change intended (certainly NFCI).
Some debugging info will change as line numbers have altered.
 1.66 07-Apr-2023  kre branches: 1.66.2;

The great shell trailing whitespace cleanup of 2023...
Inspired by private e-mail comments from mouse@

NFCI.
 1.65 22-Aug-2022  kre branches: 1.65.2;

Add debugging trace points for history and the editline interface.
NFC for any normal shell (not compiled with debugging (sh DEBUG) enabled.

We have had a defined debug mode for this for years, but since I have
not often played in this arena, never used it. Until recently (relatively).
This (or a small part of it) played a part in discovering the fc -e
bug cause. I have had it in my tree a while now - recent changes
kept causing merge conflicts (all because I hadn't bothered to commit
this), so I think now is the time...
 1.64 21-Aug-2022  nia sh(1): revert previous because it interferes with custom user bindings
 1.63 18-Aug-2022  nia sh(1): Allow an explicit set -o vi or set -o emacs to override ~/.editrc
 1.62 17-Aug-2022  nia sh(1): Assign the tab completion key binding last so a user having
"bind -v" or "bind -e" in ~/.editrc doesn't cause tab completion
to no longer function.
 1.61 08-Feb-2022  rillig sh: fix typo in comment
 1.60 02-Feb-2022  kre After (a few days short of) 21 years, revert 1.25, which did nothing except
make the -e option to "fc" fail to work (the commit message was about some
other changes entirely, so I an only assume this was committed by mistake).

It says a lot about the use of the fc command that no-one noticed that
this did not work properly for all this time.

Internally in sh, it is possible for built in commands to use either
getopt(3) (from libc) or the much simpler internal shell nextopt() routine
for option (flag) parsing. However it makes no sense to use getopt()
and then access a global variable set only by nextopt() instead of the
one getopt() sets (which is what the code had used previously, forever).

Use the correct variable again.

XXX pullup -9 -8 (-7 -6 -5 ...)
 1.59 31-Jan-2022  kre When we initialize libedit (editline) always call ourselves "sh" no
matter what $0 is (or is not) set to. This means that editrc(5)
lines that start "sh:" are used (in addition to those with no prefix,
which will usually be most of them), regardless of the name or manner in
which we were invoked.

OK christos@
 1.58 31-Jan-2022  kre Add some comments explaining accesses to the environment via
getenv()/setenv()/unsetenv() which manipulate the envornoment
the shell was passed at entry.

These are a little odd in sh as that environment is copied into
the shell's internal variable data struct at shell startup, and
normally never accessed after that - in builtin commands (test.
printf, ...) getenv() is #defined to become an internal sh lookup
function instead, so even those never use the startup environment).

NFCI
 1.57 14-Sep-2021  christos Quote the filenames like before
 1.56 15-Aug-2021  christos - Add command completion (from FreeBSD)
- Use EL_SAFEREAD
 1.55 10-Feb-2019  kre branches: 1.55.2;

Remove a function prototype which was added to <histedit.h> in 2005.
I think we can trust it to be stable by now, and doin't need the dup.
 1.54 09-Feb-2019  kre INTON / INTOFF audit and cleanup.

No visible differences expected - there is a remote chance that
some internal lossage may no longer occur in interactive shells
that receive SIGINT (untrapped) at inopportune times, but you would
have had to have been very unlucky to have ever suffered from that.
 1.53 13-Jul-2018  kre Remove atoi()

Mostly use number() (no longer implemented using atoi()) when an
unsigned integer is required, but use strtoXXX() when a conversion
is wanted, without the possibility or error (like setting OPTIND
and RANDOM). Always init OPTIND to 1 when sh starts (overriding
anything in environ.)
 1.52 28-Jun-2017  kre branches: 1.52.4; 1.52.6;

Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
 1.51 27-Jun-2017  christos Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
 1.50 27-Jun-2017  kre Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
 1.49 26-Jun-2017  christos source .editrc after we initialize so that commands persist!
 1.48 16-Mar-2016  christos branches: 1.48.8;
Sprinkle volatile for gcc 5!
 1.47 18-Jun-2014  christos Adjust to the new alias text libedit API.
 1.46 23-Mar-2014  dholland branches: 1.46.2;
don't use sprintf
 1.45 20-Mar-2012  matt branches: 1.45.2;
Use C89 function definitions
 1.44 12-Jul-2011  joerg branches: 1.44.2;
Move the savehandler assignment before setjmp() to avoid triggering
warnings about use before initialization with clang.
 1.43 18-Jun-2011  christos PR/45069: Henning Petersen: Use prototypes from builtins.h .
 1.42 07-Jan-2011  jmmv branches: 1.42.4;
Call el_source before initializing sh-specific editline properties (i.e.
the editor type and the tab completion binding).

This allows tab completion to work when a user has an ~/.editrc file.

Addresses PR bin/43404.
 1.41 13-Feb-2008  joerg Set unique mode for the history, so that repeating a command doesn't
spam the history.
 1.40 16-Oct-2006  christos branches: 1.40.8;
sprinkle volatile.
 1.39 10-May-2006  mrg quell GCC 4.1 uninitialised variable warnings.

XXX: we should audit the tree for which old ones are no longer needed
after getting the older compilers out of the tree..
 1.38 06-Mar-2006  aymeric Make the -s flag of fc work correctly. Ensure that only one command is specified
and ensure that we break out of the loop after executing it.
With the previous code, because the re-executed command was added to the
history, it would think that it still had to execute it, leading to an infinite
loop.

The last thing which differs from ksh is that we get the "fc -s " command into
the history, but this is actually rather a feature in my humble opinion.

To test:
$ echo hello
$ fc -s ec
<infinite loop or correct behaviour>
 1.37 15-Jul-2005  christos Only do certain actions when we are trully interactive, not just when we
are connected to a tty:
1. enable editor
2. print directory on directory change.
3. print job messages
 1.36 09-May-2005  christos Only add the function when we initialize. Restore the binding of tab to
ed-insert if tabcomplete is cleared.
 1.35 07-May-2005  dsl If 'set -o tabcomplete' it set, then bind <tab> to the libedit filename
completion function.
Note that the libedit code will probably want fine-tuning!
While editing the man page, add a note that non-whitespace IFS chars are
terminators and can generate null arguments.
 1.34 27-Oct-2003  lukem branches: 1.34.6;
skip a leading `-' on the arg0 name when calling el_init()
 1.33 19-Oct-2003  christos Let libedit handle signals so we resize properly. I might change my mind
later on that.
 1.32 19-Oct-2003  lukem Ensure that $TERM is set in the real environment before calling el_init(3)
when executing "set -o (emacs|vi)". Fixes [bin/23175] from me.
 1.31 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.30 13-Jul-2003  itojun use bounded string op
 1.29 04-May-2003  gmcgarry ANSIify.
 1.28 04-May-2003  gmcgarry Add new builtin 'inputrc' which allows keybindings to be redefined
for the current shell. From Arne H Juul in PR#10097.
 1.27 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.26 12-Mar-2002  christos get rid of sp completely, we were free-ing a bogus pointer; found by simonb.
 1.25 04-Feb-2001  christos remove redundant declarations and nexted externs.
 1.24 06-Nov-2000  mycroft Call el_source() to use .editrc.
 1.23 14-Apr-2000  simonb Don't declare 'extern opt*' getopt variables.
 1.22 27-Jan-2000  christos Fix bin/9184, bin/9194, bin/9265, bin/9266
Exitcode and negation problems (From Martin Husemann)
 1.21 09-Jul-1999  christos compile with WARNS = 2
 1.20 28-Jul-1998  mycroft Be more retentive about use of NOTREACHED and noreturn.
 1.19 20-May-1998  christos fix bug where if moving in history during a multi-line event, the
append to history event would end up in the last event where the history
was moved to instead of the multi-line event; reported by Mycroft
 1.18 07-Apr-1998  fair Change a few things to reference /usr/include/paths.h instead of local
references. Fixing the default PATH is a bit more effort.
 1.17 12-Nov-1997  cjs Make this compile with -DSMALL and warnings on.
 1.16 14-Oct-1997  christos branches: 1.16.2;
PR/4257: Jaromir Dolecek: Update for libedit interface change.
 1.15 14-Sep-1997  lukem getopt returns -1 not EOF
 1.14 04-Jul-1997  christos Fix compiler warnings.
 1.13 11-Apr-1997  christos Track $TERM and call the appropriate editline(3) routine to update the
terminal type.
 1.12 14-Mar-1997  christos NO_HISTORY->SMALL
 1.11 13-Mar-1997  christos Fix problems with -DNO_HISTORY
 1.10 16-Oct-1996  christos PR/2808: Remove extraneous newlines from error routines (from FreeBSD)
 1.9 25-Jun-1996  christos change sethistsize() to take the history size as an argument so it can
be used directly by the new variable callback functions.
 1.8 11-May-1995  christos branches: 1.8.6;
Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.7 31-Mar-1995  christos 1. Don't core dump on 'fc -l' (From Gerard J van der Grinten)
2. PATH=xxx ls, does the PATH assignment first and then tries to find ls in xxx
3. VAR=xxx exec ls, does the variable assignment.
 1.6 21-Mar-1995  cgd convert to new RCS id conventions.
 1.5 05-Dec-1994  cgd clean up further. more patches from Jim Jegers
 1.4 04-Dec-1994  cgd from James Jegers <jimj@miller.cs.uwm.edu>: quiet -Wall, and squelch
some of the worst style errors.
 1.3 11-Jun-1994  mycroft Add RCS ids.
 1.2 12-May-1994  jtc Include appropriate header files to bring function prototypes into scope.
 1.1 11-May-1994  jtc branches: 1.1.1;
Initial revision
 1.1.1.1 11-May-1994  jtc 44lite code
 1.8.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.16.2.2 08-May-1998  mycroft Sync with trunk, per request of christos.
 1.16.2.1 13-Nov-1997  mellon Pull rev 1.17 up from trunk (cjs)
 1.34.6.1 31-Mar-2007  bouyer Pull up following revision(s) (requested by mjf in ticket #1689):
bin/sh/histedit.c: revision 1.38
Make the -s flag of fc work correctly. Ensure that only one command
is specified and ensure that we break out of the loop after executing it.
With the previous code, because the re-executed command was added to the
history, it would think that it still had to execute it, leading to
an infinite loop.
 1.40.8.1 23-Mar-2008  matt sync with HEAD
 1.42.4.1 23-Jun-2011  cherry Catchup with rmind-uvmplock merge.
 1.44.2.2 22-May-2014  yamt sync with head.

for a reference, the tree before this commit was tagged
as yamt-pagecache-tag8.

this commit was splitted into small chunks to avoid
a limitation of cvs. ("Protocol error: too many arguments")
 1.44.2.1 17-Apr-2012  yamt sync with head
 1.45.2.1 19-Aug-2014  tls Rebase to HEAD as of a few days ago.
 1.46.2.1 10-Aug-2014  tls Rebase.
 1.48.8.3 24-Feb-2022  martin Pull up following revision(s) (requested by kre in ticket #1736):

bin/sh/histedit.c: revision 1.60

After (a few days short of) 21 years, revert 1.25, which did nothing except
make the -e option to "fc" fail to work (the commit message was about some
other changes entirely, so I an only assume this was committed by mistake).

It says a lot about the use of the fc command that no-one noticed that
this did not work properly for all this time.

Internally in sh, it is possible for built in commands to use either
getopt(3) (from libc) or the much simpler internal shell nextopt() routine
for option (flag) parsing. However it makes no sense to use getopt()
and then access a global variable set only by nextopt() instead of the
one getopt() sets (which is what the code had used previously, forever).

Use the correct variable again.

XXX pullup -9 -8 (-7 -6 -5 ...)
 1.48.8.2 25-Aug-2018  martin Pull up following revision(s) (requested by kre in ticket #988):

bin/sh/parser.c: revision 1.147
bin/sh/var.c: revision 1.70
bin/sh/mystring.c: revision 1.18
bin/sh/options.c: revision 1.53
bin/sh/histedit.c: revision 1.53

Remove atoi()

Mostly use number() (no longer implemented using atoi()) when an
unsigned integer is required, but use strtoXXX() when a conversion
is wanted, without the possibility or error (like setting OPTIND
and RANDOM). Always init OPTIND to 1 when sh starts (overriding
anything in environ.)
 1.48.8.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.52.6.3 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.52.6.2 21-Apr-2020  martin Sync with HEAD
 1.52.6.1 10-Jun-2019  christos Sync with HEAD
 1.52.4.1 28-Jul-2018  pgoyette Sync with HEAD
 1.55.2.3 07-Aug-2024  martin Pull up following revision(s) (requested by kre in ticket #1860):

bin/sh/histedit.c: revision 1.72

Fix a very old core dump causing bug found by RVP in the history code.

That is, truly very old - it is in rev 1.1 from 1994 (and so is probably
even older than that).

If one uses the (very rarely used)

fc -s string=otherstring

builtin command, to rerun the previous command (or with additional args,
any other command) after replacing the first instance of "string" in that
command with "otherstring" and the resulting command line just happens to
be a length that is a multiple of the shell's memory allocation alignment
constant, then the \0 string terminator that is appended to the result
to mark its end stood a very small chance (in 1994 probably no chance at all,
but made considerably more likely in 1999 when other changes were made -
certain in the right circumstances) of being destroyed by other sh memory
allocation before the string was finished being used.

The fix (also suggested by RVP) is to make that \0 an actual part of
the allocated result string, rather than an extra byte tacked on the
end of it -- in itself, doing the latter is common in sh, and not at all
improper, sometimes even required, but only when the string as a string
will be consumed before more (shell) stack memory allocation is performed.

It 1994 it would have been. Since 1999, it isn't.

The 1999 change is going to be undone in a later commit, but this one
is simpler to pull up to earlier releases, and probably the right thing
to do anyway, even if not strictly essential.
 1.55.2.2 20-Jul-2024  martin Pull up following revision(s) (requested by kre in ticket #1856):

bin/sh/histedit.c: revision 1.68

Ignore non-numeric values for HISTSIZE

This is a temporary change (which can be pulled up to -9 and -10)
to avoid having

HISTSIZE=foo /bin/sh

cause sh to fail to start.

A better change, but one requiring far more code changes, so that
bad HISTSIZE is ignored, only when read from the environment, but
will be an error otherwise, will come later.
 1.55.2.1 21-Feb-2022  martin Pull up following revision(s) (requested by kre in ticket #1429):

bin/sh/histedit.c: revision 1.60

After (a few days short of) 21 years, revert 1.25, which did nothing except
make the -e option to "fc" fail to work (the commit message was about some
other changes entirely, so I an only assume this was committed by mistake).

It says a lot about the use of the fc command that no-one noticed that
this did not work properly for all this time.

Internally in sh, it is possible for built in commands to use either
getopt(3) (from libc) or the much simpler internal shell nextopt() routine
for option (flag) parsing. However it makes no sense to use getopt()
and then access a global variable set only by nextopt() instead of the
one getopt() sets (which is what the code had used previously, forever).

Use the correct variable again.

XXX pullup -9 -8 (-7 -6 -5 ...)
 1.65.2.2 07-Aug-2024  martin Pull up following revision(s) (requested by kre in ticket #774):

bin/sh/histedit.c: revision 1.72

Fix a very old core dump causing bug found by RVP in the history code.

That is, truly very old - it is in rev 1.1 from 1994 (and so is probably
even older than that).

If one uses the (very rarely used)

fc -s string=otherstring

builtin command, to rerun the previous command (or with additional args,
any other command) after replacing the first instance of "string" in that
command with "otherstring" and the resulting command line just happens to
be a length that is a multiple of the shell's memory allocation alignment
constant, then the \0 string terminator that is appended to the result
to mark its end stood a very small chance (in 1994 probably no chance at all,
but made considerably more likely in 1999 when other changes were made -
certain in the right circumstances) of being destroyed by other sh memory
allocation before the string was finished being used.

The fix (also suggested by RVP) is to make that \0 an actual part of
the allocated result string, rather than an extra byte tacked on the
end of it -- in itself, doing the latter is common in sh, and not at all
improper, sometimes even required, but only when the string as a string
will be consumed before more (shell) stack memory allocation is performed.

It 1994 it would have been. Since 1999, it isn't.

The 1999 change is going to be undone in a later commit, but this one
is simpler to pull up to earlier releases, and probably the right thing
to do anyway, even if not strictly essential.
 1.65.2.1 20-Jul-2024  martin Pull up following revision(s) (requested by kre in ticket #761):

bin/sh/histedit.c: revision 1.68

Ignore non-numeric values for HISTSIZE

This is a temporary change (which can be pulled up to -9 and -10)
to avoid having

HISTSIZE=foo /bin/sh

cause sh to fail to start.

A better change, but one requiring far more code changes, so that
bad HISTSIZE is ignored, only when read from the environment, but
will be an error otherwise, will come later.
 1.66.2.1 02-Aug-2025  perseant Sync with HEAD
 1.10 07-Aug-2003  agc branches: 1.10.98;
Move UCB-licensed code from 4-clause to 3-clause licence.

Patches provided by Joel Baker in PR 22249, verified by myself.
 1.9 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.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.10.98.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.10.98.1 21-Apr-2020  martin Sync with HEAD
 1.76 14-Oct-2024  kre Apologies for that commit message ... it should have been the same
as for revision 1.124 of Makefile (and as below).

(This change changes nothing).

Reject nul characters in shell input.

At the request of Thomas Klausner (wiz@) copy an idea from OpenBSD,
and have the shell simply reject any (sh) input containing a \0 (nul)
character. Previously nul characters were simply ignored (removed
from the input before it was examined in any other way).

Note this affects data read by the shell itself only, and has no
impact on other utilities, including those that are built into
the shell (so 'read' can still use -d '' to process output using
\0 as the record separator).

While I have tested that this works, there are so many places
where a nul might appear, that I cannot possibly test them all
(or even imagine all the possible places), so if this change
causes any problems, let me know (if from a script, send me the
script).

To undo this change, simply comment out (or delete) the line
CPPFLAGS+= -DREJECT_NULS
from the Makefile, and build again. Eventually if this causes
no problems, that option (conditional compilation) will probably
just go away, and this change would be permanent.

While the conditional compilation (on or off) persists, the
NETBSD_SHELL variable value will contain the word REJECT_NULLS
so you can easily verify if you are running a shell with this
included or not.

No pullups planned.
 1.75 14-Oct-2024  kre # $NetBSD: Makefile,v 1.123 2023/10/19 04:27:24 mrg Exp $
# @(#)Makefile 8.4 (Berkeley) 5/5/95

.include <bsd.own.mk>

PROG= sh
SHSRCS= alias.c arith_token.c arithmetic.c cd.c echo.c error.c eval.c exec.c \
expand.c histedit.c input.c jobs.c mail.c main.c memalloc.c \
miscbltin.c mystring.c options.c parser.c redir.c show.c trap.c \
output.c var.c test.c kill.c syntax.c
GENSRCS=builtins.c init.c nodes.c
GENHDRS=builtins.h nodes.h token.h nodenames.h optinit.h
SRCS= ${SHSRCS} ${GENSRCS}

DPSRCS+=${GENHDRS}

LDADD+= -ledit -lterminfo
DPADD+= ${LIBEDIT} ${LIBTERMINFO}

# Environment for scripts executed during build.
SCRIPT_ENV= \
AWK=${TOOL_AWK:Q} \
MKTEMP=${TOOL_MKTEMP:Q} \
SED=${TOOL_SED:Q}

CPPFLAGS+=-DSHELL -I. -I${.CURDIR} -I${NETBSDSRCDIR}/lib/libedit
CPPFLAGS+= -DUSE_LRAND48
CPPFLAGS+= -DREJECT_NULS

#XXX: For testing only.
#CPPFLAGS+=-DDEBUG=1
#COPTS+=-g
#CFLAGS+=-funsigned-char
#TARGET_CHARFLAG?= -DTARGET_CHAR="unsigned char" -funsigned-char

# Reproducible build parameters ... export into sh for NETBSD_SHELL setting
.if ${MKREPRO_TIMESTAMP:Uno} != "no"
BUILD_DATE!= ${TOOL_DATE} -u -r "${MKREPRO_TIMESTAMP}" "+%Y%m%d%H%M%S"
# These are (should be) equivalent, but the 2nd is easier to understand
#CPPFLAGS+= -DBUILD_DATE='"${BUILD_DATE:C/([^0]0?)(00)*$/\1/}Z"'
CPPFLAGS+= -DBUILD_DATE='"${BUILD_DATE:S/00$//:S/00$//:S/00$//}Z"'
.endif

.ifdef SMALLPROG
CPPFLAGS+=-DSMALL
.endif
.ifdef TINYPROG
CPPFLAGS+=-DTINY
.else
SRCS+=printf.c
.endif

.PATH: ${.CURDIR}/bltin ${NETBSDSRCDIR}/bin/test \
${NETBSDSRCDIR}/usr.bin/printf \
${NETBSDSRCDIR}/bin/kill

CLEANFILES+= ${GENSRCS} ${GENHDRS} sh.html1
CLEANFILES+= trace.*

token.h: mktokens
${_MKTARGET_CREATE}
${SCRIPT_ENV} ${HOST_SH} ${.ALLSRC}

.ORDER: builtins.h builtins.c
builtins.h builtins.c: mkbuiltins shell.h builtins.def
${_MKTARGET_CREATE}
${SCRIPT_ENV} ${HOST_SH} ${.ALLSRC} ${.OBJDIR}
[ -f builtins.h ]

init.c: mkinit.sh ${SHSRCS}
${_MKTARGET_CREATE}
${SCRIPT_ENV} ${HOST_SH} ${.ALLSRC}

.ORDER: nodes.h nodes.c
nodes.c nodes.h: mknodes.sh nodetypes nodes.c.pat
${_MKTARGET_CREATE}
${SCRIPT_ENV} ${HOST_SH} ${.ALLSRC} ${.OBJDIR}
[ -f nodes.h ]

nodenames.h: mknodenames.sh nodes.h
${_MKTARGET_CREATE}
${SCRIPT_ENV} ${HOST_SH} ${.ALLSRC} > ${.TARGET}

optinit.h: mkoptions.sh option.list
${_MKTARGET_CREATE}
${SCRIPT_ENV} ${HOST_SH} ${.ALLSRC} ${.TARGET} ${.OBJDIR}

.if ${USETOOLS} == "yes"
NBCOMPATLIB= -L${TOOLDIR}/lib -lnbcompat
.endif

SUBDIR.roff+=USD.doc

COPTS.printf.c = -Wno-format-nonliteral
COPTS.jobs.c = -Wno-format-nonliteral
COPTS.var.c = -Wno-format-nonliteral

# XXXGCC12 - only on some targets
COPTS.parser.c+= ${${ACTIVE_CC} == "gcc" && ${HAVE_GCC:U0} >= 12:? -Wno-error=clobbered :}

.include <bsd.prog.mk>
.include <bsd.subdir.mk>

${OBJS}: Makefile
 1.74 03-Aug-2024  kre Change the "string" argument to evalstring() and setinputstring()
from being "char *" to being "const char *".

This is needed for a forthcoming change which needs to pass a const char *
to evalstring (and through it to setinputstring) and be assured that
nothing will alter the characters in the string supplied.

This is (aside from the additional compile time protection provided)
a no-op change, all evalstring() does with its string is pass it to
setinputstring() and all that does with it is determine its length
(strlen() which expects a const char *) and assign the string pointer
to parsenextc which is already a const char * - there never has been
any reason for these two functions to not include the "const" in
the arg declaration -- except that when originally written (early
1990's) I suspect "const" either didn't exist at all, or wasn't
supported by relevant compilers.

NFCI. Most probably (though I didn't check) no binary change at all.
 1.73 13-Jul-2024  kre Implement the HISTFILE and HISTAPPEND variables.

See the (newly updated) sh(1) for details.
Also add the -z option to fc (clear history).

None of this exists in SMALL shells.
 1.72 16-Feb-2021  kre branches: 1.72.8;
PR bin/55979

Correctly handle (ie: ignore completely) \0 chars (nuls) in the
shell command input stream (script, dot file, or stdin).

Previously nul chars were ignored correctly in the line in which
they occurred, but would cause trailing chars of that line to reappear
as the start of the following line. If there was just one \0 skipped,
this would generally result in an extra \n in the sh input, which in
most cases has no effect. With multiple \0's in a single line, more
of the end of that line was duplicated into the following one. This
usually manifested as a weird "command not found" error.

Note that any \0 chars in the sh input make the script non-conforming,
so fixing this is not crucial (no \0's should really ever be seen) but
it was an obvious bug in the code, which was attempting to ignore nul
chars (as do many other shells), so let it be fixed.

XXX pullup -9
 1.71 09-Feb-2019  kre branches: 1.71.2;

KNF - white space changes, indent using tabs not spaces. NFC.
 1.70 09-Feb-2019  kre INTON / INTOFF audit and cleanup.

No visible differences expected - there is a remote chance that
some internal lossage may no longer occur in interactive shells
that receive SIGINT (untrapped) at inopportune times, but you would
have had to have been very unlucky to have ever suffered from that.
 1.69 16-Jan-2019  kre Redo 1.65 in a simpler way. This is the bit rot avoidance code
that is #if 0'd and (still) has never been compiled (most likely
never will be.)

While here, in the same uncompiled code, deal with line number
counting. Whether this is correct depends upon how this code
is used, and as it never is (and never has been since line numbers
first started being counted), this is somewhat speculative, but
it seems likely to be the correct way to handle things.

NFC (this code is still all #if 0).
 1.68 15-Jan-2019  kre Don't use quoteflag when deciding if the word after an alias
should be looked up as a potential following alias - if the first
expands to a string that ends with a space (any space, quoted or
not) then the next word is to be treated as an alias candidate.
(POSIX was to specify only unquoted spaces, but is now going to
leave that unspecified, and the "any space" version turns out to
be more useful.

And besides, the quoteflag test didn't work properly, and would
have been very messy to fix ... if in a word (as if we have a
quoted space) it means that the word has been quoted, which meant
that quoted spaces were correctly detected, but it outside a word,
it just means that the previous word was quoted, so it would sometimes
reject alias lookup on the next word in cases where it is unquestioned
it should be done.
 1.67 09-Jan-2019  kre Correct an (old) typo in a comment. NFC - it is just a comment.
 1.66 09-Jan-2019  kre Fix the code taken from FreeBSD 2 revisions back, which fixed
aliases, to actually do what it was supposed to do, and not just
come close by accident. (How broken this was, while still seeming
to work perfectly most of the time was truly amazing!)

This corrects the behaviour of an alias defined with a blank char
as the last of its value, to correctly do an alias lookup on the
word that follows the alias.
 1.65 09-Jan-2019  kre Update some dead (#if 0'd) code that is never called to
cope with the changes made in the previous revision, in an
attempt to avoid bit rot.

Untested (uncompiled) - though it should work.

NFC: this change doesn't get compiled, let alone used.
 1.64 03-Dec-2018  kre Revamp aliases - as dumb an idea as they are, if we're going
to have them, they should work as documented, not cause core
dumps, reference after free, incorrect replacements, failing
to implement alias after alias, ...

The big comment that ended:
This is a good idea ------- ***NOT***
and the hack it was describing are gone.

Note that most of this was from original CVS version 1.1
code (ie: came from the original import, even before 4.4-Lite
was merged. That is, May 1994. And no-one in 24.5 years
noticed (or at least complained about) all the bugs (or at
least, most of them)).

With these changes, aliases ought to work (if you can call it
that) as they are expected to by POSIX. Now if only we could
get POSIX to delete them (or make them optional)...

Changes partly inspired by similar changes made by FreeBSD,
(as was the previous change to alias.c, forgot ack in commit
log for that one, apologies) but done a little differently,
and perhaps with a slightly better outcome.
 1.63 19-Aug-2018  kre PR bin/48875 (is related, and ameliorated, but not exactly "fixed")

Import a whole set of tree evaluation enhancements from FreeBSD.

With these, before forking, the shell predicts (often) when all it will
have to do after forking (in the parent) is wait for the child and then
exit with the status from the child, and in such a case simply does not
fork, but rather allows the child to take over the parent's role.

This turns out to handle the particular test case from PR bin/48875 in
such a way that it works as hoped, rather than as it did (the delay there
was caused by an extra copy of the shell hanging around waiting for the
background child to complete ... and keeping the command substitution
stdout open, so the "real" parent had to wait in case more output appeared).

As part of doing this, redirection processing for compound commands gets
moved out of evalsubshell() and into a new evalredir(), which allows us
to properly handle errors occurring while performing those redirects,
and not mishandle (as in simply forget) fd's which had been moved out
of the way temporarily.

evaltree() has its degree of recursion reduced by making it loop to
handle the subsequent operation: that is instead of (for any binop
like ';' '&&' (etc)) where it used to
evaltree(node->left);
evaltree(node->right);
return;
it now does (kind of)
next = node;
while ((node = next) != NULL) {
next = NULL;

if (node is a binary op) {
evaltree(node->left);
if appropriate /* if && test for success, etc */
next = node->right;
continue;
}
/* similar for loops, etc */
}
which can be a good saving, as while the left side (now) tends to be
(usually) a simple (or simpleish) command, the right side can be many
commands (in a command sequence like a; b; c; d; ... the node at the
top of the tree will now have "a" as its left node, and the tree for
b; c; d; ... as its right node - until now everything was evaluated
recursively so it made no difference, and the tree was constructed
the other way).

if/while/... statements are done similarly, recurse to evaluate the
condition, then if the (or one of the) body parts is to be evaluated,
set next to that, and loop (previously it recursed).

There is more to do in this area (particularly in the way that case
statements are processed - we can avoid recursion there as well) but
that can wait for another day.

While doing all of this we keep much better track of when the shell is
just going to exit once the current tree is evaluated (with a new
predicate at_eof() to tell us that we have, for sure, reached the end
of the input stream, that is, this shell will, for certain, not be reading
more command input) and use that info to avoid unneeded forks. For that
we also need another new predicate (have_traps()) to determine of there
are any caught traps which might occur - if there are, we need to remain
to (potentially) handle them, so these optimisations will not occur (to
make the issue in PR 48875 appear again, run the same code, but with a
trap set to execute some code when a signal (or EXIT) occurs - note that
the trap must be set in the appropriate level of sub-shell to have this
effect, any caught traps are cleared in a subshell whenever one is created).

There is still work to be done to handle traps properly, whatever
weirdness they do (some of which is related to some of this.)

These changes do not need man page updates, but 48875 does - an update
to sh.1 will be forthcoming once it is decided what it should say...

Once again, all the heavy lifting for this set of changes comes directly
(with thanks) from the FreeBSD shell.

XXX pullup-8 (but not very soon)
 1.62 19-Aug-2017  kre branches: 1.62.2; 1.62.4;

NFC - DEBUG mode change only - add some sanity to a debug printf format string
 1.61 05-Aug-2017  kre PR bin/52458

Avoid mangling history when editing is enabled, and the prompt contains a \n

Also, allow empty input lines into history when they are being appended to
a previous (partial) command (but not when they would just make an empty entry).

For all the gory details, see the PR.

Note nothing here actually makes prompts containing \n work correctly
when editing is enabled, that's a libedit issue, which will be addressed
some other time.
 1.60 05-Jul-2017  kre Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
 1.59 30-Jun-2017  kre Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
 1.58 07-Jun-2017  kre A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)

This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)

The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.

This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).

I would not call the results of this perfect yet, but it is close.
 1.57 07-Jun-2017  kre An initial attempt at implementing LINENO to meet the specs.

Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.

Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)

This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.

POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)

This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.

This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).

Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
 1.56 03-May-2017  kre branches: 1.56.2;

Another fix from FreeBSD. I'm not sure how to trigger the problem
fixed (there might be no way) - but it "feels right"!

When popping an (exhausted) input string off the input stack, allow
for the possibility that the previous string might also just happened
to have run out of steam as well, so keep poppin' along until we
run out of pop, or find something to consume.
 1.55 03-May-2017  kre Deal with \newline line continuations more correctly.
They can occur anywhere (*anywhere*) not only where it
happens to be convenient to the parser...

This fix from FreeBSD (thanks again folks).

To make this work, pushstring()'s signature needed to change to allow a
const char * as its string arg, which meant sprinkling some const other
places for a brighter appearance (and handling fallout).

All this because I wanted to see what number would come from

echo $\
{\
L\
I\
N\
E\
N\
O\
}

and was surprised at the result! That works now...

The bug would also affect stuff like

true &\
& false

and all kinds of other uses where the \newline occurred in the
"wrong" place.

An ATF test for sh syntax is coming... (sometime.)
 1.54 03-May-2017  kre Fix idiot typos in previous (this is not the advertised :next commit")
Same typo - two different places. Ugh!
 1.53 03-May-2017  kre NFC: Change prototype of pushstring() to give a real type for the 3rd
arg (struct alias *) rather than using void * and then casting it
when used. For callers, the arg either is a struct alias *, or is NULL,
so nothing to adjust there.

NB: This change untested by itself, it was going to be a part of the next
change (coming in a few minutes) but is logically unrelated, so ...
 1.52 29-Apr-2017  kre Keep track of which file descriptors the shell is using for its
own purposes, and move them elsewhere whenever a user redirection
happens to pick the same number. With this we can move the shell
file descriptors back to lower values (be slightly kinder to the kernel)
since we can no longer clash. (Also get rid of a little old unneeded code.)

This also completes the fdflags command, which no longer permits access
to (by way or either obtaining, or changing) the shell's internal fds.
 1.51 01-Jun-2016  kre branches: 1.51.6;

PR bin/51207 Only check for ELF bnaries in regular files.
 1.50 07-May-2016  kre PR bin/51119 - don't leak FDs in unusual error cases. OK christos@
 1.49 02-May-2016  christos Fix handing of user file descriptors outside the 0..9 range.
Also, move (most of) the shell's internal use fd's to much
higher values (depending upon what ulimit -n allows) so they
are less likely to clash with user supplied fd numbers. A future
patch will (hopefully) avoid this problem completely by dynamically
moving the shell's internal fds around as needed. (From kre@)
 1.48 27-Mar-2016  christos General KNF and source code cleanups, avoid scattering the
magic string " \t\n" all over the place, slightly improved
syntax error messages, restructured some of the code for
clarity, don't allow IFS to be imported through the environment,
and remove the (never) conditionally compiled ATTY option.
Apart from one or two syntax error messages, and ignoring IFS
if present in the environment, this is intended to have no
user visible changes. (from kre@)
 1.47 04-Jan-2016  christos Don't leak redirected rescriptors to exec'ed processes. This is what ksh
does, but bash does not. For example:

$ cat test1
#!/bin/sh
exec 6> out
echo "test" >&6
sh ./test2
exec 6>&-
$ cat test2
echo "test2" >&6
$ ./test1
./test2: 6: Bad file descriptor

This fixes by side effect the problem of the rc system leaking file descriptors
7 and 8 to all starting daemons:

$ fstat -p 1359
USER CMD PID FD MOUNT INUM MODE SZ|DV R/W
root powerd 1359 wd / 2 drwxr-xr-x 512 r
root powerd 1359 0 / 63029 crw-rw-rw- null rw
root powerd 1359 1 / 63029 crw-rw-rw- null rw
root powerd 1359 2 / 63029 crw-rw-rw- null rw
root powerd 1359 3* kqueue pending 0
root powerd 1359 4 / 64463 crw-r----- power r
root powerd 1359 7 flags 0x80034<ISTTY,MPSAFE,LOCKSWORK,CLEAN>
root powerd 1359 8 flags 0x80034<ISTTY,MPSAFE,LOCKSWORK,CLEAN>
root powerd 1359 9* pipe 0xfffffe815d7bfdc0 -> 0x0 w

Note fd=7,8 pointing to the revoked pty from the parent rc process.
 1.46 30-Oct-2013  mrg #ifdef a variable decl/setting with it's use.
 1.45 28-Mar-2012  christos branches: 1.45.2;
include <limits.h> for CHAR_MIN/CHAR_MAX
 1.44 17-Feb-2011  pooka branches: 1.44.4;
Tell copyfd if the caller wants the exact tofd to just fd >= tofd.
Fixes "echo foo > /rump/bar" in a rump hijacked shell.

reviewed by christos
 1.43 30-Aug-2010  christos branches: 1.43.2;
dprintf is claimed by posix.
 1.42 10-Mar-2009  roy el_gets now sets el_len to -1 on error so we can distinguish
between a NULL string and an error.
This fixes sh from exiting with libedit now allowing EINTR to return.
We may need to expand this to an errno check in the future.
 1.41 16-Oct-2008  dholland branches: 1.41.4;
Use "extern" properly for referencing globals defined in other modules.
Now builds cleanly with -warn-common.
 1.40 15-Feb-2007  rillig Since interpreting ELF binaries as shell scripts is not very useful, and
since the current error message is less than helpful, improve it.
 1.39 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.38 15-May-2003  dsl Don't close any script files if vfork is set.
If a fork() is done later in order to feed a 'here' document into a pipe
then it is possible that one end of the pipe might get closed.
 1.37 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.36 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.35 04-Feb-2001  christos branches: 1.35.2;
remove redundant declarations and nexted externs.
 1.34 22-May-2000  elric Back out previous vfork changes.
 1.33 13-May-2000  elric Now we use vfork(2) instead of fork(2) when we can.
 1.32 09-Jul-1999  christos compile with WARNS = 2
 1.31 20-May-1998  christos Simplify interface for general use.
 1.30 20-May-1998  christos fix bug where if moving in history during a multi-line event, the
append to history event would end up in the last event where the history
was moved to instead of the multi-line event; reported by Mycroft
 1.29 29-Mar-1998  mrg - change "extern" variables into int's
- remove extern'd variables not actually referenced
- don't use char as an array index
 1.28 14-Oct-1997  christos branches: 1.28.2;
PR/4257: Jaromir Dolecek: Update for libedit interface change.
 1.27 04-Jul-1997  christos Fix compiler warnings.
 1.26 11-Apr-1997  christos Rename pread to preadfd
 1.25 14-Mar-1997  christos NO_HISTORY->SMALL
 1.24 13-Mar-1997  christos Fix problems with -DNO_HISTORY
 1.23 13-Mar-1997  mycroft Set input files to close-on-exec mode.
 1.22 11-Jan-1997  tls kill 'register'
 1.21 02-Nov-1996  christos Fix problems that gcc -Wall found (from Todd Miller, OpenBSD)
 1.20 16-Oct-1996  christos PR/2808: Remove trailing whitespace (from FreeBSD)
 1.19 19-Oct-1995  christos branches: 1.19.4;
- fix PR1620, -DNO_HISTORY did not work.
- restore parsing state after parsing old style command substitution.
The ';' in '`echo z;`' broke the following:
for i in 1; do
cat > /dev/tty << __EOF__
`echo z;`
__EOF__
done

cVS: Enter Log. Lines beginning with `CVS: ' are removed automatically
 1.18 06-Oct-1995  christos fixed previous booboo that broke command line editing input.
 1.17 26-Sep-1995  christos - Fix -v flag, so that it works properly when the shell reads from scripts.
- Bad style to fix my own PR, but I'd like to commit the parallel make
changes soon, and this is a necessary prerequisite.
 1.16 09-Jun-1995  christos Changed so that 'PATH=newpath command' works, instead of looking at the
old path. Synced input.c with vangogh.
 1.15 07-Jun-1995  cgd needs string.h
 1.14 11-May-1995  christos Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.13 21-Mar-1995  cgd convert to new RCS id conventions.
 1.12 23-Dec-1994  cgd pull prototypes into scope for string functions.
 1.11 04-Dec-1994  cgd from James Jegers <jimj@miller.cs.uwm.edu>: quiet -Wall, and squelch
some of the worst style errors.
 1.10 11-Jun-1994  mycroft Add RCS ids.
 1.9 08-Jun-1994  jtc Fix from Christos for when NO_HISTORY is defined
 1.8 21-May-1994  cgd a few more things to omit when NO_HISTORY defined. from noel@cs.oberlin.edu
 1.7 14-May-1994  cgd add back in support for building w/o obj dir. also, add NO_HISTORY
define, which (if you invoke mkbuiltins properly) gets you a sh w/o
history of command line editing (for floppy sh).
 1.6 12-May-1994  jtc Include appropriate header files to bring function prototypes into scope.
 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.19.4.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.28.2.1 08-May-1998  mycroft Sync with trunk, per request of christos.
 1.35.2.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.41.4.1 13-May-2009  jym Sync with HEAD.

Third (and last) commit. See http://mail-index.netbsd.org/source-changes/2009/05/13/msg221222.html
 1.43.2.1 05-Mar-2011  bouyer Sync with HEAD
 1.44.4.2 22-May-2014  yamt sync with head.

for a reference, the tree before this commit was tagged
as yamt-pagecache-tag8.

this commit was splitted into small chunks to avoid
a limitation of cvs. ("Protocol error: too many arguments")
 1.44.4.1 17-Apr-2012  yamt sync with head
 1.45.2.1 19-Aug-2014  tls Rebase to HEAD as of a few days ago.
 1.51.6.2 11-May-2017  pgoyette Sync with HEAD
 1.51.6.1 02-May-2017  pgoyette Sync with HEAD - tag prg-localcount2-base1
 1.56.2.2 09-Aug-2017  snj Pull up following revision(s) (requested by kre in ticket #199):
bin/sh/input.c: revision 1.61
bin/sh/parser.c: revision 1.143
PR bin/52458
Avoid mangling history when editing is enabled, and the prompt contains a \n
Also, allow empty input lines into history when they are being appended to
a previous (partial) command (but not when they would just make an empty entry)
.
For all the gory details, see the PR.
Note nothing here actually makes prompts containing \n work correctly
when editing is enabled, that's a libedit issue, which will be addressed
some other time.
 1.56.2.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.62.4.3 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.62.4.2 21-Apr-2020  martin Sync with HEAD
 1.62.4.1 10-Jun-2019  christos Sync with HEAD
 1.62.2.3 18-Jan-2019  pgoyette Synch with HEAD
 1.62.2.2 26-Dec-2018  pgoyette Sync with HEAD, resolve a few conflicts
 1.62.2.1 06-Sep-2018  pgoyette Sync with HEAD

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

bin/sh/input.c: revision 1.72
bin/sh/exec.c: revision 1.55

PR bin/55979

This fixes the MSAN detected reference to an unitialised variable
(an unitialised field in a struct) which happens when a command is
not found after a PATH search.
Aside from skipping some known to be going to fail exec*() calls
in some cases, the setting of the relevant field is irrelevant,
so this problem makes no practical difference to the shell, or any
shell script.

XXX (maybe) pullup -9


PR bin/55979

Correctly handle (ie: ignore completely) \0 chars (nuls) in the
shell command input stream (script, dot file, or stdin).
Previously nul chars were ignored correctly in the line in which
they occurred, but would cause trailing chars of that line to reappear
as the start of the following line. If there was just one \0 skipped,
this would generally result in an extra \n in the sh input, which in
most cases has no effect. With multiple \0's in a single line, more
of the end of that line was duplicated into the following one. This
usually manifested as a weird "command not found" error.

Note that any \0 chars in the sh input make the script non-conforming,
so fixing this is not crucial (no \0's should really ever be seen) but
it was an obvious bug in the code, which was attempting to ignore nul
chars (as do many other shells), so let it be fixed.

XXX pullup -9
 1.72.8.1 02-Aug-2025  perseant Sync with HEAD
 1.22 03-Aug-2024  kre Change the "string" argument to evalstring() and setinputstring()
from being "char *" to being "const char *".

This is needed for a forthcoming change which needs to pass a const char *
to evalstring (and through it to setinputstring) and be assured that
nothing will alter the characters in the string supplied.

This is (aside from the additional compile time protection provided)
a no-op change, all evalstring() does with its string is pass it to
setinputstring() and all that does with it is determine its length
(strlen() which expects a const char *) and assign the string pointer
to parsenextc which is already a const char * - there never has been
any reason for these two functions to not include the "const" in
the arg declaration -- except that when originally written (early
1990's) I suspect "const" either didn't exist at all, or wasn't
supported by relevant compilers.

NFCI. Most probably (though I didn't check) no binary change at all.
 1.21 19-Aug-2018  kre branches: 1.21.12;
PR bin/48875 (is related, and ameliorated, but not exactly "fixed")

Import a whole set of tree evaluation enhancements from FreeBSD.

With these, before forking, the shell predicts (often) when all it will
have to do after forking (in the parent) is wait for the child and then
exit with the status from the child, and in such a case simply does not
fork, but rather allows the child to take over the parent's role.

This turns out to handle the particular test case from PR bin/48875 in
such a way that it works as hoped, rather than as it did (the delay there
was caused by an extra copy of the shell hanging around waiting for the
background child to complete ... and keeping the command substitution
stdout open, so the "real" parent had to wait in case more output appeared).

As part of doing this, redirection processing for compound commands gets
moved out of evalsubshell() and into a new evalredir(), which allows us
to properly handle errors occurring while performing those redirects,
and not mishandle (as in simply forget) fd's which had been moved out
of the way temporarily.

evaltree() has its degree of recursion reduced by making it loop to
handle the subsequent operation: that is instead of (for any binop
like ';' '&&' (etc)) where it used to
evaltree(node->left);
evaltree(node->right);
return;
it now does (kind of)
next = node;
while ((node = next) != NULL) {
next = NULL;

if (node is a binary op) {
evaltree(node->left);
if appropriate /* if && test for success, etc */
next = node->right;
continue;
}
/* similar for loops, etc */
}
which can be a good saving, as while the left side (now) tends to be
(usually) a simple (or simpleish) command, the right side can be many
commands (in a command sequence like a; b; c; d; ... the node at the
top of the tree will now have "a" as its left node, and the tree for
b; c; d; ... as its right node - until now everything was evaluated
recursively so it made no difference, and the tree was constructed
the other way).

if/while/... statements are done similarly, recurse to evaluate the
condition, then if the (or one of the) body parts is to be evaluated,
set next to that, and loop (previously it recursed).

There is more to do in this area (particularly in the way that case
statements are processed - we can avoid recursion there as well) but
that can wait for another day.

While doing all of this we keep much better track of when the shell is
just going to exit once the current tree is evaluated (with a new
predicate at_eof() to tell us that we have, for sure, reached the end
of the input stream, that is, this shell will, for certain, not be reading
more command input) and use that info to avoid unneeded forks. For that
we also need another new predicate (have_traps()) to determine of there
are any caught traps which might occur - if there are, we need to remain
to (potentially) handle them, so these optimisations will not occur (to
make the issue in PR 48875 appear again, run the same code, but with a
trap set to execute some code when a signal (or EXIT) occurs - note that
the trap must be set in the appropriate level of sub-shell to have this
effect, any caught traps are cleared in a subshell whenever one is created).

There is still work to be done to handle traps properly, whatever
weirdness they do (some of which is related to some of this.)

These changes do not need man page updates, but 48875 does - an update
to sh.1 will be forthcoming once it is decided what it should say...

Once again, all the heavy lifting for this set of changes comes directly
(with thanks) from the FreeBSD shell.

XXX pullup-8 (but not very soon)
 1.20 30-Jun-2017  kre branches: 1.20.4; 1.20.6;

Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
 1.19 07-Jun-2017  kre An initial attempt at implementing LINENO to meet the specs.

Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.

Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)

This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.

POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)

This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.

This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).

Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
 1.18 03-May-2017  kre branches: 1.18.2;

Deal with \newline line continuations more correctly.
They can occur anywhere (*anywhere*) not only where it
happens to be convenient to the parser...

This fix from FreeBSD (thanks again folks).

To make this work, pushstring()'s signature needed to change to allow a
const char * as its string arg, which meant sprinkling some const other
places for a brighter appearance (and handling fallout).

All this because I wanted to see what number would come from

echo $\
{\
L\
I\
N\
E\
N\
O\
}

and was surprised at the result! That works now...

The bug would also affect stuff like

true &\
& false

and all kinds of other uses where the \newline occurred in the
"wrong" place.

An ATF test for sh syntax is coming... (sometime.)
 1.17 03-May-2017  kre Fix idiot typos in previous (this is not the advertised :next commit")
Same typo - two different places. Ugh!
 1.16 03-May-2017  kre NFC: Change prototype of pushstring() to give a real type for the 3rd
arg (struct alias *) rather than using void * and then casting it
when used. For callers, the arg either is a struct alias *, or is NULL,
so nothing to adjust there.

NB: This change untested by itself, it was going to be a part of the next
change (coming in a few minutes) but is logically unrelated, so ...
 1.15 07-Aug-2003  agc branches: 1.15.88;
Move UCB-licensed code from 4-clause to 3-clause licence.

Patches provided by Joel Baker in PR 22249, verified by myself.
 1.14 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.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 Now we use vfork(2) instead of fork(2) when we can.
 1.10 09-Jul-1999  christos compile with WARNS = 2
 1.9 16-Oct-1996  christos PR/2808: Remove trailing whitespace (from FreeBSD)
 1.8 11-May-1995  christos branches: 1.8.6;
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.8.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 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.15.88.1 11-May-2017  pgoyette Sync with HEAD
 1.18.2.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.20.6.3 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.20.6.2 21-Apr-2020  martin Sync with HEAD
 1.20.6.1 10-Jun-2019  christos Sync with HEAD
 1.20.4.1 06-Sep-2018  pgoyette Sync with HEAD

Resolve a couple of conflicts (result of the uimin/uimax changes)
 1.21.12.1 02-Aug-2025  perseant Sync with HEAD
 1.124 09-Apr-2025  kre DEBUG mode change only (NFC any normal build)

Don't potentially refer to an un-init'd variable in a DEBUG mode trace msg,
and don't bother setting the variable when it won't be used when DEBUG is
not enabled.
 1.123 09-Oct-2024  kre PR bin/58687 -- implement suspend as a builtin in sh

Requested by uwe@ in PR bin/58687 without objections from
anyone except me, here is an implementation of a suspend
builtin command for /bin/sh

The sh.1 man page is updated, naturally, to describe it.

This new builtin does not exist in SMALL shells -- as used
on (some) boot media, etc.

If this turns out not to be useful, it can easily be removed.
 1.122 18-Jun-2024  kre branches: 1.122.2;
Remove the possibility that all jobs won't be cleaned up by "wait"

There was a possibility that in a wait (no options or args) not
all jobs would be cleaned up, which that should be, as such a wait
should not finish (uninterrupted) until everything else is done.

This was unlikely to happen - but it's easy to make sure it doesn't.
 1.121 15-Jun-2024  kre When generating the text that identifies the command for the job tree
from the parse tree data, be more intelligent about where we stick ';'
characters.

Previously, given:

(sleep 2 & sleep 3 & sleep 10&) & jobs -l

The output would be something like

[1] + 23631 Running (sleep 2 &; sleep 3 &; sleep 10 &)

That's nonsense (even if clear enough). After this change the
output will be:

[1] + 12116 Running (sleep 2 & sleep 3 & sleep 10 &)

There are a few other cases where an incorrect ';' will also be suppressed.
 1.120 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.119 30-Jan-2024  kre PR bin/57894

For jobs -p for a non-job-control job, avoid just printing 0 (as
there is no process group pid) and instead output what we used to,
the pid of one of the processes in the job (usually the right one!)

XXX pullup -10 (9 and earlier not affected).
 1.118 07-Apr-2023  kre The great shell trailing whitespace cleanup of 2023...
Inspired by private e-mail comments from mouse@

NFCI.
 1.117 30-Oct-2022  kre branches: 1.117.2;
PR bin/57053 is related (peripherally) here.

sh has been remembering the process group of a job for a while now, but
using that for almost nothing.

The old way to resume a job, was to try each pid in the job with a
SIGCONT (using it as the process group identifier via killpg()) until
one worked (or none did, in which case resuming would be impossible,
but that never actually happened). This wasn't as bad as it seems,
as in practice the first process attempted was *always* the correct
one. Why the loop was considered necessary I am not sure. Nothing
but the first could possibly work.

This worked until a fix for an obscure possible bug was added a
while ago - now a process which has already finished, and had its
zombie collected via wait*() is no longer ever considered to have
a pid which is a candidate for use in any system call. That's
because the kernel might have reassigned that pid for some newly
created process (we have no idea how much time might have passed
since the pid was returned to the kernel for reuse, it might have
happened weeks ago).

This is where the example in bin/57053 revealed a problem.

That PR is really about a quite different problem in zsh (from pksrc)
and should be pkg/57053, but as the test case also hit the problem
here, it was assumed (by some) they were the same issue.

The example is (in a small directory)
ls | less
which is then suspended (^Z), and resumed (fg). Since the directory
is small, ls will be finished, and reaped by sh - so the code would
now refuse to use its pid for the killpg() call to send the SIGCONT.
The (useless) loop would attempt to use less's pid for this purpose
(it is still alive at this point) but that would fail, as that pid
is not a process group identifier, of anything. Hence the job
could not be resumed.

Before the PR (or preceding mailing list discussion) the change here
had already been made (part of a much bigger set of changes, some of
which might follow - sometime). We now actually use the job's
remembered process group identifier when we want the process group
identifier, instead of trying to guess which pid it happens to be
(which actually never took any guessing, it was, and is always the
pid of the first process created for the job). A couple of minor
fixes to how the pgrp is obtained, and used, accompany the changes
to use it when appropriate.
 1.116 18-Apr-2022  kre Introduce a new macro JNUM to replace the idiom jp-jobtab+1
(the job number, given jp a pointer to a jobs table entry)
used open coded previously in many places (mostly in DEBUG mode
trace messages, so not included in most shells, but there are
a few others).

Make the type of JNUM() be int rather than the ptrdiff_t the
open coded version became ... which when used in some printf()
type function arg list was cast to some other arbitrary (but not
consistent) int type for which there is a standard %Xd type
format conversion. Now we can (and do) just use %d for this.

If the number of jobs ever exceeds the range of an int, we would
have far more serious problems than the broken output this would
cause.

While here improve a comment or two, and use JOBRUNNING instead
of 0 where the intent is the former (JOBRUNNING is #defined as 0).

NFCI.
 1.115 19-Dec-2021  andvar s/forground/foreground/ in comments.
 1.114 10-Oct-2021  rillig sh: remove useless do-while-0 loop

28 years was more than enough for the useless 'continue' statement in
this do-while-0 "loop". Without the 'continue' statement, there is no
need for the "loop" anymore. The comment at its top was confusing since
the word 'while' suggested a loop, but there was none, so remove that as
well.

Pointed out by Tom Ivar Helbekkmo on source-changes-d.

No change to the resulting binary.
 1.113 10-Oct-2021  rillig sh: remove no-op 'continue' from do-while-0 loop

With Clang, the only change to the binary are the line number changes
from __LINE__, GCC generates a bit different code.

No functional change.
 1.112 12-Sep-2021  kre Don't dereference NULL on "jobs -Z" (with no title given), instead
do setproctitle(NULL) (which is not the same thing at all). Do the
same with jobs -Z '' as setting the title to "sh: " isn't useful.

Improve the way this is documented, and note that it is only done
this way because zsh did it first (ie: pass on the balme, doing this
in the jobs command is simply absurd.)
 1.111 11-Sep-2021  christos Add jobs -Z (like in zsh(1)) to setproctitle(3).
 1.110 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.109 30-Aug-2020  kre Since "struct job" gained a pgrp member some time ago now, use it
instead of simply assuming that the pid of the first (leftmost) process
in a pipeline is the pgrp - someday we may switch things around and
create pipelines right to left instead, which has several advantages,
but which would invalidate the assumption which was being made here.
 1.108 20-Aug-2020  kre Add lots of comments explaining what is happening in here.

Also enhance some of the DEBUG mode trace output (nothing visible
in a normal shell build).

A couple of very minor code changes that no-one should ever notice
(eg: one less wait() call in the case that there is nothing pending).
 1.107 07-Feb-2020  kre Avoid a core dump if a child process that is not one of our
children happens to exit while we are waiting for another child
to exit.

This can happen with code like

sh -c '
sleep 5 &
exec sh -c "sleep 10 & wait !$"
'

when the inner "sh" is waiting for the 10 second sleep to be
done, the 5 second sleep started earlier terminates. It is
a child of our process, as the inner shell is the same process
as the outer one, but not a known child (the inner shell has no
idea what the outer one did before it started).

This was observed in the wild by Martijn Dekker (where the outer
shell was bash but that's irrelevant).

XXX pullup -9
 1.106 26-Mar-2019  kre branches: 1.106.2;
Fix a logic botch that prevented "wait -n" (with no pid args) from
finding a job that had previously terminated.

Now in that case JOBWANTED is set on all jobs (since any will do)
which then simplifies a later test which no longer needs to special
case "wait -n". Further, we always look to see if any wanted
job has already terminated, even if there are still running jobs
we can wait upon - if anything is already ready, that's where we start
harvesting (and finish, if -n is specified).
 1.105 09-Feb-2019  kre In the unlikely event that restarting a job fails (the fg bg and various
%x commands) generate the most useful error message (from errno value)
rather than whichever happened last.

In posix mode, cause the "jobs" command to delete records of completed
jobs it reports on (as posix requires) as is done in interactive shells.
We don't (won't) do this in !posix mode, as the ability to throw in a
"jobs" command in a script to debug what is happening is too useful to
lose -- and any script that is relying on "jobs" instead of "wait" to
cleanup background processes (from the sh jobs table, sh always collects
zombies from the kernel) is absurd and not worth considering (besides
which I've never seen one).
 1.104 09-Feb-2019  kre INTON / INTOFF audit and cleanup.

No visible differences expected - there is a remote chance that
some internal lossage may no longer occur in interactive shells
that receive SIGINT (untrapped) at inopportune times, but you would
have had to have been very unlucky to have ever suffered from that.
 1.103 03-Dec-2018  kre When forking a child shell, arrange for errors/exit to always unwind
to the main handler, rather than wherever the parent shell would go.

nb: not needed for vfork(), after vfork() we never go that path - which
is good or we'd be corrupting the parent's handler.

This allows the child to always exit (when it should) rather than being
caught up doing something else (and while it would eventually exit, the
status would be incorrect in some cases).

One test is:
sh -c 'trap "(! :) && echo BUG || echo nobug" EXIT'
from Martijn Dekker

Fix from FreeBSD (missed earlier).

XXX - 2b part of the 48875 pullup to -8
 1.102 28-Oct-2018  kre Use strsignal() rather than direct reference to sys_siglist[]
(apart from being cleaner, it also simplifies the code, as
strsignal() never fails ... it also removes one reference to NSIG).
 1.101 13-Sep-2018  kre A change in rev 1.91 interacted badly with the way that showjobs()
worked, preventing $(jobs) (and more usefully $(jobs -p) from
working. Fix that.

XXX pullup -8
 1.100 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.99 04-Sep-2018  kre PR bin/38004

Save more characters of command in non-interactive jobs, in case of
core dumps and similar (16 effective chars was a few too little).

Arrange for number to increase if command buffer size increases.
 1.98 30-Dec-2017  kre branches: 1.98.2; 1.98.4;
In addition to previous the which fixed a (harmless) MSAN detected ref
of uninit'd field also fix a couple more (still harmless) related
technical C usage bugs.

Explaining why these issues were harmless would take too long to include here.
 1.97 30-Dec-2017  christos initialize just used and prev_job
 1.96 30-Dec-2017  christos initialize the jobtab; it is easier than putting checks for used everywhere.
 1.95 28-Oct-2017  kre 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.94 28-Oct-2017  kre Another %zu for size_t (this one in a DEBUG mode trace call, so it
doesn't actually ever bother anyone in practice.)
 1.93 25-Oct-2017  martin Use %zu for size_t
 1.92 25-Oct-2017  kre Add options to the builtin jobid command to allow discovering the
process group (-g), the process leader pid (-p) ($! if the job was &'d)
and the job identifier (-j) (the %n that refers to the job) in addition to
(default) the list of all pids in the job (which it has always done).
No change to the (single) "job" arg, which is a specifier of the job:
the process leader pid, or one of the % forms, and defaults to %% (aka %+).
(This is all now documented in sh(1))

Also document the jobs command properly (no change to the command, just
document what it actually is.)

And while here, a whole new section in sh(1) "Job Control". It probably
needs better wording, but this is (perhaps) better than the nothing that
was there before.
 1.91 23-Oct-2017  kre PR bin/52640 PR bin/52641

Don't delete jobs from the jobs table merely because they finished,
if they are not the job we are waiting upon. (bin/52640 part 1)

In a sub-shell environment, don't allow wait to find jobs from the
parent shell that had already exited (before the sub-shell was
created) and return status for them as if they are our children.
(bin/52640 part 2)

Don't have the "jobs" command also be an implicit "wait" command
in non-interactive shells. (bin/52641)

Use WCONTINUED (when it exists) so we can report on stopped jobs that
"mysteriously" move back to running state without the user issuing
a "bg" command (eg: kill -CONT <pid>) Previously they would keep
being reported as stopped until they exited.

When a job is detected as having changed status just as we're
issuing a "jobs" command (i.e.: the change occurred between the last
prompt and the jobs command being entered) don't report it twice,
once from the status change, and then again in the jobs command
output. Once is enough (keep the jobs output, suppress the other).

Apply some sanity to the way jobs_invalid is processed - ignore it
in getjob() instead of just ignoring it most of the time there, and
instead always check it before calling getjob() in situations where
we can handle only children of the current shell. This allows the
(totally broken) save/clear/restore of jobs_invalid in jobscmd() to
be done away with (previously an error while in the clear state would
have left jobs_invalid incorrectly cleared - shouldn't have mattered
since jobs_invalid => subshell => error causes exit, but better to be safe).

Add/improve the DEBUG more tracing.

XXX pullup -8
 1.90 19-Oct-2017  kre Re-factor the code that extracts status from exited jobs, avoiding
code duplication, and reducing the size of /bin/sh by a trivial amount.

NFCI.

This is being done now as there are two other changes forthcoming, both
of which benefit - one would result in even more code duplication without
this, the other might need to alter how this is done, and doing it after this
means there's just one place to change (if required).
 1.89 29-Sep-2017  kre DEBUG only changes (non-debug, ie: normal, shell unaffected)
Add a little extra info in a few of the trace messages.
 1.88 24-Jul-2017  kre Implement the "pipefail" option (same semantics as in other shells)
to cause (when set, which it is not by default) the exit status of a
pipe to be 0 iff all commands in the pipe exited with status 0, and
otherwise, the status of the rightmost command to exit with a non-0
status.

In the doc, while describing this, also reword some of the text about
commands in general, how they are structured, and when they are executed.
 1.87 17-Jun-2017  kre NFC - DEBUG mode only change - convert this to the new TRACE() format.
 1.86 07-Jun-2017  kre A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)

This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)

The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.

This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).

I would not call the results of this perfect yet, but it is close.
 1.85 18-May-2017  kre branches: 1.85.2;

DEBUG mode only change - correctly track internal shell sub-shell nesting
levels for debug output. This change accidentally omitted earlier (only
effect is incorrect nesting levels shown in trace output when the option
to show them is enabled.) NFC for any normal shell build.
 1.84 11-May-2017  kre Avoid truncating the command string saved with background jobs if
one of the words happens to contain ${#var}. (This is the command
string shown by the "jobs" command, and when a background job completes)

While here, undo the LINENO hack when building that string.
And one ot two other foibles...
 1.83 09-May-2017  kre If we are going to permit
! ! pipeline
(And for now the other places where ! is permitted)
we should at least generate the logically correct exit
status:
! ! (exit 5); echo $?
should print 1, not 5. ksh and bosh do it this way - and it makes sense.
bash and the FreeBSD sh echo "5" (as did we until now.)
dash, zsh, yash all enforce the standard syntax, and prohibit this.
 1.82 04-May-2017  kre Implement the ';&' (used instead of ';;') case statement list terminator
which causes fall through the to command list of the following pattern
(wuthout evaluating that pattern). This has been approved for inclusion
in the next major version of the POSIX standard (Issue 8), and is
implemented by most other shells.

Now all form a circle and together attempt to summon the great wizd
in the hopes that his magic spells can transform the poor attempt
at documenting this feature into something rational...
 1.81 03-May-2017  kre Don't forget the ! reserved word exists (node ype NNOT) when displaying
"jobs" output (or other places where the cmd string is shown - like
when reporting status when a background job completes.)

Without this fix, try
! sleep 5 &
jobs
wait
and try not to wonder at the '???" that appears instead of "! sleep 5"
 1.80 29-Apr-2017  kre Keep track of which file descriptors the shell is using for its
own purposes, and move them elsewhere whenever a user redirection
happens to pick the same number. With this we can move the shell
file descriptors back to lower values (be slightly kinder to the kernel)
since we can no longer clash. (Also get rid of a little old unneeded code.)

This also completes the fdflags command, which no longer permits access
to (by way or either obtaining, or changing) the shell's internal fds.
 1.79 07-May-2016  kre branches: 1.79.6;

Slightly improve "jobs" command output in cases where a job includes
embedded background commands or pipelines. (just slightly...)
OK christos@
 1.78 03-May-2016  kre Unbreak build ... again... gcc is insane.
 1.77 03-May-2016  kre PR bin/51114 - print the correct values for >&- and >& N (N > 9)
in output from the "jobs" command (and other places that use the
same routines.)
 1.76 02-May-2016  christos Fix handing of user file descriptors outside the 0..9 range.
Also, move (most of) the shell's internal use fd's to much
higher values (depending upon what ulimit -n allows) so they
are less likely to clash with user supplied fd numbers. A future
patch will (hopefully) avoid this problem completely by dynamically
moving the shell's internal fds around as needed. (From kre@)
 1.75 22-Aug-2015  christos report the signal that wait was interrupted by, which is not always SIGINT
anymore.
 1.74 22-Aug-2015  christos Process pending signals while waiting for a job:
$ cat << EOF > hup.sh
#!/bin/sh
trap 'echo SIGHUP; exit 1' 1
sleep 10000 &
wait
EOF
$ chmod +x ./hup.sh
$ ./hup.sh &
$ kill -HUP %1
 1.73 11-Apr-2014  christos branches: 1.73.2;
PR/48729: Torbj�rn Granlund: Avoid negative index in array ref.
 1.72 26-Jan-2014  christos branches: 1.72.2;
explain why forks fail
 1.71 31-Dec-2012  dsl Add support for '%n' being a shorthand for 'fg %n'.
 1.70 23-Feb-2012  joerg branches: 1.70.2;
Don't use a for-loop with empty body.
 1.69 18-Jun-2011  christos branches: 1.69.2; 1.69.4;
PR/45069: Henning Petersen: Use prototypes from builtins.h .
 1.68 21-Dec-2008  christos branches: 1.68.6;
don't free other jobs when we are specifically using the wait built-in.
 1.67 21-Dec-2008  christos PR/35055: Wada Keiji: wait did not keep the status of terminated jobs as
expected.
 1.66 16-Oct-2008  dholland Wrap declaration of a STATIC function that's only conditionally defined
in a suitable ifdef, so things still compile if STATIC is defined as
"static", which is for some reason not the default.
 1.65 24-Apr-2006  snj It's "its."
 1.64 30-Sep-2005  tv Make slightly more portable without extra conditionals needed:

- Use getpgrp() rather than getpgid(0).
(getpgrp() is already used elsewhere in this same file.)

- Use waitpid(-1, a, b) rather than wait3(a, b, NULL).
 1.63 01-Jun-2005  lukem appease gcc -Wuninitialized
 1.62 18-Dec-2003  christos PR/23786: Robert Nestor: wait command returns the wrong status code. This
seems to be an off-by-one error, since njobs is decremented before we use
it. I hope this does not break the vfork case!
 1.61 27-Nov-2003  dsl 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.60 14-Nov-2003  dsl Add '\n' to "fork failed" trace messages.
 1.59 26-Aug-2003  jmmv s/FD_SETFD/F_SETFD/
 1.58 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.57 27-Jan-2003  christos - use FD_CLOEXEC properly
- move ttyfd to a high fd
suggested by Tim Robbins at FreeBSD.
 1.56 25-Nov-2002  agc Make this compile on some of the more esoteric architectures (e.g. those
which are not i386)
 1.55 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.54 23-Oct-2002  christos From David Laight:

> Also 'jobs' fails in a non-interactive shell.
> In showjobs(), the code that puts the process back into its
> own process group should only be run if the shell is actually
> doing job control - eg if 'mflag' is set.
 1.53 28-Sep-2002  mycroft Revert the previous for now. This is truly gross.
 1.52 28-Sep-2002  mycroft Remove the duplicate setpgid() in forkparent(). The real bug was freeing the
job structure in the child and referencing freed memory.
 1.51 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.50 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.49 27-Sep-2002  mycroft Clean up INTOFF/INTON usage a little -- none of fork{shell,parent,child}()
screw with them now, only their callers.
 1.48 27-Sep-2002  christos off by one in nprocs.
 1.47 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.46 15-May-2002  christos implement noclobber. From Ben Harris, with minor tweaks from me. Two
unimplemented comments to go. Go Ben!
 1.45 10-Apr-2002  christos Try harder to find a tty.
 1.44 03-Apr-2002  christos PR/16174: Matthias Buelow: Job control fails on jobs that fd == 2 does not
point to a tty.

Unfortunately the shell assumed that it could do all process group
handling ioctls to fd=2, but this is not correct. Jobs that redirected
fd=2 would be unable to perform the ioctls and silently fail since
the error reporting channel is fd=2... Instead open /dev/tty set
it to close on exec, and use that instead (like all other shells
do). We don't handle the case where the OS does not provide FD_CLOEXEC
or FIOCLEX, because I am lazy.

While I am there:
- Simplify the code by defining functions for tc{g,s}pgrp when OLD_TTY_DRIVER
is defined.
- make sure that 'sh &' works by stopping itself. Don't kill the shell's
process group, kill the shell itself.
 1.43 22-Mar-2002  christos branches: 1.43.2;
PR/16010: Andreas Gustafsson: wait is not interruptible.
 1.42 12-Mar-2002  simonb In forkshell() don't free the current job. Fixes problem with previous
commit where pipeline commands didn't inherit the correct process group.
Reviewed by Christos.

Change a trace format string arg to use %p instead of %x and a long cast.
 1.41 12-Mar-2002  christos PR/15877: Ed Ravin: make sure that we cleanup enough of the job structure,
in jobfree() so that we don't fail when we use a malloc where free() trashes
freed memory.
 1.40 16-Sep-2001  wiz Spell 'occurred' with two 'r's.
 1.39 13-Sep-2001  assar (waitproc): handle jp == NULL, it happens
 1.38 10-Sep-2001  christos Don't wait with UNTRACED for jobs that have not been started with job control
(i.e. processes started from shell scripts). Fixes problem where kill -STOP'ing
a subprocess of a shell script would cause the shell to proceed to the next
command.
 1.37 13-Jun-2001  lukem fix grammar
 1.36 22-May-2000  elric Back out previous vfork changes.
 1.35 15-May-2000  elric INTON and FORCEINTON modify global variables, and so should not be
executed while we are vforked.
 1.34 13-May-2000  elric Unused variable pgrp on line 576.
 1.33 13-May-2000  elric Now we use vfork(2) instead of fork(2) when we can.
 1.32 31-Aug-1999  mycroft It turns out that the code disabled in revision 1.30 *does* have an important
function (which nobody was able to explain): it's critical to allowing a
complex command run from an interactive shell to be terminated. So, reinstate
it and fix it correctly. See the comment if you really want the gory details.
 1.31 09-Jul-1999  christos compile with WARNS = 2
 1.30 05-Apr-1999  mycroft Disable bogus-looking code that cause us to throw away SIGINTs.
 1.29 04-Feb-1999  christos branches: 1.29.2;
PR/4966: Joel Reicher: Implement <> redirections which are documented in
the man page.
 1.28 28-Jul-1998  mycroft Be more retentive about use of NOTREACHED and noreturn.
 1.27 20-May-1998  christos cast pid's to longs for OS's where this is the case.
 1.26 07-Apr-1998  fair Change a few things to reference /usr/include/paths.h instead of local
references. Fixing the default PATH is a bit more effort.
 1.25 04-Feb-1998  thorpej Sigh, have to cast pointer diffs to long.
 1.24 04-Feb-1998  thorpej Fix printf formats so they work on the Alpha.
 1.23 08-Oct-1997  christos branches: 1.23.2;
PR/3662: David Holland: Make /bin/sh use the symbolic macros for wait().
 1.22 04-Jul-1997  christos Fix compiler warnings.
 1.21 11-Jan-1997  tls kill 'register'
 1.20 02-Nov-1996  christos Fix problems that gcc -Wall found (from Todd Miller, OpenBSD)
 1.19 16-Oct-1996  christos PR/2808: Don't include <sgtty.h> unless OLD_TTY_DRIVER is defined.
Remove extraneous newline from error messages.
 1.18 17-Sep-1996  mycroft ioctl(TIOC[GS]PGRP) -> tc[gs]etpgrp()
 1.17 04-Jul-1995  pk branches: 1.17.6;
Relocate pointers after re-allocation of the job table.
 1.16 11-May-1995  christos Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.15 21-Mar-1995  cgd convert to new RCS id conventions.
 1.14 23-Dec-1994  cgd be more careful with casts.
 1.13 04-Dec-1994  cgd from James Jegers <jimj@miller.cs.uwm.edu>: quiet -Wall, and squelch
some of the worst style errors.
 1.12 23-Sep-1994  mycroft Eliminate uses of some obsolete functions.
 1.11 11-Jun-1994  mycroft Add RCS ids.
 1.10 12-May-1994  jtc POSIX.1 changed getpgrp
 1.9 12-May-1994  jtc Use libc's sys_siglist[] instead of building and using our own array of
signal names. (from charles)
 1.8 11-May-1994  jtc sync with 4.4lite
 1.7 06-Aug-1993  mycroft Use sys_signame[].
 1.6 01-Aug-1993  mycroft Add RCS identifiers.
 1.5 02-May-1993  sef Jim "wilson@moria.cygnus.com" Wilson's patches to make C News (and other
things) work.
 1.4 26-Apr-1993  dpassage Removed a cast that was causing another stoopid compile error.
 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.17.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.23.2.1 08-May-1998  mycroft Sync with trunk, per request of christos.
 1.29.2.2 09-Oct-1999  cgd pull up rev 1.32 from trunk (requested by mycroft):
Allow the tty interrupt character (e.g. ^C) to interrupt loops run
in an interactive shell again.
 1.29.2.1 19-Apr-1999  mycroft Pull up rev 1.30:
Disable bogus-looking code that cause us to throw away SIGINTs.
 1.43.2.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.68.6.1 23-Jun-2011  cherry Catchup with rmind-uvmplock merge.
 1.69.4.2 15-Nov-2015  bouyer Pull up following revision(s) (requested by christos in ticket #1323):
bin/sh/jobs.c: revision 1.74
bin/sh/jobs.c: revision 1.75
bin/sh/trap.c: revision 1.36
bin/sh/trap.c: revision 1.37
bin/sh/trap.h: revision 1.21
bin/sh/trap.h: revision 1.22
Process pending signals while waiting for a job:
$ cat << EOF > hup.sh
#!/bin/sh
trap 'echo SIGHUP; exit 1' 1
sleep 10000 &
wait
EOF
$ chmod +x ./hup.sh
$ ./hup.sh &
$ kill -HUP %1
report the signal that wait was interrupted by, which is not always SIGINT
anymore.
 1.69.4.1 07-Dec-2014  martin Pullup the following revisions, requested by spz in #1205:
src/bin/sh/jobs.c 1.73

PR/48729: Torbj�rn Granlund: Avoid negative index in array ref.
 1.69.2.3 22-May-2014  yamt sync with head.

for a reference, the tree before this commit was tagged
as yamt-pagecache-tag8.

this commit was splitted into small chunks to avoid
a limitation of cvs. ("Protocol error: too many arguments")
 1.69.2.2 23-Jan-2013  yamt sync with head
 1.69.2.1 17-Apr-2012  yamt sync with head
 1.70.2.2 19-Aug-2014  tls Rebase to HEAD as of a few days ago.
 1.70.2.1 25-Feb-2013  tls resync with head
 1.72.2.1 10-Aug-2014  tls Rebase.
 1.73.2.1 04-Nov-2015  riz Pull up following revision(s) (requested by christos in ticket #964):
bin/sh/jobs.c: revision 1.74
bin/sh/jobs.c: revision 1.75
bin/sh/trap.c: revision 1.36
bin/sh/trap.c: revision 1.37
bin/sh/trap.h: revision 1.21
bin/sh/trap.h: revision 1.22
Process pending signals while waiting for a job:
$ cat << EOF > hup.sh
#!/bin/sh
trap 'echo SIGHUP; exit 1' 1
sleep 10000 &
wait
EOF
$ chmod +x ./hup.sh
$ ./hup.sh &
$ kill -HUP %1
report the signal that wait was interrupted by, which is not always SIGINT
anymore.
 1.79.6.3 19-May-2017  pgoyette Resolve conflicts from previous merge (all resulting from $NetBSD
keywork expansion)
 1.79.6.2 11-May-2017  pgoyette Sync with HEAD
 1.79.6.1 02-May-2017  pgoyette Sync with HEAD - tag prg-localcount2-base1
 1.85.2.3 09-Oct-2018  martin Pull up following revision(s) (requested by kre in ticket #1050):

bin/sh/jobs.c: revision 1.101

A change in rev 1.91 interacted badly with the way that showjobs()
worked, preventing $(jobs) (and more usefully $(jobs -p) from
working. Fix that.

XXX pullup -8
 1.85.2.2 17-Nov-2017  martin Pull up following revision(s) (requested by kre in ticket #337):
bin/sh/jobs.c: revision 1.91 (patch)


PR bin/52640 PR bin/52641

Don't delete jobs from the jobs table merely because they finished,
if they are not the job we are waiting upon. (bin/52640 part 1)

In a sub-shell environment, don't allow wait to find jobs from the
parent shell that had already exited (before the sub-shell was
created) and return status for them as if they are our children.
(bin/52640 part 2)

Don't have the "jobs" command also be an implicit "wait" command
in non-interactive shells. (bin/52641)

Use WCONTINUED (when it exists) so we can report on stopped jobs that
"mysteriously" move back to running state without the user issuing
a "bg" command (eg: kill -CONT <pid>) Previously they would keep
being reported as stopped until they exited.
When a job is detected as having changed status just as we're
issuing a "jobs" command (i.e.: the change occurred between the last
prompt and the jobs command being entered) don't report it twice,
once from the status change, and then again in the jobs command
output. Once is enough (keep the jobs output, suppress the other).

Apply some sanity to the way jobs_invalid is processed - ignore it
in getjob() instead of just ignoring it most of the time there, and
instead always check it before calling getjob() in situations where
we can handle only children of the current shell. This allows the
(totally broken) save/clear/restore of jobs_invalid in jobscmd() to
be done away with (previously an error while in the clear state would
have left jobs_invalid incorrectly cleared - shouldn't have mattered
since jobs_invalid => subshell => error causes exit, but better to be safe).

Add/improve the DEBUG more tracing.
 1.85.2.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.98.4.4 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.98.4.3 21-Apr-2020  martin Sync with HEAD
 1.98.4.2 08-Apr-2020  martin Merge changes from current as of 20200406
 1.98.4.1 10-Jun-2019  christos Sync with HEAD
 1.98.2.4 26-Dec-2018  pgoyette Sync with HEAD, resolve a few conflicts
 1.98.2.3 26-Nov-2018  pgoyette Sync with HEAD, resolve a couple of conflicts
 1.98.2.2 30-Sep-2018  pgoyette Ssync with HEAD
 1.98.2.1 06-Sep-2018  pgoyette Sync with HEAD

Resolve a couple of conflicts (result of the uimin/uimax changes)
 1.106.2.2 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
 1.106.2.1 10-Feb-2020  martin Pull up following revision(s) (requested by kre in ticket #684):

bin/sh/jobs.c: revision 1.107
bin/sh/main.c: revision 1.83
bin/sh/main.c: revision 1.84
bin/sh/main.c: revision 1.85

If we are invoked with SIGCHLD ignored, we fail badly, as we assume
that we can always wait(2) for our children, and an ignored SIGCHLD
prevents that. Recent versions of bash can be convinced (due to a
bug most likely) to invoke us that way. Always return SIGCHLD to
SIG_DFL during init - we already prevent scripts from fiddling it.

All ash derived shells apparently have this problem (observed by
Martijn Dekker, and notified on the bash-bug list). Actual issue
diagnosed by Harald van Dijk (same list).

Actually, the issue with bash (in previous) is more likely that the
SIGCHLD is blocked rather than ignored. We want neither. Make sure
SIGCHLD is unblocked as well as SIG_DFL.

XXX pullup -9

bin/sh: Fixes -Werror=shadow causing build breaks.
Conflicting variable name, sigset_t sigs has been renamed to sigset_t mask

Reviewed by: kamil@

Avoid a core dump if a child process that is not one of our
children happens to exit while we are waiting for another child
to exit.

This can happen with code like
sh -c '
sleep 5 &
exec sh -c "sleep 10 & wait !$"
'

when the inner "sh" is waiting for the 10 second sleep to be
done, the 5 second sleep started earlier terminates. It is
a child of our process, as the inner shell is the same process
as the outer one, but not a known child (the inner shell has no
idea what the outer one did before it started).

This was observed in the wild by Martijn Dekker (where the outer
shell was bash but that's irrelevant).

XXX pullup -9
 1.117.2.1 03-Feb-2024  martin Pull up following revision(s) (requested by kre in ticket #577):

bin/sh/jobs.c: revision 1.119

PR bin/57894

For jobs -p for a non-job-control job, avoid just printing 0 (as
there is no process group pid) and instead output what we used to,
the pid of one of the processes in the job (usually the right one!)
 1.122.2.1 02-Aug-2025  perseant Sync with HEAD
 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
 1.11 07-Aug-2003  agc branches: 1.11.98;
Move UCB-licensed code from 4-clause to 3-clause licence.

Patches provided by Joel Baker in PR 22249, verified by myself.
 1.10 07-Oct-2002  christos explain what's breaking with alignments > 16, but no fix yet.
 1.9 04-Oct-2002  christos Rename ALIGN to SHELL_ALIGN and simplify macro so that it does not have side
effects, and add double to it, so that it aligns doubles correctly too. This
is just a workaround to fix the sparc64 problem where ALIGN() is now defined
in some include file to be 16 instead of 8. Thanks to martin for debugging this.
 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.11.98.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.11.98.1 21-Apr-2020  martin Sync with HEAD
 1.18 04-Jun-2017  kre branches: 1.18.6;
If we are going to keep the MAILPATH % hack, then at least do something
rational. Since it isn't documented, what "rational" is is up for
discussion, but what it did before was not it (it was nonsense...).
 1.17 04-Jun-2017  kre Make cd (really) do cd -P, and not just claim that is what it is doing
while doing a half-hearted, broken, partial, version of cd -L instead.
The latter (as the manual says) is not supported, what's more, it is an
abomination, and should never be supported (anywhere.)

Fix the doc so that the pretense that we notice when a path given crosses
a symlink (and turns on printing of the destination directory) is claimed
no more (that used to be true until late Dec 2016, but was changed). Now
the print happens if -o cdprint is set, or if an entry from CDPATH that is
not "" or "." is used (or if the "cd dest repl" cd cmd variant is used.)

Fix CDPATH processing: avoid the magic '%' processing that is used for
PATH and MAILPATH from corrupting CDPATH. The % magic (both variants)
remains undocumented.

Also, don't double the '/' if an entry in PATH or CDPATH ends in '/'
(as in CDPATH=":/usr/src/"). A "cd usr.bin" used to do
chdir("/usr/src//usr.bin"). No more. This is almost invisible,
and relatively harmless, either way....

Also fix a bug where if a plausible destination directory in CDPATH
was located, but the chdir() failed (eg: permission denied) and then
a later "." or "" CDPATH entry succeeded, "print" mode was turned on.
That is:
cd /tmp; mkdir bin
mkdir -p P/bin; chmod 0 P/bin
CDPATH=/tmp/P:
cd bin
would cd to /tmp/bin (correctly) but print it (incorrectly).

Also when in "cd dest replace" mode, if the result of the replacement
generates '-' as the path named, as in:
cd $PWD -
then simply change to '-' (or attempt to, with CDPATH search), rather
than having this being equivalent to "cd -")

Because of these changes, the pwd command (and $PWD) essentially
always acts as pwd -P, even when called as pwd -L (which is still
the default.) That is, even more than it did before.

Also fixed a (kind of minor) mem management error (CDPATH related)
"whosoever shall padvance must stunalloc before repeating" (and the
same for MAILPATH).
 1.16 07-Aug-2003  agc branches: 1.16.90;
Move UCB-licensed code from 4-clause to 3-clause licence.

Patches provided by Joel Baker in PR 22249, verified by myself.
 1.15 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.14 03-Jul-2000  matt include <stdlib.h>, <string.h>, or whatever as appropriate to shut up
gcc 2.96
 1.13 09-Jul-1999  christos compile with WARNS = 2
 1.12 31-Jan-1998  christos Include our local includes after the system's ones.
 1.11 04-Jul-1997  christos branches: 1.11.2;
Fix compiler warnings.
 1.10 11-Jan-1997  tls kill 'register'
 1.9 11-May-1995  christos branches: 1.9.6;
Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.8 21-Mar-1995  cgd convert to new RCS id conventions.
 1.7 04-Dec-1994  cgd from James Jegers <jimj@miller.cs.uwm.edu>: quiet -Wall, and squelch
some of the worst style errors.
 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.9.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.11.2.1 08-May-1998  mycroft Sync with trunk, per request of christos.
 1.16.90.1 05-Jun-2017  snj Pull up following revision(s) (requested by kre in ticket #5):
bin/sh/cd.c: revision 1.48
bin/sh/eval.c: revision 1.141
bin/sh/exec.c: revision 1.48
bin/sh/exec.h: revision 1.25
bin/sh/mail.c: revisions 1.17, 1.18
bin/sh/sh.1: revision 1.147
Make cd (really) do cd -P, and not just claim that is what it is doing
while doing a half-hearted, broken, partial, version of cd -L instead.
The latter (as the manual says) is not supported, what's more, it is an
abomination, and should never be supported (anywhere.)
Fix the doc so that the pretense that we notice when a path given crosses
a symlink (and turns on printing of the destination directory) is claimed
no more (that used to be true until late Dec 2016, but was changed). Now
the print happens if -o cdprint is set, or if an entry from CDPATH that is
not "" or "." is used (or if the "cd dest repl" cd cmd variant is used.)
Fix CDPATH processing: avoid the magic '%' processing that is used for
PATH and MAILPATH from corrupting CDPATH. The % magic (both variants)
remains undocumented.
Also, don't double the '/' if an entry in PATH or CDPATH ends in '/'
(as in CDPATH=":/usr/src/"). A "cd usr.bin" used to do
chdir("/usr/src//usr.bin"). No more. This is almost invisible,
and relatively harmless, either way....
Also fix a bug where if a plausible destination directory in CDPATH
was located, but the chdir() failed (eg: permission denied) and then
a later "." or "" CDPATH entry succeeded, "print" mode was turned on.
That is:
cd /tmp; mkdir bin
mkdir -p P/bin; chmod 0 P/bin
CDPATH=/tmp/P:
cd bin
would cd to /tmp/bin (correctly) but print it (incorrectly).
Also when in "cd dest replace" mode, if the result of the replacement
generates '-' as the path named, as in:
cd $PWD -
then simply change to '-' (or attempt to, with CDPATH search), rather
than having this being equivalent to "cd -")
Because of these changes, the pwd command (and $PWD) essentially
always acts as pwd -P, even when called as pwd -L (which is still
the default.) That is, even more than it did before.
Also fixed a (kind of minor) mem management error (CDPATH related)
"whosoever shall padvance must stunalloc before repeating" (and the
same for MAILPATH).
--
If we are going to keep the MAILPATH % hack, then at least do something
rational. Since it isn't documented, what "rational" is is up for
discussion, but what it did before was not it (it was nonsense...).
 1.18.6.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.18.6.1 21-Apr-2020  martin Sync with HEAD
 1.10 07-Aug-2003  agc branches: 1.10.98;
Move UCB-licensed code from 4-clause to 3-clause licence.

Patches provided by Joel Baker in PR 22249, verified by myself.
 1.9 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.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.10.98.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.10.98.1 21-Apr-2020  martin Sync with HEAD
 1.90 07-Apr-2023  kre The great shell trailing whitespace cleanup of 2023...
Inspired by private e-mail comments from mouse@

NFCI.
 1.89 18-Sep-2022  kre Add the -l option (aka -o login): be a login shell. Meaningful only on
the command line (with both - and + forms) - overrides the presence (or
otherwise) of a '-' as argv[0][0].

Since this allows any shell to be a login shell (which simply means that
it runs /etc/profile and ~/.profile at shell startup - there are no other
side effects) add a new, always set at startup, variable NBSH_INVOCATION
which has a char string as its value, where each char has a meaning,
more or less related to how the shell was started. See sh(1).
This is intended to allow those startup scripts to tailor their behaviour
to the nature of this particular login shell (it is possible to detect
whether a shell is a login shell merely because of -l, or whether it would
have been anyway, before the -l option was added - and more). The
var could also be used to set different values for $ENV for different
uses of the shell.
 1.88 26-Oct-2021  kre Use a type-correct end marker for strstrcat() rather than NULL, as
for a function with unknown number & types of args, the compiler isn't
able to automatically convert to the correct type. Issue pointed out
in off list e-mail by Rolland Illig ... Thanks.

The first arg (pointer to where to put length of result) is of a known
type, so doesn't have the same issue - we can keep using NULL for that
one when the length isn't needed.

Also, make sure to return a correctly null terminated null string in
the (absurd) case that there are no non-null args to strstrcat() (though
there are much better ways to generate "" on the stack). Since there is
currently just one call in the code, and it has real string args, this
isn't an issue for now, but who knows, some day.

NFCI - if there is any real change, then it is a change that is required.

XXX pullup -9 (together with the previous changes)
 1.87 26-Oct-2021  kre PR bin/56464

After almost 30 years, finally do the right thing and read $HOME/.profile
rather than .profile in the initial directory (it was that way in version
1.1 ...) All other ash descendants seem to have fixed this long ago.

While here, copy a feature from FreeBSD which allows "set +p" (if a
shell run by a setuid process with the -p flag is privileged) to reset
the privileges. Once done (the set +p) it cannot be undone (a later
set -p sets the 'p' flag, but that's all it does) - that just becomes a
one bit storage location.

We do this, as (also copying from FreeBSD, and because it is the right
thing to do) we don't run .profile in a privileged shell - FreeBSD run
/etc/suid_profile in that case (not a good name, it also applies to setgid
shells) but I see no real need for that, we run /etc/profile in any case,
anything that would go in /etc/suid_profile can just go in /etc/profile
instead (with suitable guards so the commands only run in priv'd shells).

One or two minor DEBUG mode changes (notably having priv'd shells identify
themselves in the DEBUG trace) and sh.1 changes with doc of the "set +p"
change, the effect that has on $PSc and a few other wording tweaks.

XXX pullup -9 (not -8, this isn't worth it for the short lifetime
that has left - if it took 28+ years for anyone to notice this, it
cannot be having all that much effect).
 1.86 15-Sep-2021  kre Improve the solution for the 2nd access to a fd which shouldn't
be available ("13") issue reported by Jan Schaumann on netbsd-users.

This fixes a bug in the earlier fix (a day or so ago) which could allow the
shell's idea of which fd range was in use by the script to get wildly
incorrect, but now also actually looks to see which fd's are in use as
renamed other user fd's during the lifetime of a redirection which needs
to be able to be undone (most redirections occur after a fork and are
permanent in the child process). Attempting to access such a fd (as with
attempts to access a fd in use by the shell for its own purposes) is treated
as an attempt to access a closed fd (EBADF). Attempting to reuse the fd
for some other purpose (which should be rare, even for scripts attempting
to cause problems, since the shell generally knows which fds the script
wants to use, and avoids them) will cause the renamed (renumbered) fd
to be renamed again (moved aside to some other available fd), just as
happens with the shell's private fds.

Also, when a generic fd is required, don't give up because of EMFILE
or similar unless there are no available fds at all (we might prefer >10
or bigger, but if there are none there, use anything). This avoids
redirection errors when ulimit -n has been set small, and all the fds >10
that are available have been used, but we need somewhere to park the old
user of a fd while we reuse that fd for the redirection.
 1.85 07-Feb-2020  fox bin/sh: Fixes -Werror=shadow causing build breaks.

Conflicting variable name, sigset_t sigs has been renamed to sigset_t mask

Reviewed by: kamil@
 1.84 06-Feb-2020  kre Actually, the issue with bash (in previous) is more likely that the
SIGCHLD is blocked rather than ignored. We want neither. Make sure
SIGCHLD is unblocked as well as SIG_DFL.

XXX pullup -9
 1.83 06-Feb-2020  kre If we are invoked with SIGCHLD ignored, we fail badly, as we assume
that we can always wait(2) for our children, and an ignored SIGCHLD
prevents that. Recent versions of bash can be convinced (due to a
bug most likely) to invoke us that way. Always return SIGCHLD to
SIG_DFL during init - we already prevent scripts from fiddling it.

All ash derived shells apparently have this problem (observed by
Martijn Dekker, and notified on the bash-bug list). Actual issue
diagnosed by Harald van Dijk (same list).
 1.82 09-Feb-2019  kre branches: 1.82.2;

When an interactive shell exits due to an EOF on stdin, send a newline
to stderr (to follow the previous prompt) and cleanup more nicely.
 1.81 04-Feb-2019  kre PR bin/53919

Suppress shell error messages while expanding $ENV (which also causes
errors while expanding $PS1 $PS2 and $PS4 to be suppressed as well).

This allows any random garbage that happens to be in ENV to not
cause noise when the shell starts (which is effectively all it did).

On a parse error (for any of those vars) we also use "" as the result,
which will be a null prompt, and avoid attempting to open any file for ENV.

This does not in any way change what happens for a correctly parsed command
substitution (either when it is executed when permitted for one of the
prompts, or when it is not (which is always for ENV)) and commands run
from those can still produce error output (but shell errors remain suppressed).
 1.80 19-Jan-2019  kre When we exit from running off the end of the input file (which
includes typing ^D) make sure LINENO is set to indicate the last
(actually one past last) line in the input file, rather than
whatever it was set to by the last command that was actually
executed (which could be some line in a function defined in
some other file).

No effect on exit via an explicit exit command - that would already
set the line number correctly.
 1.79 11-Dec-2018  kre PR standards/42829

Implement parameter and arithmetic expansion of $ENV
before using it as the name of a file from which to
read startup commands for the shell. This continues
to happen for all interactive shells, and non-interactive
shells for which the posix option is not set (-o posix).

On any actual error, or if an attempt is made to use
command substitution, then the value of ENV is used
unchanged as the file name.

The expansion complies with POSIX XCU 2.5.3, though that
only requires parameter expansion - arithmetic expansion
is an extension (but for us, it is much easier to do, than
not to do, and it allows some weird stuff, if you're so
inclined....) Note that there is no ~ expansion (use $HOME).
 1.78 03-Dec-2018  kre Cleanup traps a bit - attempt to handle weird uses in traps, such
as traps that issue break/continue/return to cause the loop/function
executing when the trap occurred to break/continue/return, and
generating the correct exit code from the shell including when a
signal is caught, but the trap handler for it exits.

All that from FreeBSD.

Also make
T=$(trap)
work as it is supposed to (also trap -p).

For now this is handled by the same technique as $(jobs) - rather
than clearing the traps in subshells, just mark them invalid, and
then whenever they're invalid, clear them before executing anything
other than the special blessed "trap" command. Eventually we will
handle these using non-subshell command substitution instead (not
creating a subshell environ when the commands in a command-sub alter
nothing in the environment).
 1.77 03-Dec-2018  kre When forking a child shell, arrange for errors/exit to always unwind
to the main handler, rather than wherever the parent shell would go.

nb: not needed for vfork(), after vfork() we never go that path - which
is good or we'd be corrupting the parent's handler.

This allows the child to always exit (when it should) rather than being
caught up doing something else (and while it would eventually exit, the
status would be incorrect in some cases).

One test is:
sh -c 'trap "(! :) && echo BUG || echo nobug" EXIT'
from Martijn Dekker

Fix from FreeBSD (missed earlier).

XXX - 2b part of the 48875 pullup to -8
 1.76 22-Aug-2018  kre Fix (hopefully) the problem reported on current-users by Patrick Welche.
we had incorrect usage of setstackmark()/popstackmark()

There was an ancient idiom (imported from CSRG in 1993) where code
can do:
setstackmark(&smark); loop until whatever condition {
/* do lots of code */ popstackmark(&smark);
} popstackmark(&smark);

The 1st (inner) popstackmark() resets the stack, conserving memory,
The 2nd one is needed just in case the "whatever condition" was never
true, and the first one was never executed.

This is (was) safe as all popstackmark() did was reset the stack.
That could be done over and over again with no harm.

That is, until 2000 when a fix from FreeBSD for another problem was
imported. That connected all the stack marks as a list (so they can be
located). That caused the problem, as the idiom was not changed, now
there is this list of marks, and popstackmark() was removing an entry.

It rarely (never?) caused any problems as the idiom was rarely used
(the shell used to do loops like above, mostly, without the inner
popstackmark()). Further, the stack mark list is only ever used when
a memory block is realloc'd.

That is, until last weekend - with the recent set of changes.

Part of that copied code from FreeBSD introduced the idiom above
into more functions - functions used much more, and with a greater
possibility of stack marks being set on blocks that are realloc'd
and so cause the problem. In the FreeBSD code, they changed the idiom,
and always do a setstackmark() immediately after the inner popstackmark().
But not for reasons related to a list of stack marks, as in the
intervening period, FreeBSD deleted that, but for another reason.

We do not have their issue, and I did not believe that their
updated idiom was needed (I did some analysis of exactly this issue -
just missed the important part!), and just continued using the old one.
Hence Patrick's core dump....

The solution used here is to split popstackmark() into 2 halves,
popstackmark() continues to do what it has (recently) done,
but is now implemented as a call of (a new func) rststackmark()
which does all the original work of popstackmark - but not removing
the entry from the stack mark list (which remains in popstackmark()).
Then in the idiom above, the inner popstackmark() turns into a call of
rststackmark() so the stack is reset, but the stack mark list is
unchanged. Tail recursion elimination makes this essentially free.
 1.75 19-Aug-2018  kre PR bin/48875 (is related, and ameliorated, but not exactly "fixed")

Import a whole set of tree evaluation enhancements from FreeBSD.

With these, before forking, the shell predicts (often) when all it will
have to do after forking (in the parent) is wait for the child and then
exit with the status from the child, and in such a case simply does not
fork, but rather allows the child to take over the parent's role.

This turns out to handle the particular test case from PR bin/48875 in
such a way that it works as hoped, rather than as it did (the delay there
was caused by an extra copy of the shell hanging around waiting for the
background child to complete ... and keeping the command substitution
stdout open, so the "real" parent had to wait in case more output appeared).

As part of doing this, redirection processing for compound commands gets
moved out of evalsubshell() and into a new evalredir(), which allows us
to properly handle errors occurring while performing those redirects,
and not mishandle (as in simply forget) fd's which had been moved out
of the way temporarily.

evaltree() has its degree of recursion reduced by making it loop to
handle the subsequent operation: that is instead of (for any binop
like ';' '&&' (etc)) where it used to
evaltree(node->left);
evaltree(node->right);
return;
it now does (kind of)
next = node;
while ((node = next) != NULL) {
next = NULL;

if (node is a binary op) {
evaltree(node->left);
if appropriate /* if && test for success, etc */
next = node->right;
continue;
}
/* similar for loops, etc */
}
which can be a good saving, as while the left side (now) tends to be
(usually) a simple (or simpleish) command, the right side can be many
commands (in a command sequence like a; b; c; d; ... the node at the
top of the tree will now have "a" as its left node, and the tree for
b; c; d; ... as its right node - until now everything was evaluated
recursively so it made no difference, and the tree was constructed
the other way).

if/while/... statements are done similarly, recurse to evaluate the
condition, then if the (or one of the) body parts is to be evaluated,
set next to that, and loop (previously it recursed).

There is more to do in this area (particularly in the way that case
statements are processed - we can avoid recursion there as well) but
that can wait for another day.

While doing all of this we keep much better track of when the shell is
just going to exit once the current tree is evaluated (with a new
predicate at_eof() to tell us that we have, for sure, reached the end
of the input stream, that is, this shell will, for certain, not be reading
more command input) and use that info to avoid unneeded forks. For that
we also need another new predicate (have_traps()) to determine of there
are any caught traps which might occur - if there are, we need to remain
to (potentially) handle them, so these optimisations will not occur (to
make the issue in PR 48875 appear again, run the same code, but with a
trap set to execute some code when a signal (or EXIT) occurs - note that
the trap must be set in the appropriate level of sub-shell to have this
effect, any caught traps are cleared in a subshell whenever one is created).

There is still work to be done to handle traps properly, whatever
weirdness they do (some of which is related to some of this.)

These changes do not need man page updates, but 48875 does - an update
to sh.1 will be forthcoming once it is decided what it should say...

Once again, all the heavy lifting for this set of changes comes directly
(with thanks) from the FreeBSD shell.

XXX pullup-8 (but not very soon)
 1.74 19-Aug-2018  kre PR bin/48875

Revert the changes that were made 19 May 2016 (principally eval.c 1.125)
and the bug fixes in subsequent days (eval.c 1.126 and 1.127) and also
update some newer code that was added more recently which acted in
accordance with those changes (make that code be as it would have been
if the changes now being reverted had never been made).

While the changes made did solve the problem, in a sense, they were
never correct (see the PR for some discussion) and it had always been
intended that they be reverted. However, in practical sh code, no
issues were reported - until just recently - so nothing was done,
until now...

After this commit, the validate_fn_redirects test case of the sh ATF
test t_redir will fail. In particular, the subtest of that test
case which is described in the source (of the test) as:
This one is the real test for PR bin/48875
will fail.

Alternative changes, not to "fix" the problem in the PR, but to
often avoid it will be coming very soon - after which that ATF
test will succeed again.

XXX pullup-8
 1.73 23-Jan-2018  sevan branches: 1.73.2; 1.73.4;
drop main() prototype
 1.72 05-Jul-2017  kre DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
 1.71 19-Jun-2017  kre Correct the initial line number used for processing -c arg strings.

(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
 1.70 29-May-2017  kre branches: 1.70.2;

More DEBUG mode changes. As usual, read the source if you care.
 1.69 18-May-2017  kre NFC: added a minor comment (and enev then, in DEBUG code only)
 1.68 22-Apr-2017  kre branches: 1.68.2;

Keep track of the biggest fd used by, or available to, the user/script
and use that to control which fd's are examined by a (bare) fdflags
(with no fd args).

Usually this will mean that fdflags will no longer show the shell's
internal use fds, only user fds.

This is only a partial fix however, a user can easily discover the
shell's fd usage (eg: using fstat) and can then still use fdflags to
manipulate those fds (or even send output to them).

The shell needs to monitor its own fd usage better, and keep out of
the way of user fds - coming sometime later...
 1.67 09-May-2016  kre branches: 1.67.2;

PR bin/48875 - avoid holding (replaced) file descriptors open when running a
command in the current shell (so they can be restored for the next command)
in cases where it is obvious that there is not going to be a following
command to use them. This fixes the problem reported in the PR (though
there are still plenty of situations where a FD could be closed but isn't,
we do not do full fd flow eveluation to determine whether a fd will be
used or not).

This is the change that was just committed and then backed out again...

OK christos@
 1.66 09-May-2016  kre Revert previous. These changes are intended to get made (and will
be in a minute or two) but not as part of that commit... The log
entry certainly does not apply.
 1.65 09-May-2016  kre Finish the fd reassignment fixes from 1.43 and 1.45 ... if we are moving
a fd to an unspecified high fd number, we certainly do not want to hand
that high fd off to other processes after an exec, so always set close-on-exec
on the result (even if lack of fd's means no fd alteration happens.)
This will (eventually) allow some other code that sets close-on-exec to
be removed, but for now, doing it twice won't hurt. Also, in a N>&M
type redirection, do not set close-on-exec if we don't want it.

OK christos@
 1.64 31-Mar-2016  christos Implement the NETBSD_SHELL readonly unexportable unimportable
variable (with its current value set at 20160401) as discussed on
current-users and tech-userlevel. This also includes the necessary
support to implement it properly (particularly the unexportable
part) and adds options to the export command to support unexportable
variables. Also implement the "posix" option (no single letter
equivalent) which gets its default value from whether or not
POSIXLY_CORRECT is set in the environment when the shell starts
(but can be changed just like any other option using -o and +o on
the command line, or the set builtin command.) While there, fix
all uses of options so it is possible to have options that have a
short (one char) name, and no long name, just as it has been possible
to have options with a long name and no short name, though there
are currently none (with no long name). For now, the only use of
the posix option is to control whether ${ENV} is read at startup
by a non-interactive shell, so changing it with set is not usful
- that might change in the future. (from kre@)
 1.63 27-Mar-2016  christos General KNF and source code cleanups, avoid scattering the
magic string " \t\n" all over the place, slightly improved
syntax error messages, restructured some of the code for
clarity, don't allow IFS to be imported through the environment,
and remove the (never) conditionally compiled ATTY option.
Apart from one or two syntax error messages, and ignoring IFS
if present in the environment, this is intended to have no
user visible changes. (from kre@)
 1.62 01-Mar-2016  martin Fix wrong condition in previous causing bogus 'Use "exit" to leave
shell.' messages (from kre)
 1.61 29-Feb-2016  christos Complete implementation of the noexec option (-n) including
disabling noexec, if the shell is interactive, each time that
a new command is about to be read. Also correct the -I
(ignoreeof) option so that it only applies to interactive shells,
as required by posix. (from kre)
 1.60 27-Feb-2016  christos Improve debugging, from kre (I hooked it to the build).
 1.59 26-May-2015  christos Drop privileges when executed set{u,g}id unless -p is specified like other
shells do to avoid system() and popen() abuse.
 1.58 31-May-2014  christos PR/48843: Jarmo Jaakkola: dot commands mess up scope nesting tracking

Evaluation of commands goes completely haywire if a file containing
a break/continue/return command outside its "intended" scope is sourced
using a dot command inside its "intended" scope. The main symptom is
not exiting from the sourced file when supposed to, leading to evaluation
of commands that were not supposed to be evaluated. A secondary symptom
is that these extra commands are not evaluated correctly, as some of them
are skipped. Some examples are listed in the How-To-Repeat section.

According to the POSIX standard, this is how it should work:
dot:
The shell shall execute commands from the file in the current
environment.
break:
The break utility shall exit from the smallest enclosing for, while,
or until loop, [...]
continue:
The continue utility shall return to the top of the smallest
enclosing for, while, or until loop, [...]
return:
The return utility shall cause the shell to stop executing
the current function or dot script. If the shell is not currently
executing a function or dot script, the results are unspecified.

It is clear that return should return from a sourced file, which
it does not do. Whether break and continue should work from the sourced
file might be debatable. Because the dot command says "in the current
environment", I'd say yes. In any case, it should not fail in weird
ways like it does now!

The problems occur with return (a) and break/continue (b) because:
1) dotcmd() does not record the function nesting level prior to
sourcing the file nor does it touch the loopnest variable,
leading to either
2 a) returncmd() being unable to detect that it should not set
evalskip to SKIPFUNC but SKIPFILE, or
b) breakcmd() setting evalskip to SKIPCONT or SKIPBREAK,
leading to
3) cmdloop() not detecting that it should skip the rest of
the file, due to only checking for SKIPFILE.
The result is that cmdloop() keeps executing lines from the file
whilst evalskip is set, which is the main symptom. Because
evalskip is checked in multiple places in eval.c, the secondary
symptom appears.
>How-To-Repeat:
Run the following script:

printf "break\necho break1; echo break2" >break
printf "continue\necho continue1; echo continue2" >continue
printf "return\necho return1; echo return2" >return

while true; do . ./break; done

for i in 1 2; do . ./continue; done

func() {
. ./return
}
func

No output should be produced, but instead this is the result:
break1
continue1
continue1
return1

The main symptom is evident from the unexpected output and the secondary
one from the fact that there are no lines with '2' in them.
>Fix:
Here is patch to src/bin/sh to fix the above problems. It keeps
track of the function nesting level at the beginning of a dot command
to enable the return command to work properly.

I also changed the undefined-by-standard functionality of the return
command when it's not in a dot command or function from (indirectly)
exiting the shell to being silently ignored. This was done because
the previous way has at least one bug: the shell exits without asking
for confirmation when there are stopped jobs.

Because I read the standard to mean that break and continue should have
an effect outside the sourced file, that's how I implemented it. For what
it's worth, this also seems to be what bash does. Also laziness, because
this way required no changes to loopnesting tracking. If this is not
wanted, it might make sense to move the nesting tracking to the inputfile
stack.

The patch also does some clean-up to reduce the amount of global
variables by moving the dotcmd() and the find_dot_file() functions from
main.c to eval.c and making in_function() a proper function.
 1.57 18-Jun-2011  christos branches: 1.57.8; 1.57.20;
PR/45069: Henning Petersen: Use prototypes from builtins.h .
 1.56 21-Feb-2010  christos branches: 1.56.4;
fix faulty logic in previous change.
 1.55 20-Feb-2010  christos default to the original behavior for $ENV unless POSIXLY_CORRECT is set.
 1.54 17-Feb-2010  christos PR/42828: Richard Hansen: Don't evaluate ${ENV} if not interactive.
http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_05_03
 1.53 18-Jan-2009  lukem fix -Wsign-compare issues
 1.52 16-Oct-2008  dholland Remove unused global variables
 1.51 20-Jul-2008  lukem Remove the \n and tabs from the __COPYRIGHT() strings.
 1.50 10-Oct-2005  christos branches: 1.50.20;
PR/31548: Alexander Rigbo: $PWD not set when shell starts up, before pwd
or cd get executed.
 1.49 15-Jul-2005  christos Only do certain actions when we are trully interactive, not just when we
are connected to a tty:
1. enable editor
2. print directory on directory change.
3. print job messages
 1.48 14-Sep-2003  jmmv Fix crash when DEBUG=2, by opening the log file ASAP. Reviewed by simonb@.
 1.47 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.46 11-Dec-2002  christos PR/19453: Christopher Richards: Call setlocale() in /bin/sh
 1.45 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.44 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.43 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.42 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.41 11-Jun-2001  wiz branches: 1.41.2;
Fix various misspellings of compatible/compatibility.
 1.40 04-Feb-2001  christos remove redundant declarations and nexted externs.
 1.39 01-Nov-2000  christos PR/11283: Hubert Feyrer: random memory corruption executing commands:
Fix from FreeBSD:

growstackblock() sometimes relocates a stack_block considered empty
without properly relocating stack marks referencing that block.
The first call to popstackmark() with the unrelocated stack mark
as argument then causes sh to abort.

Relocating the relevant stack marks seems to solve this problem.

The patch changes the semantics of popstackmark() somewhat. It can
only be called once after a call to setstackmark(), thus cmdloop() in
main.c needs an extra call to setstackmark().
 1.38 22-May-2000  elric branches: 1.38.4;
Back out previous vfork changes.
 1.37 13-May-2000  elric Now we use vfork(2) instead of fork(2) when we can.
 1.36 14-Apr-2000  simonb Include <errno.h> instead of using "extern int errno;".
 1.35 27-Jan-2000  christos Fix bin/9184, bin/9194, bin/9265, bin/9266
Exitcode and negation problems (From Martin Husemann)
 1.34 09-Jul-1999  christos compile with WARNS = 2
 1.33 27-Mar-1999  christos When we execute commands from a shell script, make sure that the signals
are being caught (reported by Alexis Rosen), similar to the -c case.

#!/bin/sh
vi "$@"

^C when the script is running...
 1.32 05-Feb-1999  christos Fix the -c problem differently. We cannot just ignore SIGINT etc, otherwise
we cannot interrupt sh -c <command>
 1.31 04-Feb-1999  christos PR/1788: Shinya Taniguchi: sh -c does not setup signals properly.
[Reminded to me by Alexis Rosen -- thx!]
 1.30 04-Feb-1999  cjs Add -q option, which when used with -v and/or -x, turns off the tracing
during the execution of /etc/profile, .profile and $ENV.
 1.29 02-Feb-1999  itohy The builtin . (dot) command no longer sees the current working directory
even if the specified file is not in the PATH.
This change enforces security and makes it conform to POSIX.

Closes PR #6794.
I thought Christos committed this but not appeared yet. :)

The setstackmark()/popstackmark() pair in dotcmd(), used for freeing
stack storage possibly allocated by find_dot_file(), is redundant for now
since dotcmd() is surrounded by another pair in evalcommand().
This redundancy, however, may help future modifications
(suggested by Christos).
 1.28 28-Jul-1998  mycroft Be more retentive about use of NOTREACHED and noreturn.
 1.27 28-Jul-1998  mycroft Delint.
 1.26 04-Jul-1997  christos Fix compiler warnings.
 1.25 11-Apr-1997  christos Don't call getpwd() because if that fails the shell cannot start. (from scott)
 1.24 16-Oct-1996  christos PR/287: Shell does not exit with 126/127 when permission denied/
command not found. Add extra exception type and generalize
error handling routines to take that exception type. Use
a global variable exerrno to keep the last exec error.
 1.23 19-Nov-1995  christos branches: 1.23.4;
Fix PR/1760, where 'cd -' before any other command could cause a reference
to an uninitialized pointer. Use getcwd() to get the current working directory,
instead of forking /bin/pwd [per Scott's suggestion]
 1.22 11-Sep-1995  christos Fix return builtin to work like it does in ksh:
When not in a function, it skips the rest of the current input file.
Instances of `return' outside function definitions were previously ignored.
What does joe posix have to say about this?
[fixes PR/1444]
 1.21 20-Jul-1995  christos Fix bin/1240, from Dennis Ferguson. the exit builtin with no arguments
should return the exitcode of the previous command but it always returned 0.
 1.20 28-May-1995  christos Fixed bug where
$ cat foo
echo $FOO

$ FOO=1 . ./foo
$ echo $FOO

Did not echo 1 at all. Now variable assignments before sourced scripts
are honored during and after the execution of the script.
 1.19 19-May-1995  christos Changed so that syntax errors (EXERROR) set the exit status to 2,
and commands that are not found set the exit status to 1 like all
other bourne shells.
[It used to be 0 and 2 respectively]
 1.18 11-May-1995  christos Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.17 21-Mar-1995  cgd convert to new RCS id conventions.
 1.16 05-Dec-1994  cgd clean up further. more patches from Jim Jegers
 1.15 04-Dec-1994  cgd from James Jegers <jimj@miller.cs.uwm.edu>: quiet -Wall, and squelch
some of the worst style errors.
 1.14 03-Aug-1994  jtc Don't source the file specified by $ENV if either the real and effective
user IDs or the real and effective group IDs of the process are different.
Thanks to Mark Weaver who pointed this out in PR 262.
 1.13 11-Jun-1994  mycroft branches: 1.13.2;
Add RCS ids.
 1.12 12-May-1994  jtc Include appropriate header files to bring function prototypes into scope.
 1.11 11-May-1994  jtc forgot some include files
 1.10 11-May-1994  jtc integrate NetBSD's path searching for dot files
 1.9 11-May-1994  jtc sync with 4.4lite
 1.8 26-Jan-1994  jtc Removed theo's change to check S_ISLNK() for dot commands. This is
unnecessary, since stat() allready resolves symlinks (and fails, if
the link is broken).
 1.7 25-Jan-1994  deraadt source/$PATH thing for symbolic links too, reportedly
 1.6 25-Jan-1994  deraadt but don't try that for absolute or relative paths
 1.5 25-Jan-1994  deraadt make . (source) command search $PATH as it should. from dkionka@Cadence.COM (Daniel P. Kionka) and fixed by me
 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.13.2.2 18-Aug-1994  mycroft update from trunk
 1.13.2.1 03-Aug-1994  cgd from trunk.
 1.23.4.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.38.4.1 03-Nov-2000  tv Pullup 1.39 [hubertf]:
Fixes PR 11283.
 1.41.2.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.50.20.1 18-Sep-2008  wrstuden Sync with wrstuden-revivesa-base-2.
 1.56.4.1 23-Jun-2011  cherry Catchup with rmind-uvmplock merge.
 1.57.20.1 10-Aug-2014  tls Rebase.
 1.57.8.1 19-Aug-2014  tls Rebase to HEAD as of a few days ago.
 1.67.2.1 26-Apr-2017  pgoyette Sync with HEAD
 1.68.2.1 19-May-2017  pgoyette Resolve conflicts from previous merge (all resulting from $NetBSD
keywork expansion)
 1.70.2.2 25-Aug-2018  martin Pull up following revision(s) (requested by kre in ticket #983):

bin/sh/eval.c: revision 1.158
bin/sh/eval.h: revision 1.21
bin/sh/main.c: revision 1.74

PR bin/48875

Revert the changes that were made 19 May 2016 (principally eval.c 1.125)
and the bug fixes in subsequent days (eval.c 1.126 and 1.127) and also
update some newer code that was added more recently which acted in
accordance with those changes (make that code be as it would have been
if the changes now being reverted had never been made).

While the changes made did solve the problem, in a sense, they were
never correct (see the PR for some discussion) and it had always been
intended that they be reverted. However, in practical sh code, no
issues were reported - until just recently - so nothing was done,
until now...

After this commit, the validate_fn_redirects test case of the sh ATF
test t_redir will fail. In particular, the subtest of that test
case which is described in the source (of the test) as:

This one is the real test for PR bin/48875

will fail.

Alternative changes, not to "fix" the problem in the PR, but to
often avoid it will be coming very soon - after which that ATF
test will succeed again.

XXX pullup-8
 1.70.2.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.73.4.4 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.73.4.3 21-Apr-2020  martin Sync with HEAD
 1.73.4.2 08-Apr-2020  martin Merge changes from current as of 20200406
 1.73.4.1 10-Jun-2019  christos Sync with HEAD
 1.73.2.3 26-Jan-2019  pgoyette Sync with HEAD
 1.73.2.2 26-Dec-2018  pgoyette Sync with HEAD, resolve a few conflicts
 1.73.2.1 06-Sep-2018  pgoyette Sync with HEAD

Resolve a couple of conflicts (result of the uimin/uimax changes)
 1.82.2.2 06-Nov-2021  martin Pull up following revision(s) (requested by kre in ticket #1371):

bin/sh/main.c: revision 1.87
bin/sh/main.c: revision 1.88
bin/sh/memalloc.h: revision 1.20
bin/sh/sh.1: revision 1.235
bin/sh/memalloc.c: revision 1.34
bin/sh/memalloc.c: revision 1.35
bin/sh/memalloc.h: revision 1.19
bin/sh/shell.h: revision 1.31
bin/sh/options.c: revision 1.56

PR bin/56464

After almost 30 years, finally do the right thing and read $HOME/.profile
rather than .profile in the initial directory (it was that way in version
1.1 ...) All other ash descendants seem to have fixed this long ago.
While here, copy a feature from FreeBSD which allows "set +p" (if a
shell run by a setuid process with the -p flag is privileged) to reset
the privileges. Once done (the set +p) it cannot be undone (a later
set -p sets the 'p' flag, but that's all it does) - that just becomes a
one bit storage location.

We do this, as (also copying from FreeBSD, and because it is the right
thing to do) we don't run .profile in a privileged shell - FreeBSD run
/etc/suid_profile in that case (not a good name, it also applies to setgid
shells) but I see no real need for that, we run /etc/profile in any case,
anything that would go in /etc/suid_profile can just go in /etc/profile
instead (with suitable guards so the commands only run in priv'd shells).

One or two minor DEBUG mode changes (notably having priv'd shells identify
themselves in the DEBUG trace) and sh.1 changes with doc of the "set +p"
change, the effect that has on $PSc and a few other wording tweaks.

XXX pullup -9 (not -8, this isn't worth it for the short lifetime
that has left - if it took 28+ years for anyone to notice this, it
cannot be having all that much effect).

Use a type-correct end marker for strstrcat() rather than NULL, as
for a function with unknown number & types of args, the compiler isn't
able to automatically convert to the correct type. Issue pointed out
in off list e-mail by Rolland Illig ... Thanks.

The first arg (pointer to where to put length of result) is of a known
type, so doesn't have the same issue - we can keep using NULL for that
one when the length isn't needed.
Also, make sure to return a correctly null terminated null string in
the (absurd) case that there are no non-null args to strstrcat() (though
there are much better ways to generate "" on the stack). Since there is
currently just one call in the code, and it has real string args, this
isn't an issue for now, but who knows, some day.

NFCI - if there is any real change, then it is a change that is required.

XXX pullup -9 (together with the previous changes)
 1.82.2.1 10-Feb-2020  martin Pull up following revision(s) (requested by kre in ticket #684):

bin/sh/jobs.c: revision 1.107
bin/sh/main.c: revision 1.83
bin/sh/main.c: revision 1.84
bin/sh/main.c: revision 1.85

If we are invoked with SIGCHLD ignored, we fail badly, as we assume
that we can always wait(2) for our children, and an ignored SIGCHLD
prevents that. Recent versions of bash can be convinced (due to a
bug most likely) to invoke us that way. Always return SIGCHLD to
SIG_DFL during init - we already prevent scripts from fiddling it.

All ash derived shells apparently have this problem (observed by
Martijn Dekker, and notified on the bash-bug list). Actual issue
diagnosed by Harald van Dijk (same list).

Actually, the issue with bash (in previous) is more likely that the
SIGCHLD is blocked rather than ignored. We want neither. Make sure
SIGCHLD is unblocked as well as SIG_DFL.

XXX pullup -9

bin/sh: Fixes -Werror=shadow causing build breaks.
Conflicting variable name, sigset_t sigs has been renamed to sigset_t mask

Reviewed by: kamil@

Avoid a core dump if a child process that is not one of our
children happens to exit while we are waiting for another child
to exit.

This can happen with code like
sh -c '
sleep 5 &
exec sh -c "sleep 10 & wait !$"
'

when the inner "sh" is waiting for the 10 second sleep to be
done, the 5 second sleep started earlier terminates. It is
a child of our process, as the inner shell is the same process
as the outer one, but not a known child (the inner shell has no
idea what the outer one did before it started).

This was observed in the wild by Martijn Dekker (where the outer
shell was bash but that's irrelevant).

XXX pullup -9
 1.12 03-Dec-2018  kre When forking a child shell, arrange for errors/exit to always unwind
to the main handler, rather than wherever the parent shell would go.

nb: not needed for vfork(), after vfork() we never go that path - which
is good or we'd be corrupting the parent's handler.

This allows the child to always exit (when it should) rather than being
caught up doing something else (and while it would eventually exit, the
status would be incorrect in some cases).

One test is:
sh -c 'trap "(! :) && echo BUG || echo nobug" EXIT'
from Martijn Dekker

Fix from FreeBSD (missed earlier).

XXX - 2b part of the 48875 pullup to -8
 1.11 18-Jun-2011  christos branches: 1.11.42; 1.11.44;
PR/45069: Henning Petersen: Use prototypes from builtins.h .
 1.10 07-Aug-2003  agc branches: 1.10.52;
Move UCB-licensed code from 4-clause to 3-clause licence.

Patches provided by Joel Baker in PR 22249, verified by myself.
 1.9 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.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.10.52.1 23-Jun-2011  cherry Catchup with rmind-uvmplock merge.
 1.11.44.3 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.11.44.2 21-Apr-2020  martin Sync with HEAD
 1.11.44.1 10-Jun-2019  christos Sync with HEAD
 1.11.42.1 26-Dec-2018  pgoyette Sync with HEAD, resolve a few conflicts
 1.41 07-May-2025  kre Obliterate the global var herefd

For the past several years (since Nov 2021) the global var "herefd"
has led a rather meaningless existence.

It gets statically init'd to -1 (at compile time), and several
times its value is carefully saved, set to -1, then restored later.
(Lots of copying around of -1 going on there!)

The only use of its value was removed in the immediately previous update
to memalloc.c, where it was tested, and if its value were >= 0 ...
(no point mentioning what would happen, since its value is always -1,
since Nov 2021).

Bye bye herefd, it was nice knowing you. May we never meet again.
 1.40 06-May-2025  kre PR bin/59395 Remove some dead code.

Back in Nov 2021, the way here docs were implemented was changed
to fix problem report 53550 and this code can no longer ever
be executed (it is impossible without reintroducing the 53550
problems), so time for it to go.

This will make no functional difference to sh in HEAD,
and wouldn't in -10, if this were worth pulling up there (it isn't).

However, in -9 this code still runs (in the relatively rare cases
that it applies), but is broken, leading to the problem in 59395.
Removing this code, which is just an optimisation, will correct
that problem (for current releases only -9 is affected).

XXX pullup -9 (will fix PR bin/59395)
 1.39 07-Apr-2023  kre branches: 1.39.2;

Remove an end of file trailing blank line that served no purpose.

NFCI
 1.38 07-Apr-2023  kre The great shell trailing whitespace cleanup of 2023...
Inspired by private e-mail comments from mouse@

NFCI.
 1.37 31-May-2022  andvar fix various typos in comments, documentation and messages.
 1.36 10-Apr-2022  andvar fix various typos in comments and output/log messages.
 1.35 26-Oct-2021  kre Use a type-correct end marker for strstrcat() rather than NULL, as
for a function with unknown number & types of args, the compiler isn't
able to automatically convert to the correct type. Issue pointed out
in off list e-mail by Rolland Illig ... Thanks.

The first arg (pointer to where to put length of result) is of a known
type, so doesn't have the same issue - we can keep using NULL for that
one when the length isn't needed.

Also, make sure to return a correctly null terminated null string in
the (absurd) case that there are no non-null args to strstrcat() (though
there are much better ways to generate "" on the stack). Since there is
currently just one call in the code, and it has real string args, this
isn't an issue for now, but who knows, some day.

NFCI - if there is any real change, then it is a change that is required.

XXX pullup -9 (together with the previous changes)
 1.34 26-Oct-2021  kre PR bin/56464

After almost 30 years, finally do the right thing and read $HOME/.profile
rather than .profile in the initial directory (it was that way in version
1.1 ...) All other ash descendants seem to have fixed this long ago.

While here, copy a feature from FreeBSD which allows "set +p" (if a
shell run by a setuid process with the -p flag is privileged) to reset
the privileges. Once done (the set +p) it cannot be undone (a later
set -p sets the 'p' flag, but that's all it does) - that just becomes a
one bit storage location.

We do this, as (also copying from FreeBSD, and because it is the right
thing to do) we don't run .profile in a privileged shell - FreeBSD run
/etc/suid_profile in that case (not a good name, it also applies to setgid
shells) but I see no real need for that, we run /etc/profile in any case,
anything that would go in /etc/suid_profile can just go in /etc/profile
instead (with suitable guards so the commands only run in priv'd shells).

One or two minor DEBUG mode changes (notably having priv'd shells identify
themselves in the DEBUG trace) and sh.1 changes with doc of the "set +p"
change, the effect that has on $PSc and a few other wording tweaks.

XXX pullup -9 (not -8, this isn't worth it for the short lifetime
that has left - if it took 28+ years for anyone to notice this, it
cannot be having all that much effect).
 1.33 09-Feb-2019  kre branches: 1.33.2;

INTON / INTOFF audit and cleanup.

No visible differences expected - there is a remote chance that
some internal lossage may no longer occur in interactive shells
that receive SIGINT (untrapped) at inopportune times, but you would
have had to have been very unlucky to have ever suffered from that.
 1.32 22-Aug-2018  kre Fix (hopefully) the problem reported on current-users by Patrick Welche.
we had incorrect usage of setstackmark()/popstackmark()

There was an ancient idiom (imported from CSRG in 1993) where code
can do:
setstackmark(&smark); loop until whatever condition {
/* do lots of code */ popstackmark(&smark);
} popstackmark(&smark);

The 1st (inner) popstackmark() resets the stack, conserving memory,
The 2nd one is needed just in case the "whatever condition" was never
true, and the first one was never executed.

This is (was) safe as all popstackmark() did was reset the stack.
That could be done over and over again with no harm.

That is, until 2000 when a fix from FreeBSD for another problem was
imported. That connected all the stack marks as a list (so they can be
located). That caused the problem, as the idiom was not changed, now
there is this list of marks, and popstackmark() was removing an entry.

It rarely (never?) caused any problems as the idiom was rarely used
(the shell used to do loops like above, mostly, without the inner
popstackmark()). Further, the stack mark list is only ever used when
a memory block is realloc'd.

That is, until last weekend - with the recent set of changes.

Part of that copied code from FreeBSD introduced the idiom above
into more functions - functions used much more, and with a greater
possibility of stack marks being set on blocks that are realloc'd
and so cause the problem. In the FreeBSD code, they changed the idiom,
and always do a setstackmark() immediately after the inner popstackmark().
But not for reasons related to a list of stack marks, as in the
intervening period, FreeBSD deleted that, but for another reason.

We do not have their issue, and I did not believe that their
updated idiom was needed (I did some analysis of exactly this issue -
just missed the important part!), and just continued using the old one.
Hence Patrick's core dump....

The solution used here is to split popstackmark() into 2 halves,
popstackmark() continues to do what it has (recently) done,
but is now implemented as a call of (a new func) rststackmark()
which does all the original work of popstackmark - but not removing
the entry from the stack mark list (which remains in popstackmark()).
Then in the idiom above, the inner popstackmark() turns into a call of
rststackmark() so the stack is reset, but the stack mark list is
unchanged. Tail recursion elimination makes this essentially free.
 1.31 22-Jul-2018  kre Minor cleanups to growstackblock(). This should really change
nothing that matters, but might be slightly more robust/complete.
 1.30 17-Jun-2017  kre branches: 1.30.4; 1.30.6;
Many internal memory management type fixes.

PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)

echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)

(Recently added) Problems with ~ expansion fixed (mem management related).

Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)

And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.

Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,

More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.

[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]

More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).

User visible changes:

Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in

cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END

(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)

With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)

POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).

Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
 1.29 15-Feb-2008  matt branches: 1.29.62;
Fix inconsistent definitions
 1.28 07-Aug-2003  agc branches: 1.28.22;
Move UCB-licensed code from 4-clause to 3-clause licence.

Patches provided by Joel Baker in PR 22249, verified by myself.
 1.27 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.26 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.25 07-Oct-2002  christos - it is wrong to put inton/intoff arount ckmalloc(), because the code
around it is the one that does this.
- whitespace fixes.
 1.24 04-Oct-2002  christos Rename ALIGN to SHELL_ALIGN and simplify macro so that it does not have side
effects, and add double to it, so that it aligns doubles correctly too. This
is just a workaround to fix the sparc64 problem where ALIGN() is now defined
in some include file to be 16 instead of 8. Thanks to martin for debugging this.
 1.23 01-Nov-2000  christos PR/11283: Hubert Feyrer: random memory corruption executing commands:
Fix from FreeBSD:

growstackblock() sometimes relocates a stack_block considered empty
without properly relocating stack marks referencing that block.
The first call to popstackmark() with the unrelocated stack mark
as argument then causes sh to abort.

Relocating the relevant stack marks seems to solve this problem.

The patch changes the semantics of popstackmark() somewhat. It can
only be called once after a call to setstackmark(), thus cmdloop() in
main.c needs an extra call to setstackmark().
 1.22 21-Oct-2000  mycroft Wrap malloc() calls with an INTOFF/INTON pair. Fixes PR 8414.
 1.21 31-Jan-1998  christos branches: 1.21.10;
Include our local includes after the system's ones.
 1.20 04-Jul-1997  christos branches: 1.20.2;
Fix compiler warnings.
 1.19 11-Jan-1997  tls kill 'register'
 1.18 16-Oct-1996  christos PR/2808: Remove trailing whitespace (from FreeBSD)
 1.17 20-May-1996  cgd branches: 1.17.2;
Fix growstackblock() 'newlen' calculations:
(1) it needs to be ALIGNed for both halves of the 'if,' and
(2) if you're going to claim that you now have ALIGN(newlen)
bytes left, you should have actually allocated
ALIGN(newlen), rather than just 'newlen' bytes.
 1.16 11-May-1995  christos Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.15 21-Mar-1995  cgd convert to new RCS id conventions.
 1.14 31-Dec-1994  mycroft Fix that last bug in a less expensive way.
 1.13 31-Dec-1994  cgd take two: make grabstackstr() work correctly, in the face of strange filling.
 1.12 30-Dec-1994  mycroft Remove previous misguided change.
 1.11 23-Dec-1994  cgd don't play fast and loose with memory block allcation. try to allocate
in more-round sizes, but realize that not everybody will fill them up
exactly.
 1.10 04-Dec-1994  cgd from James Jegers <jimj@miller.cs.uwm.edu>: quiet -Wall, and squelch
some of the worst style errors.
 1.9 23-Sep-1994  mycroft Eliminate uses of some obsolete functions.
 1.8 11-Jun-1994  mycroft Add RCS ids.
 1.7 12-May-1994  jtc use prototypes provided by header files instead of our own
 1.6 12-May-1994  jtc Include appropriate header files to bring function prototypes into scope.
 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.17.2.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.20.2.1 08-May-1998  mycroft Sync with trunk, per request of christos.
 1.21.10.2 03-Nov-2000  tv Pullup 1.23 [hubertf]:
Fixes PR 11283.
 1.21.10.1 22-Oct-2000  tv Pullup 1.22 [he]:
Wrap malloc() calls with an INTOFF/INTON pair. Fixes PR 8414.
 1.28.22.1 23-Mar-2008  matt sync with HEAD
 1.29.62.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.30.6.3 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.30.6.2 21-Apr-2020  martin Sync with HEAD
 1.30.6.1 10-Jun-2019  christos Sync with HEAD
 1.30.4.2 06-Sep-2018  pgoyette Sync with HEAD

Resolve a couple of conflicts (result of the uimin/uimax changes)
 1.30.4.1 28-Jul-2018  pgoyette Sync with HEAD
 1.33.2.2 09-May-2025  martin Pull up following revision(s) (requested by kre in ticket #1948):

bin/sh/memalloc.c: revision 1.40

PR bin/59395 Remove some dead code.

Back in Nov 2021, the way here docs were implemented was changed
to fix problem report 53550 and this code can no longer ever
be executed (it is impossible without reintroducing the 53550
problems), so time for it to go.

This will make no functional difference to sh in HEAD,
and wouldn't in -10, if this were worth pulling up there (it isn't).
However, in -9 this code still runs (in the relatively rare cases
that it applies), but is broken, leading to the problem in 59395.

Removing this code, which is just an optimisation, will correct
that problem (for current releases only -9 is affected).
PR bin/59395
 1.33.2.1 06-Nov-2021  martin Pull up following revision(s) (requested by kre in ticket #1371):

bin/sh/main.c: revision 1.87
bin/sh/main.c: revision 1.88
bin/sh/memalloc.h: revision 1.20
bin/sh/sh.1: revision 1.235
bin/sh/memalloc.c: revision 1.34
bin/sh/memalloc.c: revision 1.35
bin/sh/memalloc.h: revision 1.19
bin/sh/shell.h: revision 1.31
bin/sh/options.c: revision 1.56

PR bin/56464

After almost 30 years, finally do the right thing and read $HOME/.profile
rather than .profile in the initial directory (it was that way in version
1.1 ...) All other ash descendants seem to have fixed this long ago.
While here, copy a feature from FreeBSD which allows "set +p" (if a
shell run by a setuid process with the -p flag is privileged) to reset
the privileges. Once done (the set +p) it cannot be undone (a later
set -p sets the 'p' flag, but that's all it does) - that just becomes a
one bit storage location.

We do this, as (also copying from FreeBSD, and because it is the right
thing to do) we don't run .profile in a privileged shell - FreeBSD run
/etc/suid_profile in that case (not a good name, it also applies to setgid
shells) but I see no real need for that, we run /etc/profile in any case,
anything that would go in /etc/suid_profile can just go in /etc/profile
instead (with suitable guards so the commands only run in priv'd shells).

One or two minor DEBUG mode changes (notably having priv'd shells identify
themselves in the DEBUG trace) and sh.1 changes with doc of the "set +p"
change, the effect that has on $PSc and a few other wording tweaks.

XXX pullup -9 (not -8, this isn't worth it for the short lifetime
that has left - if it took 28+ years for anyone to notice this, it
cannot be having all that much effect).

Use a type-correct end marker for strstrcat() rather than NULL, as
for a function with unknown number & types of args, the compiler isn't
able to automatically convert to the correct type. Issue pointed out
in off list e-mail by Rolland Illig ... Thanks.

The first arg (pointer to where to put length of result) is of a known
type, so doesn't have the same issue - we can keep using NULL for that
one when the length isn't needed.
Also, make sure to return a correctly null terminated null string in
the (absurd) case that there are no non-null args to strstrcat() (though
there are much better ways to generate "" on the stack). Since there is
currently just one call in the code, and it has real string args, this
isn't an issue for now, but who knows, some day.

NFCI - if there is any real change, then it is a change that is required.

XXX pullup -9 (together with the previous changes)
 1.39.2.1 02-Aug-2025  perseant Sync with HEAD
 1.21 07-May-2025  kre Obliterate the global var herefd

For the past several years (since Nov 2021) the global var "herefd"
has led a rather meaningless existence.

It gets statically init'd to -1 (at compile time), and several
times its value is carefully saved, set to -1, then restored later.
(Lots of copying around of -1 going on there!)

The only use of its value was removed in the immediately previous update
to memalloc.c, where it was tested, and if its value were >= 0 ...
(no point mentioning what would happen, since its value is always -1,
since Nov 2021).

Bye bye herefd, it was nice knowing you. May we never meet again.
 1.20 26-Oct-2021  kre branches: 1.20.4;
Use a type-correct end marker for strstrcat() rather than NULL, as
for a function with unknown number & types of args, the compiler isn't
able to automatically convert to the correct type. Issue pointed out
in off list e-mail by Rolland Illig ... Thanks.

The first arg (pointer to where to put length of result) is of a known
type, so doesn't have the same issue - we can keep using NULL for that
one when the length isn't needed.

Also, make sure to return a correctly null terminated null string in
the (absurd) case that there are no non-null args to strstrcat() (though
there are much better ways to generate "" on the stack). Since there is
currently just one call in the code, and it has real string args, this
isn't an issue for now, but who knows, some day.

NFCI - if there is any real change, then it is a change that is required.

XXX pullup -9 (together with the previous changes)
 1.19 26-Oct-2021  kre PR bin/56464

After almost 30 years, finally do the right thing and read $HOME/.profile
rather than .profile in the initial directory (it was that way in version
1.1 ...) All other ash descendants seem to have fixed this long ago.

While here, copy a feature from FreeBSD which allows "set +p" (if a
shell run by a setuid process with the -p flag is privileged) to reset
the privileges. Once done (the set +p) it cannot be undone (a later
set -p sets the 'p' flag, but that's all it does) - that just becomes a
one bit storage location.

We do this, as (also copying from FreeBSD, and because it is the right
thing to do) we don't run .profile in a privileged shell - FreeBSD run
/etc/suid_profile in that case (not a good name, it also applies to setgid
shells) but I see no real need for that, we run /etc/profile in any case,
anything that would go in /etc/suid_profile can just go in /etc/profile
instead (with suitable guards so the commands only run in priv'd shells).

One or two minor DEBUG mode changes (notably having priv'd shells identify
themselves in the DEBUG trace) and sh.1 changes with doc of the "set +p"
change, the effect that has on $PSc and a few other wording tweaks.

XXX pullup -9 (not -8, this isn't worth it for the short lifetime
that has left - if it took 28+ years for anyone to notice this, it
cannot be having all that much effect).
 1.18 22-Aug-2018  kre branches: 1.18.2;
Fix (hopefully) the problem reported on current-users by Patrick Welche.
we had incorrect usage of setstackmark()/popstackmark()

There was an ancient idiom (imported from CSRG in 1993) where code
can do:
setstackmark(&smark); loop until whatever condition {
/* do lots of code */ popstackmark(&smark);
} popstackmark(&smark);

The 1st (inner) popstackmark() resets the stack, conserving memory,
The 2nd one is needed just in case the "whatever condition" was never
true, and the first one was never executed.

This is (was) safe as all popstackmark() did was reset the stack.
That could be done over and over again with no harm.

That is, until 2000 when a fix from FreeBSD for another problem was
imported. That connected all the stack marks as a list (so they can be
located). That caused the problem, as the idiom was not changed, now
there is this list of marks, and popstackmark() was removing an entry.

It rarely (never?) caused any problems as the idiom was rarely used
(the shell used to do loops like above, mostly, without the inner
popstackmark()). Further, the stack mark list is only ever used when
a memory block is realloc'd.

That is, until last weekend - with the recent set of changes.

Part of that copied code from FreeBSD introduced the idiom above
into more functions - functions used much more, and with a greater
possibility of stack marks being set on blocks that are realloc'd
and so cause the problem. In the FreeBSD code, they changed the idiom,
and always do a setstackmark() immediately after the inner popstackmark().
But not for reasons related to a list of stack marks, as in the
intervening period, FreeBSD deleted that, but for another reason.

We do not have their issue, and I did not believe that their
updated idiom was needed (I did some analysis of exactly this issue -
just missed the important part!), and just continued using the old one.
Hence Patrick's core dump....

The solution used here is to split popstackmark() into 2 halves,
popstackmark() continues to do what it has (recently) done,
but is now implemented as a call of (a new func) rststackmark()
which does all the original work of popstackmark - but not removing
the entry from the stack mark list (which remains in popstackmark()).
Then in the idiom above, the inner popstackmark() turns into a call of
rststackmark() so the stack is reset, but the stack mark list is
unchanged. Tail recursion elimination makes this essentially free.
 1.17 17-Jun-2017  kre branches: 1.17.4; 1.17.6;
Many internal memory management type fixes.

PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)

echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)

(Recently added) Problems with ~ expansion fixed (mem management related).

Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)

And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.

Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,

More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.

[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]

More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).

User visible changes:

Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in

cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END

(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)

With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)

POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).

Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
 1.16 03-Jun-2017  kre branches: 1.16.2;
Fixes to shell expand (that is, $ stuff) from FreeBSD (implemented
differently...)

In particular ${01} is now $1 not $0 (for ${0any-digits})

${4294967297} is most probably now ""
(unless you have a very large number of params)
it is no longer an alias for $1 (4294967297 & 0xFFFFFFFF) == 1

$(( expr $(( more )) stuff )) is no longer the same as
$(( expr (( more )) stuff )) which was sometimes OK, as in:
$(( 3 + $(( 2 - 1 )) * 3 ))
but not always as in:
$(( 1$((1 + 1))1 ))
which should be 121, but was an arith syntax error as
1((1 + 1))1
is meaningless.

Probably some more. This also sprinkles a little const, splits a big
func that had 2 (kind of unrelated) purposes into two simpler ones,
and avoids some (semi-dubious) modifications (and restores) in the input
string to insert \0's when they were needed.
 1.15 15-Feb-2008  matt Fix inconsistent definitions
 1.14 07-Aug-2003  agc branches: 1.14.22;
Move UCB-licensed code from 4-clause to 3-clause licence.

Patches provided by Joel Baker in PR 22249, verified by myself.
 1.13 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.12 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.11 01-Nov-2000  christos PR/11283: Hubert Feyrer: random memory corruption executing commands:
Fix from FreeBSD:

growstackblock() sometimes relocates a stack_block considered empty
without properly relocating stack marks referencing that block.
The first call to popstackmark() with the unrelocated stack mark
as argument then causes sh to abort.

Relocating the relevant stack marks seems to solve this problem.

The patch changes the semantics of popstackmark() somewhat. It can
only be called once after a call to setstackmark(), thus cmdloop() in
main.c needs an extra call to setstackmark().
 1.10 11-May-1995  christos branches: 1.10.16;
Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.9 21-Mar-1995  cgd convert to new RCS id conventions.
 1.8 31-Dec-1994  mycroft Fix that last bug in a less expensive way.
 1.7 31-Dec-1994  cgd take two: make grabstackstr() work correctly, in the face of strange filling.
 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.10.16.1 03-Nov-2000  tv Pullup 1.11 [hubertf]:
Fixes PR 11283.
 1.14.22.1 23-Mar-2008  matt sync with HEAD
 1.16.2.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.17.6.3 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.17.6.2 21-Apr-2020  martin Sync with HEAD
 1.17.6.1 10-Jun-2019  christos Sync with HEAD
 1.17.4.1 06-Sep-2018  pgoyette Sync with HEAD

Resolve a couple of conflicts (result of the uimin/uimax changes)
 1.18.2.1 06-Nov-2021  martin Pull up following revision(s) (requested by kre in ticket #1371):

bin/sh/main.c: revision 1.87
bin/sh/main.c: revision 1.88
bin/sh/memalloc.h: revision 1.20
bin/sh/sh.1: revision 1.235
bin/sh/memalloc.c: revision 1.34
bin/sh/memalloc.c: revision 1.35
bin/sh/memalloc.h: revision 1.19
bin/sh/shell.h: revision 1.31
bin/sh/options.c: revision 1.56

PR bin/56464

After almost 30 years, finally do the right thing and read $HOME/.profile
rather than .profile in the initial directory (it was that way in version
1.1 ...) All other ash descendants seem to have fixed this long ago.
While here, copy a feature from FreeBSD which allows "set +p" (if a
shell run by a setuid process with the -p flag is privileged) to reset
the privileges. Once done (the set +p) it cannot be undone (a later
set -p sets the 'p' flag, but that's all it does) - that just becomes a
one bit storage location.

We do this, as (also copying from FreeBSD, and because it is the right
thing to do) we don't run .profile in a privileged shell - FreeBSD run
/etc/suid_profile in that case (not a good name, it also applies to setgid
shells) but I see no real need for that, we run /etc/profile in any case,
anything that would go in /etc/suid_profile can just go in /etc/profile
instead (with suitable guards so the commands only run in priv'd shells).

One or two minor DEBUG mode changes (notably having priv'd shells identify
themselves in the DEBUG trace) and sh.1 changes with doc of the "set +p"
change, the effect that has on $PSc and a few other wording tweaks.

XXX pullup -9 (not -8, this isn't worth it for the short lifetime
that has left - if it took 28+ years for anyone to notice this, it
cannot be having all that much effect).

Use a type-correct end marker for strstrcat() rather than NULL, as
for a function with unknown number & types of args, the compiler isn't
able to automatically convert to the correct type. Issue pointed out
in off list e-mail by Rolland Illig ... Thanks.

The first arg (pointer to where to put length of result) is of a known
type, so doesn't have the same issue - we can keep using NULL for that
one when the length isn't needed.
Also, make sure to return a correctly null terminated null string in
the (absurd) case that there are no non-null args to strstrcat() (though
there are much better ways to generate "" on the stack). Since there is
currently just one call in the code, and it has real string args, this
isn't an issue for now, but who knows, some day.

NFCI - if there is any real change, then it is a change that is required.

XXX pullup -9 (together with the previous changes)
 1.20.4.1 02-Aug-2025  perseant Sync with HEAD
 1.57 03-Jul-2025  kre Don't allow read to make use of the shell's internal '='
terminates var names feature (which exists so in things
like "external foo=bar" the shell can simply set the "variable"
"foo=bar" to "bar" and doesn't need to put \0 on top of the '=',
or copy the var name part elsewhere, and other similar internal
advantages) - in most cases either allowing the '=' is intended, (as
in the export example) or other checks make it impossible (${var} etc),
but nothing was checking the var names passed to the read command.

Fix that ... (side effect is that now if an invalid name is
given, it will be detected before anything is read, before a
prompt is written, rather than after the read, when the vars
are being set to the fields from the line read).

Don't bother doing this in SMALL shells, avoid the (small) extra
code bloat - SMALL shells can just treat being able to say
read a b=hello c (which means the same as read a b c)
as a harmless foible...
 1.56 12-Oct-2024  kre Undo an idiotic attempted micro optimisation in the previous
version which broke things...
 1.55 11-Oct-2024  kre Add -b and -nMAX options to the read builtin.

As requested on (perhaps more than one) mailing list, this adds
a -n MAX option, to allow the amount of data read by the read
builtin to be limited to MAX bytes (in case the record delimiter
doesn't appear in the input for a long time). There is
currently an upper bound of 8MiB on the value of MAX.

Also add a -b option, which allows for buffered input (with
some usage caveats) rather than 1 byte at a time.

Neither option exists in SMALL shells.

Note that the proposed -z option got deleted ... I couldn't
find a rational way to explain what the final state would be
if a \0 on input generated an error, so rather than have
things ambiguous, better just not to have the option, and
simply keep ignoring input \0's as always.

See the (updated) sh(1) man page for more details.

No pullups planned (new feature, only for new releases).
 1.54 05-Oct-2023  kre branches: 1.54.2;
If the read builtin is told to read into IFS, we must avoid doing
that until all current uses of IFS are complete (as we have IFS's
value cached in ifs - if IFS alters, ifs might point anywhere).
Handle this by deferring assignments to IFS until everything is done.
This makes us appear to comply with the (currently) proposed requirement
for read by POSIX that field splitting complete before vars are
assigned. (Other shells, like dash, ksh93, yash, bosh behave like this)

That might end up being unspecified though, as other shells (bosh,
mksh) assign each field to its var as it is delimited (though bosh
appears to have bugs). If we wanted to go that route, the issue here
could have been handled by re-doing the init of ifs after every
setvar() that is performed here (except the last, after which it is
no longer needed).

XXX pullup -10
 1.53 11-Dec-2022  kre branches: 1.53.2;

It appears that POSIX intends to add a -d X option to the read command
in its next version, so it can be used as -d '' (to specify a \0 end
character for the record read, rather than the default \n) to accompany
find -print0 and xargs -0 options (also likely to be added).

Add support for -d now. While here fix a bug where escaped nul
chars (\ \0) in non-raw mode were not being dropped, as they are
when not escaped (if not dropped, they're still not used in any
useful way, they just ended the value at that point).
 1.52 19-Aug-2022  kre Don't output the error for bad usage (no var name given)
after already writing the prompt (set with the -p option).

That results in nonsense like:

$ read -p foo
fooread: arg count

While here, improve the error message so it means something.

Now we will get:

$ read -p foo
read: variable name required
Usage: read [-r] [-p prompt] var...

[Detected by code reading while doing the work for the previous fix]
 1.51 19-Aug-2022  kre PR bin/56972 Fix escape ('\') handling in sh read builtin.

In 1.35 (March 2005) (the big read fixup), most escape handling and IFS
processing in the read builtin was corrected. However 2 cases were missed,
one is a word (something to be assigned to any variable but the last) in
which every character is escaped (the code was relying on a non-escaped char
to set the "in a word" status), and second trailing IFS whitespace at
the end of the line was being deleted, even if the chars had been escaped
(the escape chars are no longer present).

See the PR for more details (including the case that detected the problem).

After fixing this, I looked at the FreeBSD code (normally might do it
before, but these fixes were trivial) to check their implementation.
Their code does similar things to ours now does, but in a completely
different way, their read builtin is more complex than ours needs to
be (they handle more options). For anyone tempted to simply incorporate
their code, note that it relies upon infrastructure changes elsewhere
in the shell, so would not be a simple cut and drop in exercise.

This needs pullups to -3 -4 -5 -6 -7 -8 and -9 (fortunately this is
happening before -10 is branched, so will never be broken this way there).
 1.50 16-Apr-2022  kre Redo the way the builtin cmd 'ulimit' getopt() (nextopt() really, but it
is essentially the same) arg string is generated, to lessen the chances
that the table of limits, and the arg string that allows limits to be
reported or set will get out of sync. They weren't (as long as we didn't
grow an RLIMIT_SWAP) this is just tidier.

While here, reorder the limits table fields, and shrink a couple that
were needlessly wasteful, to save some space -- for most architectures
this should save 8 bytes per table entry (there are currently 13).
(Some minor code bloat offsets this slightly because of int type
promotions now required).

NFCI.
 1.49 16-Apr-2022  kre While doing the previous change, I noticed that when used in a
particularly perverse way, the error message for a bad octal
constant as the new umask value could incorrectly claim that the
-S option (which would need to be present to cause this issue)
was the detected bad value. Fix that to report the actual
incorrect arg.

And while fiddling, also check for args to umask that are too big
to be sane mask values (the biggest permitted is 07777) and use
mode_t as the mask variable type, rather than int.
 1.48 16-Apr-2022  kre Avoid generating error messages implying that user errors are illegal.
 1.47 12-Dec-2021  andvar s/Miscelaneous/Miscellaneous/ and s/slahes/slashes/ in comments.
 1.46 16-Nov-2021  kre Detect write errors to stdout, and exit(1) from some built-in
commands which (primarily) are used just to generate output
(or with a particular option combination do so).
 1.45 15-Sep-2021  kre Have the ulimit command watch for ulimit -n (alter number of available fds)
and keep the rest of the shell aware of any changes.

While here, modify 'ulimit -aSH' to print both the soft and hard limits
for the resources, rather than just (in this case, as H comes last) the
hard limit. In any other case when both S and H are present, and we're
examining a limit, use the soft limit (just as if neither were given).

No change for setting limits (both are set, unless exactly one of -H
or -S is given). However, we now check for overflow when converting
the value to be assigned, rather than just truncating the value however
it happens to work out...
 1.44 13-May-2017  gson branches: 1.44.2; 1.44.10; 1.44.12;
Fix inconsistent whitespace
 1.43 09-May-2015  christos branches: 1.43.6;
CID 1225078: check getrlimit return
 1.42 11-Jun-2012  njoly Allow thread limit queries by adding the new -r flag to ulimit. Add
the corresponding documentation in the man page.
 1.41 09-Jun-2012  christos support RLIMIT_NTHR.
 1.40 11-Oct-2011  christos branches: 1.40.2;
print the flag too next to the units like bash does.
 1.39 18-Jun-2011  christos PR/45069: Henning Petersen: Use prototypes from builtins.h .
 1.38 29-Mar-2009  mrg branches: 1.38.4;
- add new RLIMIT_AS (aka RLIMIT_VMEM) resource that limits the total
address space available to processes. this limit exists in most other
modern unix variants, and like most of them, our defaults are unlimited.
remove the old mmap / rlimit.datasize hack.

- adds the VMCMD_STACK flag to all the stack-creation vmcmd callers.
it is currently unused, but was added a few years ago.

- add a pair of new process size values to kinfo_proc2{}. one is the
total size of the process memory map, and the other is the total size
adjusted for unused stack space (since most processes have a lot of
this...)

- patch sh, and csh to notice RLIMIT_AS. (in some cases, the alias
RLIMIT_VMEM was already present and used if availble.)

- patch ps, top and systat to notice the new k_vm_vsize member of
kinfo_proc2{}.

- update irix, svr4, svr4_32, linux and osf1 emulations to support
this information. (freebsd could be done, but that it's best left
as part of the full-update of compat/freebsd.)


this addresses PR 7897. it also gives correct memory usage values,
which have never been entirely correct (since mmap), and have been
very incorrect since jemalloc() was enabled.

tested on i386 and sparc64, build tested on several other platforms.

thanks to many folks for feedback and testing but most espcially
chuq and yamt for critical suggestions that lead to this patch not
having a special ugliness i wasn't happy with anyway :-)
 1.37 28-Dec-2008  christos branches: 1.37.2;
rlim_t will be unsigned as TOG mandates.
 1.36 01-Oct-2005  christos branches: 1.36.26;
fix setmode error handling.
 1.35 19-Mar-2005  dsl Fix the way the 'read' builtin processes IFS. In particular:
- IFS whitespace is now processes correctly,
- Trailing non-whitespace IFS characters are added to the last variable
iff a subsequent variable would have been assigned a non-null string.
Now passes the 'read' tests in http://www.research.att.com/~gsf/public/ifs.sh
 1.34 19-Apr-2004  lukem branches: 1.34.2;
Correct the description of sbsize; it is parsed in bytes not kbytes.
 1.33 17-Apr-2004  christos understand rlimit sbsize
 1.32 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.31 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.30 04-Feb-2001  christos remove redundant declarations and nexted externs.
 1.29 04-Jan-2001  lukem use more standard %ll_ in favour of %q_
 1.28 22-Nov-2000  christos error message cleanup:
- don't print the builtin name twice
- explain why things fail
- no extra newline
 1.27 26-Sep-1998  christos include <stdlib.h> to get the prototype for free()
 1.26 24-Sep-1998  itohy The return value of setmode(3) is a pointer to malloc()'ed area
and must be freed to avoid memory leaks if called repeatedly.
The leaks occured on symbolic umask command, such as "umask go-w",
which is undocumented.
 1.25 20-May-1998  christos Cast is*() args to unsigned chars in case the ctype macros are implemented
using arrays.
 1.24 04-Feb-1998  thorpej Fix printf formats so they work on the Alpha.
 1.23 21-Jan-1998  christos BSD4_4 is a standard symbol in <sys/param.h>; make sure that files
that need this defined, include <sys/param.h> and don't define it in
the Makefile. Add a comment to that effect.
 1.22 16-Jan-1998  christos test for the boundary condition in the previous trailing blank fix
 1.21 15-Jan-1998  christos PR/4805: Ty Sarna: read builtin does not remove trailing blanks.
 1.20 05-Nov-1997  kleink Per 1003.2, the (builtin) read utility shall treat the backslash as an
escape character (including line continuation), unless the `-r' option
is specified:
* adopt to this behaviour, add the `-r' option to disable it;
* remove the `-e' option, which was previously necessary to get this behaviour.
 1.19 04-Jul-1997  christos branches: 1.19.2;
Fix compiler warnings.
 1.18 11-Apr-1997  christos Make this work on systems that don't have quads
 1.17 11-Jan-1997  tls kill 'register'
 1.16 16-Oct-1996  christos PR/2808: Remove trailing whitespace (from FreeBSD)
 1.15 12-Jun-1995  jtc branches: 1.15.6;
Changed type of rlimit values from quad_t to rlim_t. Cast rlim_t's to
quad_t's and use "%qd" in printf.
Eliminated unneccessary conditional.
 1.14 11-May-1995  christos Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.13 21-Mar-1995  cgd convert to new RCS id conventions.
 1.12 05-Dec-1994  cgd clean up further. more patches from Jim Jegers
 1.11 11-Jun-1994  mycroft Add RCS ids.
 1.10 12-May-1994  jtc use prototypes provided by header files instead of our own
 1.9 12-May-1994  jtc Include appropriate header files to bring function prototypes into scope.
 1.8 11-May-1994  jtc integrate NetBSD's POSIX.2 compliant umask builtin
 1.7 11-May-1994  jtc sync with 4.4lite
 1.6 06-Apr-1994  cgd do right right thing if 'read' given no args. ptd out by Geoff Rehmet
 1.5 01-Aug-1993  mycroft Add RCS identifiers.
 1.4 21-Jul-1993  jtc Make umask builtin of shell POSIX 1003.2 compliant:
Print out a symbolic mask with the -S option; and accept symbolic mask
specifications.
 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.15.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.19.2.2 08-May-1998  mycroft Sync with trunk, per request of christos.
 1.19.2.1 06-Nov-1997  mellon Pull rev 1.20 up from trunk (kleink)
 1.34.2.1 07-Apr-2005  tron Pull up revision 1.35 (requested by dsl in ticket #117):
Fix the way the 'read' builtin processes IFS. In particular:
- IFS whitespace is now processes correctly,
- Trailing non-whitespace IFS characters are added to the last variable
iff a subsequent variable would have been assigned a non-null string.
Now passes the 'read' tests in http://www.research.att.com/~gsf/public/ifs.sh
 1.36.26.1 01-Apr-2009  snj Pull up following revision(s) (requested by mrg in ticket #622):
bin/csh/csh.1: revision 1.46
bin/csh/func.c: revision 1.37
bin/ps/print.c: revision 1.111
bin/ps/ps.c: revision 1.74
bin/sh/miscbltin.c: revision 1.38
bin/sh/sh.1: revision 1.92 via patch
external/bsd/top/dist/machine/m_netbsd.c: revision 1.7
lib/libkvm/kvm_proc.c: revision 1.82
sys/arch/mips/mips/cpu_exec.c: revision 1.55
sys/compat/darwin/darwin_exec.c: revision 1.57
sys/compat/ibcs2/ibcs2_exec.c: revision 1.73
sys/compat/irix/irix_resource.c: revision 1.15
sys/compat/linux/arch/amd64/linux_exec_machdep.c: revision 1.16
sys/compat/linux/arch/i386/linux_exec_machdep.c: revision 1.12
sys/compat/linux/common/linux_limit.h: revision 1.5
sys/compat/osf1/osf1_resource.c: revision 1.14
sys/compat/svr4/svr4_resource.c: revision 1.18
sys/compat/svr4_32/svr4_32_resource.c: revision 1.17
sys/kern/exec_subr.c: revision 1.62
sys/kern/init_sysctl.c: revision 1.160
sys/kern/kern_exec.c: revision 1.288
sys/kern/kern_resource.c: revision 1.151
sys/sys/param.h: patch
sys/sys/resource.h: revision 1.31
sys/sys/sysctl.h: revision 1.184
sys/uvm/uvm_extern.h: revision 1.153
sys/uvm/uvm_glue.c: revision 1.136
sys/uvm/uvm_mmap.c: revision 1.128
usr.bin/systat/ps.c: revision 1.32
- - add new RLIMIT_AS (aka RLIMIT_VMEM) resource that limits the total
address space available to processes. this limit exists in most other
modern unix variants, and like most of them, our defaults are unlimited.
remove the old mmap / rlimit.datasize hack.
- - adds the VMCMD_STACK flag to all the stack-creation vmcmd callers.
it is currently unused, but was added a few years ago.
- - add a pair of new process size values to kinfo_proc2{}. one is the
total size of the process memory map, and the other is the total size
adjusted for unused stack space (since most processes have a lot of
this...)
- - patch sh, and csh to notice RLIMIT_AS. (in some cases, the alias
RLIMIT_VMEM was already present and used if availble.)
- - patch ps, top and systat to notice the new k_vm_vsize member of
kinfo_proc2{}.
- - update irix, svr4, svr4_32, linux and osf1 emulations to support
this information. (freebsd could be done, but that it's best left
as part of the full-update of compat/freebsd.)
this addresses PR 7897. it also gives correct memory usage values,
which have never been entirely correct (since mmap), and have been
very incorrect since jemalloc() was enabled.
tested on i386 and sparc64, build tested on several other platforms.
thanks to many folks for feedback and testing but most espcially
chuq and yamt for critical suggestions that lead to this patch not
having a special ugliness i wasn't happy with anyway :-)
 1.37.2.1 13-May-2009  jym Sync with HEAD.

Third (and last) commit. See http://mail-index.netbsd.org/source-changes/2009/05/13/msg221222.html
 1.38.4.1 23-Jun-2011  cherry Catchup with rmind-uvmplock merge.
 1.40.2.1 30-Oct-2012  yamt sync with head
 1.43.6.1 19-May-2017  pgoyette Resolve conflicts from previous merge (all resulting from $NetBSD
keywork expansion)
 1.44.12.1 27-Oct-2022  martin Pull up following revision(s) (requested by kre in ticket #1549):

bin/sh/miscbltin.c: revision 1.51
bin/sh/miscbltin.c: revision 1.52

PR bin/56972 Fix escape ('\') handling in sh read builtin.

In 1.35 (March 2005) (the big read fixup), most escape handling and IFS
processing in the read builtin was corrected. However 2 cases were missed,
one is a word (something to be assigned to any variable but the last) in
which every character is escaped (the code was relying on a non-escaped char
to set the "in a word" status), and second trailing IFS whitespace at
the end of the line was being deleted, even if the chars had been escaped
(the escape chars are no longer present).

See the PR for more details (including the case that detected the problem).

After fixing this, I looked at the FreeBSD code (normally might do it
before, but these fixes were trivial) to check their implementation.

Their code does similar things to ours now does, but in a completely
different way, their read builtin is more complex than ours needs to
be (they handle more options). For anyone tempted to simply incorporate
their code, note that it relies upon infrastructure changes elsewhere
in the shell, so would not be a simple cut and drop in exercise.

This needs pullups to -3 -4 -5 -6 -7 -8 and -9 (fortunately this is
happening before -10 is branched, so will never be broken this way there).

-

Don't output the error for bad usage (no var name given)
after already writing the prompt (set with the -p option).

That results in nonsense like:
$ read -p foo
fooread: arg count

While here, improve the error message so it means something.

Now we will get:
$ read -p foo
read: variable name required
Usage: read [-r] [-p prompt] var...

[Detected by code reading while doing the work for the previous fix]
 1.44.10.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.44.10.1 21-Apr-2020  martin Sync with HEAD
 1.44.2.1 27-Oct-2022  martin Pull up following revision(s) (requested by kre in ticket #1779):

bin/sh/miscbltin.c: revision 1.51
bin/sh/miscbltin.c: revision 1.52

PR bin/56972 Fix escape ('\') handling in sh read builtin.

In 1.35 (March 2005) (the big read fixup), most escape handling and IFS
processing in the read builtin was corrected. However 2 cases were missed,
one is a word (something to be assigned to any variable but the last) in
which every character is escaped (the code was relying on a non-escaped char
to set the "in a word" status), and second trailing IFS whitespace at
the end of the line was being deleted, even if the chars had been escaped
(the escape chars are no longer present).

See the PR for more details (including the case that detected the problem).

After fixing this, I looked at the FreeBSD code (normally might do it
before, but these fixes were trivial) to check their implementation.

Their code does similar things to ours now does, but in a completely
different way, their read builtin is more complex than ours needs to
be (they handle more options). For anyone tempted to simply incorporate
their code, note that it relies upon infrastructure changes elsewhere
in the shell, so would not be a simple cut and drop in exercise.

This needs pullups to -3 -4 -5 -6 -7 -8 and -9 (fortunately this is
happening before -10 is branched, so will never be broken this way there).

-

Don't output the error for bad usage (no var name given)
after already writing the prompt (set with the -p option).

That results in nonsense like:
$ read -p foo
fooread: arg count

While here, improve the error message so it means something.

Now we will get:
$ read -p foo
read: variable name required
Usage: read [-r] [-p prompt] var...

[Detected by code reading while doing the work for the previous fix]
 1.53.2.1 03-Nov-2023  martin Pull up following revision(s) (requested by kre in ticket #454):

bin/sh/miscbltin.c: revision 1.54

If the read builtin is told to read into IFS, we must avoid doing
that until all current uses of IFS are complete (as we have IFS's
value cached in ifs - if IFS alters, ifs might point anywhere).
Handle this by deferring assignments to IFS until everything is done.

This makes us appear to comply with the (currently) proposed requirement
for read by POSIX that field splitting complete before vars are
assigned. (Other shells, like dash, ksh93, yash, bosh behave like this)

That might end up being unspecified though, as other shells (bosh,
mksh) assign each field to its var as it is delimited (though bosh
appears to have bugs). If we wanted to go that route, the issue here
could have been handled by re-doing the init of ifs after every
setvar() that is performed here (except the last, after which it is
no longer needed).
 1.54.2.1 02-Aug-2025  perseant Sync with HEAD
 1.3 21-Aug-2003  christos branches: 1.3.98;
remove clause 3
 1.2 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.1 04-Jul-1997  christos Fix compiler warnings.
 1.3.98.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.3.98.1 21-Apr-2020  martin Sync with HEAD
 1.22 06-Oct-2009  apb branches: 1.22.48;
Make this slightly more portable; it has to run on arbitary host
platforms at build time. Previousy, some shells were confused by
some of the "[ ... ]" tests.
 1.21 06-Jun-2004  christos don't include the printf builtin if we are SMALL; saves 10K.
 1.20 22-Aug-2003  agc Move 4 more files from UCB 4 clause to 3 clause licence.

Thanks to Julio Merino for pointing them out.
 1.19 15-May-2003  dsl Use echo instead of cat to add prologue to builtins.[ch]
Under some circumstances the headers got overwritten.
 1.18 02-Feb-2003  dsl Parse end of line comments correctly
(approved by christos)
 1.17 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.16 15-Oct-2002  lukem don't compile in `-h' as a synonym for the command that the argument is for.
this fix is hokey, but works as well as the previous solution for -j.
 1.15 09-Jul-1999  christos compile with WARNS = 2
 1.14 29-Mar-1998  christos Pr/5221: Jason Thorpe: Simplify sh Makefile, so that builts from other
directories work.
 1.13 04-Jul-1997  christos branches: 1.13.2;
Fix compiler warnings.
 1.12 11-May-1995  christos Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.11 21-Mar-1995  cgd convert to new RCS id conventions.
 1.10 07-Jul-1994  mycroft Bandaid quoting.
 1.9 24-Jun-1994  jtc Renamed builtins to builtins.def to eliminate make's (incorrect) circular
dependancy between the builtins data file and builtins.c.

The bug only occured when there was no obj directory, and is a result of
NetBSD's better (compared to 4.4lite's) default make rules.

Fixes bug #301.
 1.8 11-Jun-1994  mycroft Add RCS ids.
 1.7 14-May-1994  cgd add back in support for building w/o obj dir. also, add NO_HISTORY
define, which (if you invoke mkbuiltins properly) gets you a sh w/o
history of command line editing (for floppy sh).
 1.6 11-May-1994  jtc sync with 4.4lite
 1.5 28-Dec-1993  davidb Changed to use make's new .OBJDIR
 1.4 18-Apr-1993  mycroft Don't lose if obj dir not present.
 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.13.2.1 08-May-1998  mycroft Sync with trunk, per request of christos.
 1.22.48.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.22.48.1 21-Apr-2020  martin Sync with HEAD
 1.24 17-Jan-2004  dsl Replace mkinit.c with mkinit.sh
Build mksyntax directly from mksyntax.c so that the -DTARGET_CHAR=xxx
is applied when it is build.
OTOH mksyntax is broken as it tries to determine properties of the
target system by running code on the build system.
 1.23 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.22 13-Jul-2003  itojun use bounded string op
 1.21 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.20 18-Jul-2000  cgd host program portability: don't use <sys/cdefs.h>, __COPYRIGHT(),
__RCSID(), or __P(). (these programs have been de-__P()'d.)
Repeat after me: "Not all cross-compilation host systems are NetBSD."
 1.19 28-Jul-1998  mycroft Be more retentive about use of NOTREACHED and noreturn.
 1.18 28-Jul-1998  mycroft Delint.
 1.17 04-Jul-1997  christos Fix compiler warnings.
 1.16 11-Jan-1997  tls kill 'register'
 1.15 16-Oct-1996  christos PR/2808: #undef things that we #define to avoid duplicate definitions.
(from FreeBSD)
 1.14 18-Feb-1996  mycroft branches: 1.14.4;
Fix problems with the way init.o is built:
* Prevent gratuitous rebuilds when nothing has changed.
* Make sure it's rebuilt if a .h file is updated.
From Mike Long, PR 1454.
 1.13 11-May-1995  christos Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.12 21-Mar-1995  cgd convert to new RCS id conventions.
 1.11 23-Dec-1994  cgd pull some prototypes into scope.
 1.10 04-Dec-1994  cgd from James Jegers <jimj@miller.cs.uwm.edu>: quiet -Wall, and squelch
some of the worst style errors.
 1.9 15-Jun-1994  mycroft Re-fix an old bug.
 1.8 11-Jun-1994  mycroft Add RCS ids.
 1.7 11-May-1994  jtc sync with 4.4lite
 1.6 25-Apr-1994  cgd lseek long lossage.
 1.5 27-Mar-1994  deraadt avoid spilling garbage into the file init.c. this happened if libc
was compiled -g..
 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.14.4.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.10 05-Dec-2018  kre Use printf, rather than echo (via echo redefined as a function that
uses printf for simplicity).

This script runs using the build host's shell, and echo, and so must
deal with all of the absurdity that different versions of echo dumb
upon us.

This is the underlying cause of the linux build failure that gson@ reported.
 1.9 18-Oct-2018  kre Dynamically detect the way the shell matches \ in a pattern,
and use whatever works for the sh running this script. Previously
we were using the (broken, and incorrect) method that worked in
old broken NetBSD sh's (and some others) and not the method that
works with the current (fixed) /bin/sh and other correct shells
(like bash). (For an exotic reason, in the particular use case,
both methods work with ksh93, but it is also generally correct).

This hasn't really mattered, as the difference is only significant
(only causes actual issues - the build fails) when compiling with DEBUG
enabled, which is something that most sane humans would never do, if they
want to retain that sanity.

The problem was detected by Patrick Welche when looking for an
unrelated problem, which was once considered to be a possible sh
problem, but turned out to be something entirely different.

XXX pullup -8
 1.8 16-Sep-2018  kre Begone unspecified test-a ... and be more obious what it was doing.
 1.7 27-Mar-2016  christos branches: 1.7.8; 1.7.14; 1.7.16;
General KNF and source code cleanups, avoid scattering the
magic string " \t\n" all over the place, slightly improved
syntax error messages, restructured some of the code for
clarity, don't allow IFS to be imported through the environment,
and remove the (never) conditionally compiled ATTY option.
Apart from one or two syntax error messages, and ignoring IFS
if present in the environment, this is intended to have no
user visible changes. (from kre@)
 1.6 08-Mar-2016  christos avoid duplicate includes (from kre)
 1.5 23-Oct-2008  apb Don't try to remove trailing newlines from shell variables via
constructs like ${var%$nl}. Apparently this allows the Ubuntu Linux
/bin/sh (dash) to be used as a host shell during the build.
Patch from PR 39786 by Andy Shevchenko.
 1.4 29-Apr-2008  martin Convert to new 2 clause license
 1.3 27-Feb-2008  dsl branches: 1.3.2;
Generate ANSI functions.
Just indent the code by a single tab - no need to compare against the
C program generated version any more.
 1.2 15-Jun-2004  dsl branches: 1.2.16; 1.2.22;
Use shell variables to get '(' and '\' inside shell substitution patterns.
Solves problems with different shells having differntly buggy parsers
(and the standard probably allowing random behaviour).
Should fix bin/25938
 1.1 17-Jan-2004  dsl Replace mkinit.c with mkinit.sh
Build mksyntax directly from mksyntax.c so that the -DTARGET_CHAR=xxx
is applied when it is build.
OTOH mksyntax is broken as it tries to determine properties of the
target system by running code on the build system.
 1.2.22.1 24-Mar-2008  keiichi sync with head.
 1.2.16.1 23-Mar-2008  matt sync with HEAD
 1.3.2.1 18-May-2008  yamt sync with head.
 1.7.16.3 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.7.16.2 21-Apr-2020  martin Sync with HEAD
 1.7.16.1 10-Jun-2019  christos Sync with HEAD
 1.7.14.3 26-Dec-2018  pgoyette Sync with HEAD, resolve a few conflicts
 1.7.14.2 20-Oct-2018  pgoyette Sync with head
 1.7.14.1 30-Sep-2018  pgoyette Ssync with HEAD
 1.7.8.1 21-Oct-2018  martin Pull up following revision(s) (requested by kre in ticket #1067):

bin/sh/mkinit.sh: revision 1.9

Dynamically detect the way the shell matches \ in a pattern,
and use whatever works for the sh running this script. Previously
we were using the (broken, and incorrect) method that worked in
old broken NetBSD sh's (and some others) and not the method that
works with the current (fixed) /bin/sh and other correct shells
(like bash). (For an exotic reason, in the particular use case,
both methods work with ksh93, but it is also generally correct).

This hasn't really mattered, as the difference is only significant
(only causes actual issues - the build fails) when compiling with DEBUG
enabled, which is something that most sane humans would never do, if they
want to retain that sanity.

The problem was detected by Patrick Welche when looking for an
unrelated problem, which was once considered to be a possible sh
problem, but turned out to be something entirely different.

XXX pullup -8
 1.7 14-Oct-2024  kre Use tools awk where appropriate

And while here, switch from using echo to printf (via a
function echo() which just uses printf, but is limited to
this file only - it isn't general enough for use elsewhere).

NFCI
 1.6 18-Aug-2018  kre branches: 1.6.12;

In the older debug code (not using the new macros added in the
previous rev) the two values (node name, and node number) were
arbitrarily printed in different formats and orders (depending
upon my mood at the time I guess...) The new macros will standardise
that usage (in the debug output) once some use of them actually begins.

When the macros were added, I arbitrarily copied the format of one
use I was looking at at that instant (the one which inspired the change),
but after gazing at DEBUG mode output over the intervening time, I
have concluded that I did not pick the easiest to read/follow format.

So, even before they are used, change the style... Also, conform
to standard PRIxxxx macro style by omitting the leading '%'.

NFC (since they aren't used at all, anywhere, yet, not even the
possibility of anything changing!)
 1.5 16-Aug-2018  kre NFC - a build structure code layout change only.

This generates nodenames.h which is a file that used to begin
#ifdef DEBUG
(line 1) and end with
#endif
(last line) with no intervening (matching) #else ... ie: for DEBUG use only.

That led to situations where non-debug code would like to make use
of the info provided, if DEBUG was enabled, needed to add #ifdef DEBUG
at the point of use.

Avoid that by providing new macros that are always defined (DEBUG or not,
so now we have a #else) which allow code to be written to make use of
the extra DEBUG info, if it is available, or not, if not.

While here, add double-include protection on the generated .h file
(just being cautious - nothing is ever going to cause it to get
included anywhere twice - or it shouldn't) and add the traditional
comments on the #else and #endif stuff (which is also really useless
as no-one is really expected to ever read the generated file). Never mind.

Nothing yet (elsewhere in the sh source) uses the new macros, so there's
even less chance of this changing anything than there would otherwise be.
 1.4 19-Jun-2017  kre branches: 1.4.4; 1.4.6;

It is amazing what nonsense appears to work sometimes... (all my nonsense too!)

Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...

So as it happens these fixes change nothing, but they are needed anyway.

(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
 1.3 27-Mar-2016  christos branches: 1.3.8;
General KNF and source code cleanups, avoid scattering the
magic string " \t\n" all over the place, slightly improved
syntax error messages, restructured some of the code for
clarity, don't allow IFS to be imported through the environment,
and remove the (never) conditionally compiled ATTY option.
Apart from one or two syntax error messages, and ignoring IFS
if present in the environment, this is intended to have no
user visible changes. (from kre@)
 1.2 27-Feb-2016  christos Improve debugging, from kre (I hooked it to the build).
 1.1 24-Feb-2016  christos Simple script to create node names for debugging
 1.3.8.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.4.6.3 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.4.6.2 21-Apr-2020  martin Sync with HEAD
 1.4.6.1 10-Jun-2019  christos Sync with HEAD
 1.4.4.1 06-Sep-2018  pgoyette Sync with HEAD

Resolve a couple of conflicts (result of the uimin/uimax changes)
 1.6.12.1 02-Aug-2025  perseant Sync with HEAD
 1.24 16-Jan-2004  dsl Replace the C program mknodes.c with a shell script mknodes.sh
(mkinit and mksyntax may also die soon...)
 1.23 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.22 13-Jul-2003  itojun use bounded string op
 1.21 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.20 04-Oct-2002  christos Rename ALIGN to SHELL_ALIGN and simplify macro so that it does not have side
effects, and add double to it, so that it aligns doubles correctly too. This
is just a workaround to fix the sparc64 problem where ALIGN() is now defined
in some include file to be 16 instead of 8. Thanks to martin for debugging this.
 1.19 25-May-2002  wiz __STDC__ is always defined on NetBSD, so remove #ifdef __STDC__ (and
unnecessary #else cases).
 1.18 27-Jul-2000  cgd host program portability: set infp to stdin at runtime, since apparently
some systems (e.g. linux) define stdin in such a way that it can't
be used to initialize values at compile time.
 1.17 18-Jul-2000  cgd host program portability: don't use <sys/cdefs.h>, __COPYRIGHT(),
__RCSID(), or __P(). (these programs have been de-__P()'d.)
Repeat after me: "Not all cross-compilation host systems are NetBSD."
 1.16 28-Jul-1998  mycroft Delint.
 1.15 04-Jul-1997  christos Fix compiler warnings.
 1.14 11-Apr-1997  christos Pointer arithmetic on void * is illegal but gcc does not care.
 1.13 11-Jan-1997  tls kill 'register'
 1.12 16-Oct-1996  christos PR/2808: Remove extraneous newline from error message (from FreeBSD)
 1.11 11-May-1995  christos branches: 1.11.6;
Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.10 21-Mar-1995  cgd convert to new RCS id conventions.
 1.9 23-Dec-1994  cgd pull some prototypes into scope.
 1.8 04-Dec-1994  cgd from James Jegers <jimj@miller.cs.uwm.edu>: quiet -Wall, and squelch
some of the worst style errors.
 1.7 11-Jun-1994  mycroft Add RCS ids.
 1.6 11-May-1994  jtc sync with 4.4lite
 1.5 05-Sep-1993  mycroft From Vincent Broman:
error.c: Add , in initializer list if ENOLINK defined.
output.c: Gratuitously remove extra ;.
mknodes.c: main() should return a value.
Not from Vincent Broman:
mknodes.c: main() should return an error condition when approriate, too.
 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.11.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.4 19-Jan-2019  kre Add some error checking, and stop assuming what the input
will necessarily contain. Allow defined nodes to use any
intN_t or unintN_t (as well as plain old int) data types
in fields (along with the others that are permitted).

Note: this script is a part of the build procedure for /bin/sh,
the modified version generates the exact same output files
(for the unaltered input specifications) as the previous one
did, hence no visible change is expected (or even possible).

While there is a tiny chance that some host shell will fail
to be able to run this script while building, the script still
uses nothing even slightly exotic, and is much more conservative
than other scripts used during the build process, so there should
be no issues there either.
 1.3 22-Jun-2018  kre branches: 1.3.2;
Deal with ref after free found by ASAN when a function redefines
itself, or some other function which is still active.
This was a long known bug (fixed ages ago in the FreeBSD sh) which
hadn't been fixed as in practice, the situation that causes the
problem simply doesn't arise .. ASAN found it in the sh dotcmd
tests which do have this odd "feature" in the way they are written
(but where it never caused a problem, as the tests are so simple
that no mem is ever allocated between when the old version of the
function was deleted, and when it finished executing, so its code
all remained intact, despite having been freed.)

The fix is taken from the FreeBSD sh.

XXX -- pullup-8 (after a while to ensure no other problems arise).
 1.2 29-Apr-2008  martin branches: 1.2.56; 1.2.62;
Convert to new 2 clause license
 1.1 16-Jan-2004  dsl branches: 1.1.30;
Replace the C program mknodes.c with a shell script mknodes.sh
(mkinit and mksyntax may also die soon...)
 1.1.30.1 18-May-2008  yamt sync with head.
 1.2.62.2 26-Jan-2019  pgoyette Sync with HEAD
 1.2.62.1 25-Jun-2018  pgoyette Sync with HEAD
 1.2.56.1 13-Jul-2018  martin Pull up following revision(s) (requested by kre in ticket #906):

bin/sh/eval.c: revision 1.155
bin/sh/mknodes.sh: revision 1.3
bin/sh/nodes.c.pat: revision 1.14
bin/sh/exec.h: revision 1.27
bin/sh/exec.c: revision 1.52

Deal with ref after free found by ASAN when a function redefines
itself, or some other function which is still active.

This was a long known bug (fixed ages ago in the FreeBSD sh) which
hadn't been fixed as in practice, the situation that causes the
problem simply doesn't arise .. ASAN found it in the sh dotcmd
tests which do have this odd "feature" in the way they are written
(but where it never caused a problem, as the tests are so simple
that no mem is ever allocated between when the old version of the
function was deleted, and when it finished executing, so its code
all remained intact, despite having been freed.)

The fix is taken from the FreeBSD sh.

XXX -- pullup-8 (after a while to ensure no other problems arise).
 1.3.2.3 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.3.2.2 21-Apr-2020  martin Sync with HEAD
 1.3.2.1 10-Jun-2019  christos Sync with HEAD
 1.9 11-Oct-2024  kre Allow '+' to be specified as the "one char option name" for long options
that don't have a 1 char equivalent, but do want to become a member of
an option set. The '+' is otherwise ignored. This is similar to '-'
in that position, except that skips past the option set field, and is
followed directly by the default value, '+' does not do that.

This currently changes nothing, as there are no current options that
use it (or would want to).
 1.8 16-Apr-2024  christos branches: 1.8.2;
Be more explicit with sort fields to produce consistent results with gnu
sort (Jan-Benedict Glaw)
 1.7 06-Apr-2024  kre Redo the mktemp(1) part - some mktemp's (including ours) require the
XXXX's to be at the end of the name (like mk*temp(3)) so however well
it will work with mktemp implementations which allow the X's to be
anywhere in the final component of the name, it will work just as
well on them with the X's at the end.

But we don't normally need all of that mess - knowing which temp
file is which is useful only when debugging the script, and that's
(mostly) long done. So, in normal uses now just use $(mktemp) and
allow mktemp to pick its own name - we don't need to know what it is.
Every mktemp(1) supports that mode of operation.

Bug when debugging the script (which for current purposes will be
taken to be when the -x flag is passed to the shell running it, to
trace what it does) then we will make the temp files have names we
can recognise (and in that case, also don't delete them when done).

While here, check for mktemp(1) failing, and abort if that
happens (we assume that if it fails it will write an error
message to stderr, so the script does not need to.)

As for the purpose of the script ... of course the header file
generated (or an equivalent elsewhere) could be generated and
maintained by hand, but why would anyone want to do all that
work when software can do it for us, and do it correctly without
human thought?

This also allows the options in the master list (option.list) to be
arranged in a way that is meaningful for them, unrelated to the order
the shell needs to have them in (or rearrange them to be at run time)
and have that order shuffled however is convenient. Currently all
the posix standard options are first, then the "hybrid" options, and
finally the local ones for this shell. Currently "pipefail" is in the
final set, but once the next posix version is published, that will
become a standard option, and get moved in the list - the shell won't
even notice as this script puts the options into shell desired order.
 1.6 05-Apr-2024  christos From Jan-Benedict Glaw:

Fix a redirection and prepare a stable sort for upper-/lowercase
option letters

This script is a mess, I strongly believe that it should be rewritten.
However, I'm not 100% sure why it was invented in the first place
(come on, the generated header file isn't _that_ complicated that
it couldn't be sanely managed by hand!), but let's fix the sorting
order by using LC_ALL=C.

Also add a few 'X' to the `mktemp` template to make non-BSD
implementations happy. As a bonus, actually *use* the initial `sed`
output instead of throwing it away by piping it into `sort` with
also connecting `sort`'s stdin with the original input file...
 1.5 15-Nov-2017  kre branches: 1.5.4; 1.5.6; 1.5.14;
Sort options with long names that differ only by char case in
the same order that option flags with a similar property are sorted.
This corresponds with the change made to the sort order of the short
names made in the previous update (1.4).

Right now, this change makes no difference at all, as there are no
long option names that differ only in char case (yet.)
 1.4 01-Jul-2017  kre Make $- list flags in the same order they appear in sh(1)
 1.3 19-Jun-2017  kre "b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
 1.2 28-May-2017  kre branches: 1.2.2;
Redo mkoptions.sh .. much better this way, now fully automated
option sorting (no longer required option.list to be manually
sorted by long option name) and properly handles conditional
options. Cleaner output format as well.

This allows option.list to be reordered to group related options
together ... also added more comments to it.
 1.1 28-May-2017  kre Arrange for set -o and $- output to be sorted, rather than more
or less random (and becoming worse as more options are added.)
Since the data is known at compile time, sort at compile time,
rather than at run time.
 1.2.2.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.5.14.1 01-Oct-2025  martin Pull up following revision(s) (requested by kre in ticket #1165):

bin/sh/option.list: revision 1.12
bin/sh/mkoptions.sh: revision 1.6
bin/sh/mkoptions.sh: revision 1.7
bin/sh/mkoptions.sh: revision 1.8
bin/sh/mkoptions.sh: revision 1.9

From Jan-Benedict Glaw:
Fix a redirection and prepare a stable sort for upper-/lowercase
option letters

This script is a mess, I strongly believe that it should be rewritten.
However, I'm not 100% sure why it was invented in the first place
(come on, the generated header file isn't _that_ complicated that
it couldn't be sanely managed by hand!), but let's fix the sorting
order by using LC_ALL=C.

Also add a few 'X' to the `mktemp` template to make non-BSD
implementations happy. As a bonus, actually *use* the initial `sed`
output instead of throwing it away by piping it into `sort` with
also connecting `sort`'s stdin with the original input file...

Redo the mktemp(1) part - some mktemp's (including ours) require the
XXXX's to be at the end of the name (like mk*temp(3)) so however well
it will work with mktemp implementations which allow the X's to be
anywhere in the final component of the name, it will work just as
well on them with the X's at the end.

But we don't normally need all of that mess - knowing which temp
file is which is useful only when debugging the script, and that's
(mostly) long done. So, in normal uses now just use $(mktemp) and
allow mktemp to pick its own name - we don't need to know what it is.
Every mktemp(1) supports that mode of operation.
Bug when debugging the script (which for current purposes will be
taken to be when the -x flag is passed to the shell running it, to
trace what it does) then we will make the temp files have names we
can recognise (and in that case, also don't delete them when done).

While here, check for mktemp(1) failing, and abort if that
happens (we assume that if it fails it will write an error
message to stderr, so the script does not need to.)

As for the purpose of the script ... of course the header file
generated (or an equivalent elsewhere) could be generated and
maintained by hand, but why would anyone want to do all that
work when software can do it for us, and do it correctly without
human thought?

This also allows the options in the master list (option.list) to be
arranged in a way that is meaningful for them, unrelated to the order
the shell needs to have them in (or rearrange them to be at run time)
and have that order shuffled however is convenient. Currently all
the posix standard options are first, then the "hybrid" options, and
finally the local ones for this shell. Currently "pipefail" is in the
final set, but once the next posix version is published, that will
become a standard option, and get moved in the list - the shell won't
even notice as this script puts the options into shell desired order.

Be more explicit with sort fields to produce consistent results with gnu
sort (Jan-Benedict Glaw)

Allow '+' to be specified as the "one char option name" for long options
that don't have a 1 char equivalent, but do want to become a member of
an option set. The '+' is otherwise ignored. This is similar to '-'
in that position, except that skips past the option set field, and is
followed directly by the default value, '+' does not do that.
This currently changes nothing, as there are no current options that
use it (or would want to).

PR bin/59646 option.list wsp consistency
Be consistent with use of tab/space in fields used as
sort keys, so versions of sort which might not behave
exactly as we expect should still produce the same results.
 1.5.6.1 01-Oct-2025  martin Pull up following revision(s) (requested by kre in ticket #1970):

bin/sh/option.list: revision 1.12
bin/sh/mkoptions.sh: revision 1.6
bin/sh/mkoptions.sh: revision 1.7
bin/sh/mkoptions.sh: revision 1.8
bin/sh/mkoptions.sh: revision 1.9

From Jan-Benedict Glaw:
Fix a redirection and prepare a stable sort for upper-/lowercase
option letters

This script is a mess, I strongly believe that it should be rewritten.
However, I'm not 100% sure why it was invented in the first place
(come on, the generated header file isn't _that_ complicated that
it couldn't be sanely managed by hand!), but let's fix the sorting
order by using LC_ALL=C.

Also add a few 'X' to the `mktemp` template to make non-BSD
implementations happy. As a bonus, actually *use* the initial `sed`
output instead of throwing it away by piping it into `sort` with
also connecting `sort`'s stdin with the original input file...

Redo the mktemp(1) part - some mktemp's (including ours) require the
XXXX's to be at the end of the name (like mk*temp(3)) so however well
it will work with mktemp implementations which allow the X's to be
anywhere in the final component of the name, it will work just as
well on them with the X's at the end.

But we don't normally need all of that mess - knowing which temp
file is which is useful only when debugging the script, and that's
(mostly) long done. So, in normal uses now just use $(mktemp) and
allow mktemp to pick its own name - we don't need to know what it is.
Every mktemp(1) supports that mode of operation.
Bug when debugging the script (which for current purposes will be
taken to be when the -x flag is passed to the shell running it, to
trace what it does) then we will make the temp files have names we
can recognise (and in that case, also don't delete them when done).

While here, check for mktemp(1) failing, and abort if that
happens (we assume that if it fails it will write an error
message to stderr, so the script does not need to.)

As for the purpose of the script ... of course the header file
generated (or an equivalent elsewhere) could be generated and
maintained by hand, but why would anyone want to do all that
work when software can do it for us, and do it correctly without
human thought?

This also allows the options in the master list (option.list) to be
arranged in a way that is meaningful for them, unrelated to the order
the shell needs to have them in (or rearrange them to be at run time)
and have that order shuffled however is convenient. Currently all
the posix standard options are first, then the "hybrid" options, and
finally the local ones for this shell. Currently "pipefail" is in the
final set, but once the next posix version is published, that will
become a standard option, and get moved in the list - the shell won't
even notice as this script puts the options into shell desired order.

Be more explicit with sort fields to produce consistent results with gnu
sort (Jan-Benedict Glaw)

Allow '+' to be specified as the "one char option name" for long options
that don't have a 1 char equivalent, but do want to become a member of
an option set. The '+' is otherwise ignored. This is similar to '-'
in that position, except that skips past the option set field, and is
followed directly by the default value, '+' does not do that.
This currently changes nothing, as there are no current options that
use it (or would want to).

PR bin/59646 option.list wsp consistency
Be consistent with use of tab/space in fields used as
sort keys, so versions of sort which might not behave
exactly as we expect should still produce the same results.
 1.5.4.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.5.4.1 21-Apr-2020  martin Sync with HEAD
 1.8.2.1 02-Aug-2025  perseant Sync with HEAD
 1.5 06-Aug-1993  mycroft Clean up deleted files.
 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.31 17-Jan-2004  dsl Put a syntax.c under CVS instead of building if with the mksyntax program.
Kill mksyntax.c - no longer possible to get the 'wrong sort of chars'.
/bin/sh now has no helper binaries.
syntax.c uses C99 initialisers, run time initialisation could be used
for systems where the compiler doesn't support them.
I've used some #defines to help make this possible - but writing the code
starts making it rather messy.
 1.30 17-Jan-2004  dsl Put syntax.h under CVS instead of having it generated by mksyntax.
Use CHAR_MIN (from limits.h) to determine whether target char are signed
or unsigned - the syntax tables will not be indexed properly.
Rip out all the stuff from mksyntax.c that wrote syntax.h.
syntax.c can stiff be generated incorrectly...
 1.29 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.28 13-Jul-2003  itojun use bounded string op
 1.27 12-Jan-2003  christos Make sure that UPEOF is compared to the right type on the left hand
side. Sometimes it was compared to int, which was -1 on EOF, and on
unsigned char machines UPEOF was (unsigned char)-1. This worked
by chance because isalpha((unsigned char)-1) returns false usually,
but it does not when the locale is invalid!
 1.26 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.25 31-May-2002  christos deal with char c; c != -129 warning. Hi jason!
 1.24 12-Feb-2002  christos branches: 1.24.4;
Since we should be able to handle nested double quotes, don't use
the syntax maps to determine the beginning and end quotes (kill
CENDQUOTE). Handle single quotes opening and closing via checking
the current syntax map. Keep a bitmap of doublequote state one bit
per variable nesting level. For the first 32 nested double quotes,
we don't need any additional memory, but for more we allocate
dynamically.
 1.23 18-Jul-2000  cgd host program portability: don't use <sys/cdefs.h>, __COPYRIGHT(),
__RCSID(), or __P(). (these programs have been de-__P()'d.)
Repeat after me: "Not all cross-compilation host systems are NetBSD."
 1.22 08-Mar-1999  castor Add '#include <sys/types.h>' since that's where int8_t and u_int8_t can
usually be found.
 1.21 23-Feb-1999  wrstuden Make cross-building from i386 to powerpc (from signed to unsigned char)
ports work right.
 1.20 25-Jan-1999  mycroft Patches from Tor Egge (via Havard Eidnes) to fix various bugs in field
splitting and combining.
(Note: Some of this are not strictly bugs, but differences between traditional
Bourne shell and POSIX.)
 1.19 12-Sep-1998  wrstuden Patch to make sh cross-compile right. mksyntax reports unsigned char for
powerpc, and signed for m68k & i386.
 1.18 28-Jul-1998  mycroft Be more retentive about use of NOTREACHED and noreturn.
 1.17 28-Jul-1998  mycroft Delint.
 1.16 18-Jul-1997  thorpej Cast the result of pointer arithmetic to "long", and use %ld to print it.
 1.15 05-Jul-1997  christos Fix problem introduced in yesterday's commit that broke both signed and
unsigned character machines. So that people don't have to reverse engineer
this again:
mksyntax detects if characters are signed or not and builts a syntax
table that has a base of 129 for signed characters or 1 for unsigned
characters. This is so the largest negative signed char [-128] + the
base == 1. 0 is special and means end of file in both cases. PEOF
is -1 for the unsigned character case and -129 for the signed
character case, so that syntax[PEOF + base] == syntax[0] == CEOF
So PEOF has to be -1, but it is explicitly compared with
unsigned characters on machines where characters are unsigned.
The quick fix is to define UPEOF the (unsigned char) version of PEOF
and use that. A better fix is to always use unsigned characters
when referencing symbol table entries, but that would require
extensive changes to the shell. So to summarize

syntax[0] == CEOF, base + PEOF == 0

unsigned signed
base 1 129
PEOF -1 -129
 1.14 04-Jul-1997  christos Make the syntax tables work on machines where characters are unsigned.
 1.13 04-Jul-1997  christos Fix compiler warnings.
 1.12 16-Oct-1996  christos PR/2808: Use the <ctype.h> functions instead of our homegrown tables to
determine if a character is alpha or alphanumeric, so that NLS
works... now if only our NLS really worked... (from FreeBSD).
 1.11 11-May-1995  christos branches: 1.11.6;
Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.10 21-Mar-1995  cgd convert to new RCS id conventions.
 1.9 23-Dec-1994  cgd pull some prototypes into scope.
 1.8 04-Dec-1994  cgd from James Jegers <jimj@miller.cs.uwm.edu>: quiet -Wall, and squelch
some of the worst style errors.
 1.7 14-Jun-1994  jtc From Christos:
1. Fix `-' quoting in [ ] expressions.
2. Fix expansion of variables in redirections
 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.11.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.24.4.1 31-May-2002  tv Pull up revision 1.25 (requested by mycroft in ticket #110):
deal with char c; c != -129 warning. Hi jason!
 1.15 07-Apr-2023  kre The great shell trailing whitespace cleanup of 2023...
Inspired by private e-mail comments from mouse@

NFCI.
 1.14 26-Jul-2017  kre branches: 1.14.4;
Add a comment explaining the ordering reltionship of the tokens
(operators all come first, then TWORD, then keywords), and switch
from using TIF to define KWDOFFSET to using TWORD (the barrier,
rather than the token that happens to be first after it.)
 1.13 04-May-2017  kre Implement the ';&' (used instead of ';;') case statement list terminator
which causes fall through the to command list of the following pattern
(wuthout evaluating that pattern). This has been approved for inclusion
in the next major version of the POSIX standard (Issue 8), and is
implemented by most other shells.

Now all form a circle and together attempt to summon the great wizd
in the hopes that his magic spells can transform the poor attempt
at documenting this feature into something rational...
 1.12 25-Oct-2008  apb branches: 1.12.52;
In shell scripts run during the build, add a SED variable, defaulting
to "sed". SED=${TOOL_SED:Q} should be passed in the environment to
override this.
 1.11 19-Oct-2008  apb In shell scripts invoked during a build, and in crunchgen, use ${AWK}
instead of plain "awk". The Makefiles that invoke these scripts
or programs will pass AWK=${HOST_AWK:Q}.
 1.10 22-Aug-2003  agc Move 4 more files from UCB 4 clause to 3 clause licence.

Thanks to Julio Merino for pointing them out.
 1.9 09-Jul-1999  christos compile with WARNS = 2
 1.8 16-Oct-1996  christos PR/2808: tokens.def -> tokens.h
 1.7 11-May-1995  christos branches: 1.7.6;
Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.6 21-Mar-1995  cgd convert to new RCS id conventions.
 1.5 11-Jun-1994  mycroft Add RCS ids.
 1.4 11-May-1994  jtc sync with 4.4lite
 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.7.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.12.52.1 11-May-2017  pgoyette Sync with HEAD
 1.14.4.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.14.4.1 21-Apr-2020  martin Sync with HEAD
 1.4 26-Jan-1994  mycroft Clean up deleted files.
 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.1 21-Mar-1993  cgd initial import of 386bsd-0.1 sources
 1.16 13-Jul-2024  kre Implement the HISTFILE and HISTAPPEND variables.

See the (newly updated) sh(1) for details.
Also add the -z option to fc (clear history).

None of this exists in SMALL shells.
 1.15 12-Jul-2024  kre Improve safety in var imports from the environment.

Add a new var flag VUNSAFE - set on all vars imported from the environment.

Add setvareqsafe() (which is to setvareq() as setvarsafe() is to setvar())
and use that instead of setvareq() when processing the environment, so
errors don't cause the shell to abort. Use VUNSAFE in that call.

Add flags arguments to all var callback functions which are used when setting
variables, and pass the flags given to the setvar*() functions to those
functions, so they can act differently in different situations (if desired).
Most of them just ignore the flags.

When unsetting a variable, call setvar() to clear things (and call the
callback function) both when the variable had a value which needs to be freed,
and when unsetting a variable which wasn't unset previously, so the VUNSET
flag can be seen by that callback func.

When setting HISTSIZE, use the flags passed to determine whether to ignore
bad values (if VUNSAFE) or treat them as an error. This replaces the
earlier temporary hack to always ignore bad data there (histedit.c 1.68).

Miscellaneous associated minor changes.

These changes should largely be invisible in normal use.
 1.14 15-Aug-2021  christos branches: 1.14.4;
- Add command completion (from FreeBSD)
- Use EL_SAFEREAD
 1.13 28-Jun-2017  kre branches: 1.13.6;

Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
 1.12 27-Jun-2017  kre Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
 1.11 18-Jun-2011  christos branches: 1.11.36;
PR/45069: Henning Petersen: Use prototypes from builtins.h .
 1.10 07-Aug-2003  agc branches: 1.10.52;
Move UCB-licensed code from 4-clause to 3-clause licence.

Patches provided by Joel Baker in PR 22249, verified by myself.
 1.9 04-May-2003  gmcgarry Add new builtin 'inputrc' which allows keybindings to be redefined
for the current shell. From Arne H Juul in PR#10097.
 1.8 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.7 09-Jul-1999  christos compile with WARNS = 2
 1.6 11-Apr-1997  christos Track $TERM and call the appropriate editline(3) routine to update the
terminal type.
 1.5 25-Jun-1996  christos change sethistsize() to take the history size as an argument so it can
be used directly by the new variable callback functions.
 1.4 11-May-1995  christos branches: 1.4.6;
Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.3 21-Mar-1995  cgd convert to new RCS id conventions.
 1.2 11-Jun-1994  mycroft Add RCS ids.
 1.1 11-May-1994  jtc branches: 1.1.1;
Initial revision
 1.1.1.1 11-May-1994  jtc 44lite code
 1.4.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.10.52.1 23-Jun-2011  cherry Catchup with rmind-uvmplock merge.
 1.11.36.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.13.6.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.13.6.1 21-Apr-2020  martin Sync with HEAD
 1.14.4.1 02-Aug-2025  perseant Sync with HEAD
 1.21 13-Jul-2024  kre Implement the HISTFILE and HISTAPPEND variables.

See the (newly updated) sh(1) for details.
Also add the -z option to fc (clear history).

None of this exists in SMALL shells.
 1.20 07-Apr-2023  kre branches: 1.20.2;

The great shell trailing whitespace cleanup of 2023...
Inspired by private e-mail comments from mouse@

NFCI.
 1.19 16-Apr-2022  kre Avoid generating error messages implying that user errors are illegal.
 1.18 13-Jul-2018  kre Remove atoi()

Mostly use number() (no longer implemented using atoi()) when an
unsigned integer is required, but use strtoXXX() when a conversion
is wanted, without the possibility or error (like setting OPTIND
and RANDOM). Always init OPTIND to 1 when sh starts (overriding
anything in environ.)
 1.17 28-Apr-2013  dholland branches: 1.17.22; 1.17.28; 1.17.30;
Add const.
 1.16 07-Aug-2003  agc branches: 1.16.54; 1.16.60;
Move UCB-licensed code from 4-clause to 3-clause licence.

Patches provided by Joel Baker in PR 22249, verified by myself.
 1.15 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.14 09-Jul-1999  christos compile with WARNS = 2
 1.13 04-Jul-1997  christos Fix compiler warnings.
 1.12 11-Jan-1997  tls kill 'register'
 1.11 16-Oct-1996  christos PR/2808: Kill use of error2() (from FreeBSD)
 1.10 11-May-1995  christos branches: 1.10.6;
Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.9 21-Mar-1995  cgd convert to new RCS id conventions.
 1.8 11-Jun-1994  mycroft Add RCS ids.
 1.7 12-May-1994  jtc Include appropriate header files to bring function prototypes into scope.
 1.6 11-May-1994  jtc sync with 4.4lite
 1.5 04-May-1994  jtc Remove private versions of strchr() & bcopy(); there is nothing wrong with
the versions in our C library.
 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.10.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.16.60.1 23-Jun-2013  tls resync from head
 1.16.54.1 22-May-2014  yamt sync with head.

for a reference, the tree before this commit was tagged
as yamt-pagecache-tag8.

this commit was splitted into small chunks to avoid
a limitation of cvs. ("Protocol error: too many arguments")
 1.17.30.3 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.17.30.2 21-Apr-2020  martin Sync with HEAD
 1.17.30.1 10-Jun-2019  christos Sync with HEAD
 1.17.28.1 28-Jul-2018  pgoyette Sync with HEAD
 1.17.22.1 25-Aug-2018  martin Pull up following revision(s) (requested by kre in ticket #988):

bin/sh/parser.c: revision 1.147
bin/sh/var.c: revision 1.70
bin/sh/mystring.c: revision 1.18
bin/sh/options.c: revision 1.53
bin/sh/histedit.c: revision 1.53

Remove atoi()

Mostly use number() (no longer implemented using atoi()) when an
unsigned integer is required, but use strtoXXX() when a conversion
is wanted, without the possibility or error (like setting OPTIND
and RANDOM). Always init OPTIND to 1 when sh starts (overriding
anything in environ.)
 1.20.2.1 02-Aug-2025  perseant Sync with HEAD
 1.12 13-Jul-2024  kre Implement the HISTFILE and HISTAPPEND variables.

See the (newly updated) sh(1) for details.
Also add the -z option to fc (clear history).

None of this exists in SMALL shells.
 1.11 07-Aug-2003  agc branches: 1.11.98; 1.11.110;
Move UCB-licensed code from 4-clause to 3-clause licence.

Patches provided by Joel Baker in PR 22249, verified by myself.
 1.10 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.9 11-May-1995  christos Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.8 21-Mar-1995  cgd convert to new RCS id conventions.
 1.7 11-Jun-1994  mycroft Add RCS ids.
 1.6 11-May-1994  jtc sync with 4.4lite
 1.5 04-May-1994  jtc Remove private versions of strchr() & bcopy(); there is nothing wrong with
the versions in our C library.
 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.11.110.1 02-Aug-2025  perseant Sync with HEAD
 1.11.98.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.11.98.1 21-Apr-2020  martin Sync with HEAD
 1.14 22-Jun-2018  kre branches: 1.14.2;
Deal with ref after free found by ASAN when a function redefines
itself, or some other function which is still active.
This was a long known bug (fixed ages ago in the FreeBSD sh) which
hadn't been fixed as in practice, the situation that causes the
problem simply doesn't arise .. ASAN found it in the sh dotcmd
tests which do have this odd "feature" in the way they are written
(but where it never caused a problem, as the tests are so simple
that no mem is ever allocated between when the old version of the
function was deleted, and when it finished executing, so its code
all remained intact, despite having been freed.)

The fix is taken from the FreeBSD sh.

XXX -- pullup-8 (after a while to ensure no other problems arise).
 1.13 20-Mar-2012  matt branches: 1.13.26; 1.13.32;
Use C89 function definitions
 1.12 15-Jun-2004  dsl branches: 1.12.48;
Change '\0' to 0 so that the SVR4 'echo' doesn't convert it to a null byte.
Fixes bin/25938
 1.11 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.10 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.9 04-Oct-2002  christos Rename ALIGN to SHELL_ALIGN and simplify macro so that it does not have side
effects, and add double to it, so that it aligns doubles correctly too. This
is just a workaround to fix the sparc64 problem where ALIGN() is now defined
in some include file to be 16 instead of 8. Thanks to martin for debugging this.
 1.8 11-Apr-1997  christos Pointer arithmetic on void * is illegal but gcc does not care.
 1.7 11-May-1995  christos Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.6 21-Mar-1995  cgd convert to new RCS id conventions.
 1.5 11-Jun-1994  mycroft Add RCS ids.
 1.4 11-May-1994  jtc sync with 4.4lite
 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.48.1 17-Apr-2012  yamt sync with head
 1.13.32.1 25-Jun-2018  pgoyette Sync with HEAD
 1.13.26.1 13-Jul-2018  martin Pull up following revision(s) (requested by kre in ticket #906):

bin/sh/eval.c: revision 1.155
bin/sh/mknodes.sh: revision 1.3
bin/sh/nodes.c.pat: revision 1.14
bin/sh/exec.h: revision 1.27
bin/sh/exec.c: revision 1.52

Deal with ref after free found by ASAN when a function redefines
itself, or some other function which is still active.

This was a long known bug (fixed ages ago in the FreeBSD sh) which
hadn't been fixed as in practice, the situation that causes the
problem simply doesn't arise .. ASAN found it in the sh dotcmd
tests which do have this odd "feature" in the way they are written
(but where it never caused a problem, as the tests are so simple
that no mem is ever allocated between when the old version of the
function was deleted, and when it finished executing, so its code
all remained intact, despite having been freed.)

The fix is taken from the FreeBSD sh.

XXX -- pullup-8 (after a while to ensure no other problems arise).
 1.14.2.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.14.2.1 21-Apr-2020  martin Sync with HEAD
 1.20 22-Nov-2021  kre PR bin/53550

Here we go again... One more time to redo how here docs are
processed (it has been a few years since the last time!)

This is actually a relatively minor change, mostly to timimg
(to just when things happen). Now here docs are expanded at the
same time the "filename" word in a redirect is expanded, rather than
later when the heredoc was being sent to its process. This actually
makes things more consistent - but does break one of the ATF tests
which was testing that we were (effectively) internally inconsistent
in this area.

Not all shells agree on the context in which redirection expansions
should happen, some make any side effects visible to the parent shell
(the majority do) others do the redirection expansions in a subshell
so any side effcts are lost. We used to have a foot in each camp,
with the majority for everything but here docs, and the minority for
here docs. Now we're all the way with LBJ ... (or something like that).
 1.19 16-Nov-2021  kre Fix value of ${LINENO} in "for" commands.

This affects (as best I can tell) only uses of ${LINENO} in PS4
when -x is enabled (and perhaps only when the list contains no
expansions). "for" like "case" (which was already handled) is
special in that it generates trace output before actually executing
any kind of simple command.
 1.18 08-Jun-2017  kre branches: 1.18.6;

Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
 1.17 07-Jun-2017  kre A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)

This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)

The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.

This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).

I would not call the results of this perfect yet, but it is close.
 1.16 07-Jun-2017  kre An initial attempt at implementing LINENO to meet the specs.

Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.

Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)

This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.

POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)

This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.

This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).

Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
 1.15 09-May-2017  kre branches: 1.15.2;

If we are going to permit
! ! pipeline
(And for now the other places where ! is permitted)
we should at least generate the logically correct exit
status:
! ! (exit 5); echo $?
should print 1, not 5. ksh and bosh do it this way - and it makes sense.
bash and the FreeBSD sh echo "5" (as did we until now.)
dash, zsh, yash all enforce the standard syntax, and prohibit this.
 1.14 04-May-2017  kre Implement the ';&' (used instead of ';;') case statement list terminator
which causes fall through the to command list of the following pattern
(wuthout evaluating that pattern). This has been approved for inclusion
in the next major version of the POSIX standard (Issue 8), and is
implemented by most other shells.

Now all form a circle and together attempt to summon the great wizd
in the hopes that his magic spells can transform the poor attempt
at documenting this feature into something rational...
 1.13 26-May-2009  joerg branches: 1.13.38;
Make indentation consistent.
 1.12 22-Aug-2003  agc Move 4 more files from UCB 4 clause to 3 clause licence.

Thanks to Julio Merino for pointing them out.
 1.11 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.10 15-May-2002  christos implement noclobber. From Ben Harris, with minor tweaks from me. Two
unimplemented comments to go. Go Ben!
 1.9 04-Feb-1999  christos PR/4966: Joel Reicher: Implement <> redirections which are documented in
the man page.
 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 14-Jun-1994  jtc From Christos:
1. Fix `-' quoting in [ ] expressions.
2. Fix expansion of variables in redirections
 1.5 11-Jun-1994  mycroft Add RCS ids.
 1.4 11-May-1994  jtc sync with 4.4lite
 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.13.38.1 11-May-2017  pgoyette Sync with HEAD
 1.15.2.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.18.6.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.18.6.1 21-Apr-2020  martin Sync with HEAD
 1.12 10-Sep-2025  kre PR bin/59646 option.list wsp consistency

Be consistent with use of tab/space in fields used as
sort keys, so versions of sort which might not behave
exactly as we expect should still produce the same results.

XXX pullup -9 -10 -11
 1.11 14-Oct-2024  kre branches: 1.11.2;
Add a -r (version) option to sh

This new -r (or +r) option is for command line use only.
When encountered, the shell simply prints its version info
(such as it has, which isn't much) and exits (immediately).

This allows "funny" uses like
sh -version
the -v and -e options are standard, and processed as normal
(changing nothing, yet, except setting the option). Then the
'r' option is seen, the version info is printed, and the shell
exits. Any remaining "options" (there is no "-o n" option) are
ignored, as are any other args given to the shell.

The string printed (currently) is just "NetBSD shell:" followed
by the value of the NETBSD_SHELL variable (which has been established
already by the time options are processed).
 1.10 18-Sep-2022  kre branches: 1.10.2; 1.10.4;
Add the -l option (aka -o login): be a login shell. Meaningful only on
the command line (with both - and + forms) - overrides the presence (or
otherwise) of a '-' as argv[0][0].

Since this allows any shell to be a login shell (which simply means that
it runs /etc/profile and ~/.profile at shell startup - there are no other
side effects) add a new, always set at startup, variable NBSH_INVOCATION
which has a char string as its value, where each char has a meaning,
more or less related to how the shell was started. See sh(1).
This is intended to allow those startup scripts to tailor their behaviour
to the nature of this particular login shell (it is possible to detect
whether a shell is a login shell merely because of -l, or whether it would
have been anyway, before the -l option was added - and more). The
var could also be used to set different values for $ENV for different
uses of the shell.
 1.9 23-Nov-2018  kre branches: 1.9.2;

Avoid long option names that differ only in character case.
Change Xtrace (the name) to xlock instead. Aside from the different
name, there is no change to functionality.
 1.8 21-Nov-2017  kre branches: 1.8.2; 1.8.4;
Remove the -X option from SMALL shells (as used on boot floppies,
some other install media, mini-roots, etc.) It is unlikely that
such a shell will be used for much script debugging (and the old -x
still exists of course) and it adds a little bloat, so, zap...

The ancient unused (unrelated) xioctl() function is gone as well
(from all shells).
 1.7 19-Nov-2017  kre Implement the -X option - an apparent variant of -x which sends all trace
output to the stderr which existed when the -X option was (last) enabled.
It also enables tracing by enabling -x (and when reset, +X, also resets
the 'x' flag (+x)). Note that it is still -x/+x which actually
enables/disables the trace output. Hence "apparent variant" - what -X
actually does (aside from setting -x) is just to lock the trace output,
rather than having it follow wherever stderr is later redirected.
 1.6 24-Jul-2017  kre Implement the "pipefail" option (same semantics as in other shells)
to cause (when set, which it is not by default) the exit status of a
pipe to be 0 iff all commands in the pipe exited with status 0, and
otherwise, the status of the rightmost command to exit with a non-0
status.

In the doc, while describing this, also reword some of the text about
commands in general, how they are structured, and when they are executed.
 1.5 30-Jun-2017  kre Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
 1.4 17-Jun-2017  kre Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
 1.3 07-Jun-2017  kre A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)

This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)

The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.

This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).

I would not call the results of this perfect yet, but it is close.
 1.2 28-May-2017  kre branches: 1.2.2;
Redo mkoptions.sh .. much better this way, now fully automated
option sorting (no longer required option.list to be manually
sorted by long option name) and properly handles conditional
options. Cleaner output format as well.

This allows option.list to be reordered to group related options
together ... also added more comments to it.
 1.1 28-May-2017  kre Arrange for set -o and $- output to be sorted, rather than more
or less random (and becoming worse as more options are added.)
Since the data is known at compile time, sort at compile time,
rather than at run time.
 1.2.2.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.8.4.3 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.8.4.2 21-Apr-2020  martin Sync with HEAD
 1.8.4.1 10-Jun-2019  christos Sync with HEAD
 1.8.2.1 26-Nov-2018  pgoyette Sync with HEAD, resolve a couple of conflicts
 1.9.2.1 01-Oct-2025  martin Pull up following revision(s) (requested by kre in ticket #1970):

bin/sh/option.list: revision 1.12
bin/sh/mkoptions.sh: revision 1.6
bin/sh/mkoptions.sh: revision 1.7
bin/sh/mkoptions.sh: revision 1.8
bin/sh/mkoptions.sh: revision 1.9

From Jan-Benedict Glaw:
Fix a redirection and prepare a stable sort for upper-/lowercase
option letters

This script is a mess, I strongly believe that it should be rewritten.
However, I'm not 100% sure why it was invented in the first place
(come on, the generated header file isn't _that_ complicated that
it couldn't be sanely managed by hand!), but let's fix the sorting
order by using LC_ALL=C.

Also add a few 'X' to the `mktemp` template to make non-BSD
implementations happy. As a bonus, actually *use* the initial `sed`
output instead of throwing it away by piping it into `sort` with
also connecting `sort`'s stdin with the original input file...

Redo the mktemp(1) part - some mktemp's (including ours) require the
XXXX's to be at the end of the name (like mk*temp(3)) so however well
it will work with mktemp implementations which allow the X's to be
anywhere in the final component of the name, it will work just as
well on them with the X's at the end.

But we don't normally need all of that mess - knowing which temp
file is which is useful only when debugging the script, and that's
(mostly) long done. So, in normal uses now just use $(mktemp) and
allow mktemp to pick its own name - we don't need to know what it is.
Every mktemp(1) supports that mode of operation.
Bug when debugging the script (which for current purposes will be
taken to be when the -x flag is passed to the shell running it, to
trace what it does) then we will make the temp files have names we
can recognise (and in that case, also don't delete them when done).

While here, check for mktemp(1) failing, and abort if that
happens (we assume that if it fails it will write an error
message to stderr, so the script does not need to.)

As for the purpose of the script ... of course the header file
generated (or an equivalent elsewhere) could be generated and
maintained by hand, but why would anyone want to do all that
work when software can do it for us, and do it correctly without
human thought?

This also allows the options in the master list (option.list) to be
arranged in a way that is meaningful for them, unrelated to the order
the shell needs to have them in (or rearrange them to be at run time)
and have that order shuffled however is convenient. Currently all
the posix standard options are first, then the "hybrid" options, and
finally the local ones for this shell. Currently "pipefail" is in the
final set, but once the next posix version is published, that will
become a standard option, and get moved in the list - the shell won't
even notice as this script puts the options into shell desired order.

Be more explicit with sort fields to produce consistent results with gnu
sort (Jan-Benedict Glaw)

Allow '+' to be specified as the "one char option name" for long options
that don't have a 1 char equivalent, but do want to become a member of
an option set. The '+' is otherwise ignored. This is similar to '-'
in that position, except that skips past the option set field, and is
followed directly by the default value, '+' does not do that.
This currently changes nothing, as there are no current options that
use it (or would want to).

PR bin/59646 option.list wsp consistency
Be consistent with use of tab/space in fields used as
sort keys, so versions of sort which might not behave
exactly as we expect should still produce the same results.
 1.10.4.1 02-Aug-2025  perseant Sync with HEAD
 1.10.2.1 01-Oct-2025  martin Pull up following revision(s) (requested by kre in ticket #1165):

bin/sh/option.list: revision 1.12
bin/sh/mkoptions.sh: revision 1.6
bin/sh/mkoptions.sh: revision 1.7
bin/sh/mkoptions.sh: revision 1.8
bin/sh/mkoptions.sh: revision 1.9

From Jan-Benedict Glaw:
Fix a redirection and prepare a stable sort for upper-/lowercase
option letters

This script is a mess, I strongly believe that it should be rewritten.
However, I'm not 100% sure why it was invented in the first place
(come on, the generated header file isn't _that_ complicated that
it couldn't be sanely managed by hand!), but let's fix the sorting
order by using LC_ALL=C.

Also add a few 'X' to the `mktemp` template to make non-BSD
implementations happy. As a bonus, actually *use* the initial `sed`
output instead of throwing it away by piping it into `sort` with
also connecting `sort`'s stdin with the original input file...

Redo the mktemp(1) part - some mktemp's (including ours) require the
XXXX's to be at the end of the name (like mk*temp(3)) so however well
it will work with mktemp implementations which allow the X's to be
anywhere in the final component of the name, it will work just as
well on them with the X's at the end.

But we don't normally need all of that mess - knowing which temp
file is which is useful only when debugging the script, and that's
(mostly) long done. So, in normal uses now just use $(mktemp) and
allow mktemp to pick its own name - we don't need to know what it is.
Every mktemp(1) supports that mode of operation.
Bug when debugging the script (which for current purposes will be
taken to be when the -x flag is passed to the shell running it, to
trace what it does) then we will make the temp files have names we
can recognise (and in that case, also don't delete them when done).

While here, check for mktemp(1) failing, and abort if that
happens (we assume that if it fails it will write an error
message to stderr, so the script does not need to.)

As for the purpose of the script ... of course the header file
generated (or an equivalent elsewhere) could be generated and
maintained by hand, but why would anyone want to do all that
work when software can do it for us, and do it correctly without
human thought?

This also allows the options in the master list (option.list) to be
arranged in a way that is meaningful for them, unrelated to the order
the shell needs to have them in (or rearrange them to be at run time)
and have that order shuffled however is convenient. Currently all
the posix standard options are first, then the "hybrid" options, and
finally the local ones for this shell. Currently "pipefail" is in the
final set, but once the next posix version is published, that will
become a standard option, and get moved in the list - the shell won't
even notice as this script puts the options into shell desired order.

Be more explicit with sort fields to produce consistent results with gnu
sort (Jan-Benedict Glaw)

Allow '+' to be specified as the "one char option name" for long options
that don't have a 1 char equivalent, but do want to become a member of
an option set. The '+' is otherwise ignored. This is similar to '-'
in that position, except that skips past the option set field, and is
followed directly by the default value, '+' does not do that.
This currently changes nothing, as there are no current options that
use it (or would want to).

PR bin/59646 option.list wsp consistency
Be consistent with use of tab/space in fields used as
sort keys, so versions of sort which might not behave
exactly as we expect should still produce the same results.
 1.11.2.1 01-Oct-2025  martin Pull up following revision(s) (requested by kre in ticket #37):

bin/sh/option.list: revision 1.12

PR bin/59646 option.list wsp consistency

Be consistent with use of tab/space in fields used as
sort keys, so versions of sort which might not behave
exactly as we expect should still produce the same results.
 1.62 14-Oct-2024  kre 80 column police (for the recent -r change). NFC.
 1.61 14-Oct-2024  kre Add a -r (version) option to sh

This new -r (or +r) option is for command line use only.
When encountered, the shell simply prints its version info
(such as it has, which isn't much) and exits (immediately).

This allows "funny" uses like
sh -version
the -v and -e options are standard, and processed as normal
(changing nothing, yet, except setting the option). Then the
'r' option is seen, the version info is printed, and the shell
exits. Any remaining "options" (there is no "-o n" option) are
ignored, as are any other args given to the shell.

The string printed (currently) is just "NetBSD shell:" followed
by the value of the NETBSD_SHELL variable (which has been established
already by the time options are processed).
 1.60 21-Sep-2024  kre In !TINYPROG versions of sh, make the builtin "shift" builtin command
perform a rotate instead or shift if given a numeric arg (which is
otherwise an error).

"set -- a b c; shift -1; echo $*" will echo "c a b".

While here, make the shift builtin comply with POSIX, and accept
(and ignore) a '--' arg before the shift (or rotate) count.

Document the variant of shift in sh(1)

Adapt the shell test for shift to not expect "shift -1" to be an
error, test that rotate works as expected, and include some tests
that use the (useless, but required) "--" arg.
 1.59 12-Jul-2024  kre Improve safety in var imports from the environment.

Add a new var flag VUNSAFE - set on all vars imported from the environment.

Add setvareqsafe() (which is to setvareq() as setvarsafe() is to setvar())
and use that instead of setvareq() when processing the environment, so
errors don't cause the shell to abort. Use VUNSAFE in that call.

Add flags arguments to all var callback functions which are used when setting
variables, and pass the flags given to the setvar*() functions to those
functions, so they can act differently in different situations (if desired).
Most of them just ignore the flags.

When unsetting a variable, call setvar() to clear things (and call the
callback function) both when the variable had a value which needs to be freed,
and when unsetting a variable which wasn't unset previously, so the VUNSET
flag can be seen by that callback func.

When setting HISTSIZE, use the flags passed to determine whether to ignore
bad values (if VUNSAFE) or treat them as an error. This replaces the
earlier temporary hack to always ignore bad data there (histedit.c 1.68).

Miscellaneous associated minor changes.

These changes should largely be invisible in normal use.
 1.58 18-Sep-2022  kre branches: 1.58.4;
Add the -l option (aka -o login): be a login shell. Meaningful only on
the command line (with both - and + forms) - overrides the presence (or
otherwise) of a '-' as argv[0][0].

Since this allows any shell to be a login shell (which simply means that
it runs /etc/profile and ~/.profile at shell startup - there are no other
side effects) add a new, always set at startup, variable NBSH_INVOCATION
which has a char string as its value, where each char has a meaning,
more or less related to how the shell was started. See sh(1).
This is intended to allow those startup scripts to tailor their behaviour
to the nature of this particular login shell (it is possible to detect
whether a shell is a login shell merely because of -l, or whether it would
have been anyway, before the -l option was added - and more). The
var could also be used to set different values for $ENV for different
uses of the shell.
 1.57 16-Apr-2022  kre Avoid generating error messages implying that user errors are illegal.
 1.56 26-Oct-2021  kre PR bin/56464

After almost 30 years, finally do the right thing and read $HOME/.profile
rather than .profile in the initial directory (it was that way in version
1.1 ...) All other ash descendants seem to have fixed this long ago.

While here, copy a feature from FreeBSD which allows "set +p" (if a
shell run by a setuid process with the -p flag is privileged) to reset
the privileges. Once done (the set +p) it cannot be undone (a later
set -p sets the 'p' flag, but that's all it does) - that just becomes a
one bit storage location.

We do this, as (also copying from FreeBSD, and because it is the right
thing to do) we don't run .profile in a privileged shell - FreeBSD run
/etc/suid_profile in that case (not a good name, it also applies to setgid
shells) but I see no real need for that, we run /etc/profile in any case,
anything that would go in /etc/suid_profile can just go in /etc/profile
instead (with suitable guards so the commands only run in priv'd shells).

One or two minor DEBUG mode changes (notably having priv'd shells identify
themselves in the DEBUG trace) and sh.1 changes with doc of the "set +p"
change, the effect that has on $PSc and a few other wording tweaks.

XXX pullup -9 (not -8, this isn't worth it for the short lifetime
that has left - if it took 28+ years for anyone to notice this, it
cannot be having all that much effect).
 1.55 05-Feb-2020  kre Oops, the previous didn't do what was promised. Rather that ignoring
just "--" for exec & "." it ignored any first arg starting '-'.
Do it properly.
 1.54 04-Feb-2020  kre After bug report 262 (from 2010)
https://austingroupbugs.net/view.php?id=252
the Austin Group decided to require processing of "--" by the "."
and "exec" commands to solve a problem where some shells did
option processing for those commands (permitted) and others did
not (also permitted) which left no safe way to process a file
with a name beginning with "-".

This has finally made its way into what will be the next version of
the POSIX standard.

Since this shell did no option processing at all for those commands,
we need to update. This is that update.

The sole effect is that a "--" 'option' (to "." or "exec") is ignored.
This means that if you want to use "--" as the arg to one of those
commands, it needs to be given twice ". -- --". Apart from that there
should be no difference at all (though the "--" can now be used in other
situations, where we did not require it before, and still do not).
 1.53 13-Jul-2018  kre branches: 1.53.2;
Remove atoi()

Mostly use number() (no longer implemented using atoi()) when an
unsigned integer is required, but use strtoXXX() when a conversion
is wanted, without the possibility or error (like setting OPTIND
and RANDOM). Always init OPTIND to 1 when sh starts (overriding
anything in environ.)
 1.52 21-Nov-2017  kre branches: 1.52.2; 1.52.4;
Remove the -X option from SMALL shells (as used on boot floppies,
some other install media, mini-roots, etc.) It is unlikely that
such a shell will be used for much script debugging (and the old -x
still exists of course) and it adds a little bloat, so, zap...

The ancient unused (unrelated) xioctl() function is gone as well
(from all shells).
 1.51 19-Nov-2017  kre Implement the -X option - an apparent variant of -x which sends all trace
output to the stderr which existed when the -X option was (last) enabled.
It also enables tracing by enabling -x (and when reset, +X, also resets
the 'x' flag (+x)). Note that it is still -x/+x which actually
enables/disables the trace output. Hence "apparent variant" - what -X
actually does (aside from setting -x) is just to lock the trace output,
rather than having it follow wherever stderr is later redirected.
 1.50 24-Jul-2017  kre PR standards/52406

Absent other information, the shell should be interactive if reading
from stdin, and stdin and stderr are ttys, not stdin and stdout.

So sayeth the great lord posix.
 1.49 29-May-2017  kre branches: 1.49.2;

More DEBUG mode changes. As usual, read the source if you care.
 1.48 18-May-2017  kre Command line, and "set" command options processing cleanup.

sh +c "command string" no longer works (it must be -c)
sh +o and sh -o no longer work (if you could call what they did
before working.) nb: this is without an option name.
-ooo Opt1 Opt2 Opt3 no longer works (set & cmd line), this should be
-o Opt1 -o Opt2 -o Opt3 (same with +ooo of course).
-oOpt is now supported - option value (name of option in
this case) immediately following -o (or +o).
(as with other commands that use std opt parsing)
Both set comamnd and command line.

In addition, the output from "set +o" has shrunk dramatically, by borrowing
a trick from ksh93 (but implemented in a more traditional syntax).
"set +o" is required to produce a command (or commands) which when executed
later, will return all options to the state they were in when "set +o"
was done. Previously that was done by generating a set command, with
every option listed (set -o opt +o other-opt ...) to set them all back
to their current setings. Now we have a new "magic option" ("default")
which sets all options to their default values, so now set +o output
need only be "set -o default -o changed-opt ..." (only the options that
have been changed from their default values need be explicitly mentioned.)
The definition of "default value" for this is the value the shell set the
option to, after startup, after processing the command line (with any
flags, or -o option type settings), but before beginning processing any
user input (incuding startup files, like $ENV etc).

Anyone can execute "set -o default" of course, but only from a "set"
command (it makes no sense at all as a -o option to sh). This also
causes "set +o" to be slightly more useful as a general command, as
ignoring the "set -o default" part of the result, it lists just those
options that have been altered after sh startup. There is no +o default.
There isn't an option called "default" at all...

This causes some of the commented out text from sh.1 to become uncommented.
 1.47 15-May-2017  kre DEBUG mode shell update (changes nothing for shells which are not
compiled for DEBUG.)

Add debug builtin command, and corresponding -D command line option.
As usual, for DEBUG related stuff, read the source for info, that's
all there is about this.

This completes the infrastructure changes for the updated DEBUG TRACE
mechanism, so now converting the rest of the shell's internal tracing
can happen as desired - piecemeal.
 1.46 31-Mar-2016  christos branches: 1.46.6;
Implement the NETBSD_SHELL readonly unexportable unimportable
variable (with its current value set at 20160401) as discussed on
current-users and tech-userlevel. This also includes the necessary
support to implement it properly (particularly the unexportable
part) and adds options to the export command to support unexportable
variables. Also implement the "posix" option (no single letter
equivalent) which gets its default value from whether or not
POSIXLY_CORRECT is set in the environment when the shell starts
(but can be changed just like any other option using -o and +o on
the command line, or the set builtin command.) While there, fix
all uses of options so it is possible to have options that have a
short (one char) name, and no long name, just as it has been possible
to have options with a long name and no short name, though there
are currently none (with no long name). For now, the only use of
the posix option is to control whether ${ENV} is read at startup
by a non-interactive shell, so changing it with set is not usful
- that might change in the future. (from kre@)
 1.45 08-Mar-2016  christos PR bin/50896: make shift with more than 1 arg give a usage message, from kre
 1.44 24-Feb-2016  christos If we don't have shared address space vfork fail back to using fork since
we are depending on the shared address space feature (from kre)
 1.43 20-Mar-2012  matt Use C89 function definitions
 1.42 18-Jun-2011  christos branches: 1.42.2;
PR/45069: Henning Petersen: Use prototypes from builtins.h .
 1.41 18-Jan-2009  lukem branches: 1.41.6;
fix -Wsign-compare issues
 1.40 13-Dec-2005  dsl TOG require that 'set +o' output the options in a form suitable for
restoring them - make it so.
 1.39 15-Jul-2005  christos If we have a script and we are interactive, set interactive to 2. This
allows us to run scripts with -i without printing the prompt like the
other shells do.
 1.38 20-Mar-2005  dsl Add 'continue' as body of empty loop.
 1.37 30-Oct-2004  christos Pass WARNS=3
 1.36 05-Jan-2004  jmmv Homogenize usage messages: make the 'usage' word all lowercase, as this seems
to be the most common practice in our tree.
 1.35 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.34 15-Apr-2003  itojun %d is 12 chars, not 10 chars. hinted by deraadt
 1.33 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.32 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.31 26-Feb-2001  wiz Fix command name in error message for 'sh nonexistingfile'.
 1.30 04-Feb-2001  christos remove redundant declarations and nexted externs.
 1.29 09-Jul-1999  christos compile with WARNS = 2
 1.28 28-Jul-1998  mycroft Be more retentive about use of NOTREACHED and noreturn.
 1.27 28-Jul-1998  mycroft Delint.
 1.26 02-May-1998  christos PR/5315: Dan Winship: options parsing code should print errors to stderr.
 1.25 04-Jul-1997  christos branches: 1.25.2;
Fix compiler warnings.
 1.24 14-Mar-1997  christos NO_HISTORY->SMALL
 1.23 25-Feb-1997  christos Fix PR/3258 sh -c 'echo $0' causes segmentation fault.
 1.22 11-Jan-1997  tls kill 'register'
 1.21 15-Dec-1996  christos Getopts bugs again (I'll never get this right).
- make sure that OPTIND is set correctly even in the absence of options.
- don't keep stale state between getopts calls.
 1.20 24-Nov-1996  christos Fix bug in getopts code where the argument list got truncated.
From Todd Miller.
 1.19 06-Nov-1996  christos Fix miscellaneous getopts problems:
- the 3 argument version of getopts would not reset properly
- OPTARG did not get cleared after a non argument option was found
- OPTIND was not set properly after a non argument option.
 1.18 02-Nov-1996  christos Fix problems that gcc -Wall found (from Todd Miller, OpenBSD)
 1.17 16-Oct-1996  christos PR/2808: POSIX 1003.2: first arg after -c cmd is $0, remainder $1...
(from FreeBSD)
 1.16 25-Jun-1996  christos - Add getoptsreset to be used as a callback function when OPTIND is set.
This is used to implement the POSIX behavior when OPTIND=1
- Call setvarsafe instead of setvar. If one ran
"getopts optstr badvariable"
where badvariable contained an illegal variable name, there was no way
to recover, since setvar() would longjmp on the error.
 1.15 04-Jun-1996  christos getopts fixes:

1. OPTIND value was not computed correctly when the argument was part of the
option string (i.e. for "l:" "-l 1" was working "-l1" was not). (PR/2505).
2. OPTARG was not being unset in case of errors [in the non POSIX error case].
3. optvar could be set to random values.
4. Option string starting with a : was not treated specially as POSIX
specifies (if the option string starts with a :, then there is no
error printed when there are missing option arguments or illegal options,
and OPTARG and optvar are being set specially).
5. Implemented getopts "opts" optvar [arg]. The optional argument case
was not implemented.

To do:
- what does Posix say about resetting the getopts state? Bash does it
by setting OPTIND=0; is that correct? Should we be doing the same thing?
- should we be using getopt(3) for everything internal to the shell? Is that
feasible because we might need to handle multiple invocations at once.
 1.14 11-May-1995  christos branches: 1.14.6;
Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.13 26-Mar-1995  christos Reverted to set - turning off -x and -v. Charles corrected me... It is part
of POSIX.
 1.12 25-Mar-1995  christos set -
does not anymore clear the -x and -v flags. This was incompatible with
all other bourne shell implementations.
 1.11 21-Mar-1995  cgd convert to new RCS id conventions.
 1.10 05-Dec-1994  cgd clean up further. more patches from Jim Jegers
 1.9 04-Dec-1994  cgd from James Jegers <jimj@miller.cs.uwm.edu>: quiet -Wall, and squelch
some of the worst style errors.
 1.8 11-Jun-1994  mycroft Add RCS ids.
 1.7 14-May-1994  cgd add back in support for building w/o obj dir. also, add NO_HISTORY
define, which (if you invoke mkbuiltins properly) gets you a sh w/o
history of command line editing (for floppy sh).
 1.6 12-May-1994  jtc Include appropriate header files to bring function prototypes into scope.
 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.14.6.2 04-Mar-1997  mycroft Pull up latest sh(1). Fixes yet more bugs.
 1.14.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.25.2.1 08-May-1998  mycroft Sync with trunk, per request of christos.
 1.41.6.1 23-Jun-2011  cherry Catchup with rmind-uvmplock merge.
 1.42.2.1 17-Apr-2012  yamt sync with head
 1.46.6.1 19-May-2017  pgoyette Resolve conflicts from previous merge (all resulting from $NetBSD
keywork expansion)
 1.49.2.1 25-Aug-2018  martin Pull up following revision(s) (requested by kre in ticket #988):

bin/sh/parser.c: revision 1.147
bin/sh/var.c: revision 1.70
bin/sh/mystring.c: revision 1.18
bin/sh/options.c: revision 1.53
bin/sh/histedit.c: revision 1.53

Remove atoi()

Mostly use number() (no longer implemented using atoi()) when an
unsigned integer is required, but use strtoXXX() when a conversion
is wanted, without the possibility or error (like setting OPTIND
and RANDOM). Always init OPTIND to 1 when sh starts (overriding
anything in environ.)
 1.52.4.4 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.52.4.3 21-Apr-2020  martin Sync with HEAD
 1.52.4.2 08-Apr-2020  martin Merge changes from current as of 20200406
 1.52.4.1 10-Jun-2019  christos Sync with HEAD
 1.52.2.1 28-Jul-2018  pgoyette Sync with HEAD
 1.53.2.1 06-Nov-2021  martin Pull up following revision(s) (requested by kre in ticket #1371):

bin/sh/main.c: revision 1.87
bin/sh/main.c: revision 1.88
bin/sh/memalloc.h: revision 1.20
bin/sh/sh.1: revision 1.235
bin/sh/memalloc.c: revision 1.34
bin/sh/memalloc.c: revision 1.35
bin/sh/memalloc.h: revision 1.19
bin/sh/shell.h: revision 1.31
bin/sh/options.c: revision 1.56

PR bin/56464

After almost 30 years, finally do the right thing and read $HOME/.profile
rather than .profile in the initial directory (it was that way in version
1.1 ...) All other ash descendants seem to have fixed this long ago.
While here, copy a feature from FreeBSD which allows "set +p" (if a
shell run by a setuid process with the -p flag is privileged) to reset
the privileges. Once done (the set +p) it cannot be undone (a later
set -p sets the 'p' flag, but that's all it does) - that just becomes a
one bit storage location.

We do this, as (also copying from FreeBSD, and because it is the right
thing to do) we don't run .profile in a privileged shell - FreeBSD run
/etc/suid_profile in that case (not a good name, it also applies to setgid
shells) but I see no real need for that, we run /etc/profile in any case,
anything that would go in /etc/suid_profile can just go in /etc/profile
instead (with suitable guards so the commands only run in priv'd shells).

One or two minor DEBUG mode changes (notably having priv'd shells identify
themselves in the DEBUG trace) and sh.1 changes with doc of the "set +p"
change, the effect that has on $PSc and a few other wording tweaks.

XXX pullup -9 (not -8, this isn't worth it for the short lifetime
that has left - if it took 28+ years for anyone to notice this, it
cannot be having all that much effect).

Use a type-correct end marker for strstrcat() rather than NULL, as
for a function with unknown number & types of args, the compiler isn't
able to automatically convert to the correct type. Issue pointed out
in off list e-mail by Rolland Illig ... Thanks.

The first arg (pointer to where to put length of result) is of a known
type, so doesn't have the same issue - we can keep using NULL for that
one when the length isn't needed.
Also, make sure to return a correctly null terminated null string in
the (absurd) case that there are no non-null args to strstrcat() (though
there are much better ways to generate "" on the stack). Since there is
currently just one call in the code, and it has real string args, this
isn't an issue for now, but who knows, some day.

NFCI - if there is any real change, then it is a change that is required.

XXX pullup -9 (together with the previous changes)
 1.58.4.1 02-Aug-2025  perseant Sync with HEAD
 1.28 12-Jul-2024  kre Improve safety in var imports from the environment.

Add a new var flag VUNSAFE - set on all vars imported from the environment.

Add setvareqsafe() (which is to setvareq() as setvarsafe() is to setvar())
and use that instead of setvareq() when processing the environment, so
errors don't cause the shell to abort. Use VUNSAFE in that call.

Add flags arguments to all var callback functions which are used when setting
variables, and pass the flags given to the setvar*() functions to those
functions, so they can act differently in different situations (if desired).
Most of them just ignore the flags.

When unsetting a variable, call setvar() to clear things (and call the
callback function) both when the variable had a value which needs to be freed,
and when unsetting a variable which wasn't unset previously, so the VUNSET
flag can be seen by that callback func.

When setting HISTSIZE, use the flags passed to determine whether to ignore
bad values (if VUNSAFE) or treat them as an error. This replaces the
earlier temporary hack to always ignore bad data there (histedit.c 1.68).

Miscellaneous associated minor changes.

These changes should largely be invisible in normal use.
 1.27 28-May-2017  kre branches: 1.27.10; 1.27.22;
Arrange for set -o and $- output to be sorted, rather than more
or less random (and becoming worse as more options are added.)
Since the data is known at compile time, sort at compile time,
rather than at run time.
 1.26 18-May-2017  kre Command line, and "set" command options processing cleanup.

sh +c "command string" no longer works (it must be -c)
sh +o and sh -o no longer work (if you could call what they did
before working.) nb: this is without an option name.
-ooo Opt1 Opt2 Opt3 no longer works (set & cmd line), this should be
-o Opt1 -o Opt2 -o Opt3 (same with +ooo of course).
-oOpt is now supported - option value (name of option in
this case) immediately following -o (or +o).
(as with other commands that use std opt parsing)
Both set comamnd and command line.

In addition, the output from "set +o" has shrunk dramatically, by borrowing
a trick from ksh93 (but implemented in a more traditional syntax).
"set +o" is required to produce a command (or commands) which when executed
later, will return all options to the state they were in when "set +o"
was done. Previously that was done by generating a set command, with
every option listed (set -o opt +o other-opt ...) to set them all back
to their current setings. Now we have a new "magic option" ("default")
which sets all options to their default values, so now set +o output
need only be "set -o default -o changed-opt ..." (only the options that
have been changed from their default values need be explicitly mentioned.)
The definition of "default value" for this is the value the shell set the
option to, after startup, after processing the command line (with any
flags, or -o option type settings), but before beginning processing any
user input (incuding startup files, like $ENV etc).

Anyone can execute "set -o default" of course, but only from a "set"
command (it makes no sense at all as a -o option to sh). This also
causes "set +o" to be slightly more useful as a general command, as
ignoring the "set -o default" part of the result, it lists just those
options that have been altered after sh startup. There is no +o default.
There isn't an option called "default" at all...

This causes some of the commented out text from sh.1 to become uncommented.
 1.25 31-Mar-2016  christos branches: 1.25.6;
Implement the NETBSD_SHELL readonly unexportable unimportable
variable (with its current value set at 20160401) as discussed on
current-users and tech-userlevel. This also includes the necessary
support to implement it properly (particularly the unexportable
part) and adds options to the export command to support unexportable
variables. Also implement the "posix" option (no single letter
equivalent) which gets its default value from whether or not
POSIXLY_CORRECT is set in the environment when the shell starts
(but can be changed just like any other option using -o and +o on
the command line, or the set builtin command.) While there, fix
all uses of options so it is possible to have options that have a
short (one char) name, and no long name, just as it has been possible
to have options with a long name and no short name, though there
are currently none (with no long name). For now, the only use of
the posix option is to control whether ${ENV} is read at startup
by a non-interactive shell, so changing it with set is not usful
- that might change in the future. (from kre@)
 1.24 23-Feb-2016  christos name the long option after the ksh name (trackall) to indicate the intended
posix behavior not the bash one.
 1.23 23-Feb-2016  christos update that -n is implemented and add -h using the long name that bash
uses. (from kre, long name from me)
 1.22 26-May-2015  christos Drop privileges when executed set{u,g}id unless -p is specified like other
shells do to avoid system() and popen() abuse.
 1.21 02-Jan-2015  christos Define an undocumented -F option to only use fork instead of vfork for
debugging purposes.
 1.20 18-Jun-2011  christos PR/45069: Henning Petersen: Use prototypes from builtins.h .
 1.19 13-Dec-2005  dsl branches: 1.19.40;
TOG require that 'set +o' output the options in a form suitable for
restoring them - make it so.
 1.18 07-May-2005  dsl If 'set -o tabcomplete' it set, then bind <tab> to the libedit filename
completion function.
Note that the libedit code will probably want fine-tuning!
While editing the man page, add a note that non-whitespace IFS chars are
terminators and can generate null arguments.
 1.17 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.16 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.15 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.14 04-Feb-2001  christos remove redundant declarations and nexted externs.
 1.13 09-Jul-1999  christos compile with WARNS = 2
 1.12 04-Feb-1999  cjs Add -q option, which when used with -v and/or -x, turns off the tracing
during the execution of /etc/profile, .profile and $ENV.
 1.11 06-Nov-1996  christos Fix miscellaneous getopts problems:
- the 3 argument version of getopts would not reset properly
- OPTARG did not get cleared after a non argument option was found
- OPTIND was not set properly after a non argument option.
 1.10 16-Oct-1996  christos PR/2808: Remove trailing whitespace (from FreeBSD)
 1.9 25-Jun-1996  christos - Add getoptsreset to be used as a callback function when OPTIND is set.
This is used to implement the POSIX behavior when OPTIND=1
- Call setvarsafe instead of setvar. If one ran
"getopts optstr badvariable"
where badvariable contained an illegal variable name, there was no way
to recover, since setvar() would longjmp on the error.
 1.8 11-May-1995  christos branches: 1.8.6;
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.8.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.19.40.1 23-Jun-2011  cherry Catchup with rmind-uvmplock merge.
 1.25.6.1 19-May-2017  pgoyette Resolve conflicts from previous merge (all resulting from $NetBSD
keywork expansion)
 1.27.22.1 02-Aug-2025  perseant Sync with HEAD
 1.27.10.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.27.10.1 21-Apr-2020  martin Sync with HEAD
 1.42 03-Oct-2024  rillig bin: fix lint warning "effectively discards 'const'"

For example: src/bin/ed/io.c(339): warning: call to 'strchr' effectively
discards 'const' from argument [346]

No binary change.
 1.41 07-Apr-2023  kre branches: 1.41.2;

The great shell trailing whitespace cleanup of 2023...
Inspired by private e-mail comments from mouse@

NFCI.
 1.40 21-Nov-2017  kre branches: 1.40.4;
Remove the -X option from SMALL shells (as used on boot floppies,
some other install media, mini-roots, etc.) It is unlikely that
such a shell will be used for much script debugging (and the old -x
still exists of course) and it adds a little bloat, so, zap...

The ancient unused (unrelated) xioctl() function is gone as well
(from all shells).
 1.39 19-Nov-2017  kre Implement the -X option - an apparent variant of -x which sends all trace
output to the stderr which existed when the -X option was (last) enabled.
It also enables tracing by enabling -x (and when reset, +X, also resets
the 'x' flag (+x)). Note that it is still -x/+x which actually
enables/disables the trace output. Hence "apparent variant" - what -X
actually does (aside from setting -x) is just to lock the trace output,
rather than having it follow wherever stderr is later redirected.
 1.38 19-Nov-2017  kre Rearrange "struct output" to be slightly more friendly (I think)
to I32 P64 systems - keep nextc first, as that's used in macros,
and nleft next, as that's used (and both are updated) in the same macro,
which is used frequently, this increases the chance they're in the
same cache line (unchanged from before). Beyond that it matters less,
so just shuffle a bit to avoid internal padding when pointers are 64 bits.
Note that there are just 3 of these structs (currently), even if there was
to be a memory saving (there probably won't be, trailing padding will eat it)
it would be of the order of 12 or 24 bytes total, so all this really
just panders to my sense of rightness....

Note to anyone who might be tempted, please don't update the struct
initializers to use newer C forms - eventually sh is planned to become
a host tool, and a separable package, so it wants to remain able to be
compiled using older (though at least ansi) compilers that implement only
older C variants.
 1.37 16-Nov-2017  kre Improve quoting in xtrace (-x) output ... if a string ("word") to be
output includes a single quote (') then see if using double-quotes
to quote it is reasonable (if no chars that are magic in " also appear).
If so, and if the string is not entirely the ' character, then
use " quoting. This avoids some ugly looking results (occasionally).

Also, fix a bug introduced about 20 months ago where null strings
in xtrace output are dropped, instead of made explicit ('').
To observe this, before you get the fix: set -x; echo '' (or similar.)

Move a comment from the wrong place to the right place.
 1.36 18-May-2017  kre branches: 1.36.2;

Added comma and plus to the "don't need quoting" set. This affects
output from "sh -x" only (tracing execution), not quoting + is better,
as it makes tracing commands with + and - options, or numbers, more
consistent.

Also one minor white space change (excess indentation removed).
 1.35 12-Mar-2016  christos branches: 1.35.6;
Improve quoting in the output from sh -x - use less unnecessary
quotes ('_' and '.' do not need quoting) and never quote the '=' in
an assignment (or it would not be one.) From kre, with some refactoring
to be blamed to me.
 1.34 28-Feb-2016  christos Bug fixes to handling of unterminated here documents
(they should be, and now are, a syntax error), and
miscellaneous other minor cleanups. (from kre)
 1.33 30-Aug-2010  christos dprintf is claimed by posix.
 1.32 19-Jul-2010  joerg Don't quite `+', `-' and `/' in set -x output.
 1.31 31-Oct-2008  christos show better quoting output for sh -x, from Aleksey Cheusov
 1.30 12-Oct-2008  dholland output.c output.h: expose OUTPUT_ERR (flag for an exposed flags variable)
bltin.h: support ferror()
echo.c: use ferror() to fail on output write errors

Another piece of PR bin/39574.
 1.29 17-Mar-2006  rumble branches: 1.29.4;
Handle asprintf failing to allocate.
 1.28 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.27 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.26 25-May-2002  wiz __STDC__ is always defined on NetBSD, so remove #ifdef __STDC__ (and
unnecessary #else cases).
 1.25 09-Apr-2002  thorpej Move the declaration of digit[] into the #ifdef'd code block that
uses it. Prevents a warning from gcc 3.2.
 1.24 24-Sep-2001  wiz va_{start,end} audit:
Make sure that each va_start has one and only one matching va_end,
especially in error cases.
If the va_list is used multiple times, do multiple va_starts/va_ends.
If a function gets va_list as argument, don't let it use va_end (since
it's the callers responsibility).

Improved by comments from enami and christos -- thanks!

Heimdal/krb4/KAME changes already fed back, rest to follow.

Inspired by, but not not based on, OpenBSD.
 1.23 07-Jan-2001  lukem if HAVE_VASPRINTF (set ifdef BSD4_4), use vasprintf() instead of homegrown
code in doformat(). results in slightly smaller /bin/sh. idea suggested by
Witold J. Wnuk <witek@pd37.warszawa.sdi.tpnet.pl>, approved by christos.
 1.22 07-Jan-2001  lukem support %ll (as synonym for %q) in doformat(), since my changes to %q -> %ll
broke this :/
problem reported in private email by Witold J. Wnuk.
<witek@pd37.warszawa.sdi.tpnet.pl>.
 1.21 31-Jan-1998  christos - Add gcc attributes to printf like functions
- Fix format strings to be const
- Fix buffer length to be size_t
- Add %p format
- Avoid code duplication in varargs/stdarg cases
 1.20 21-Jan-1998  christos BSD4_4 is a standard symbol in <sys/param.h>; make sure that files
that need this defined, include <sys/param.h> and don't define it in
the Makefile. Add a comment to that effect.
 1.19 04-Jul-1997  christos branches: 1.19.2;
Fix compiler warnings.
 1.18 11-Apr-1997  christos Fix so that this compiles on systems without quads and remove the double
inclusion of varargs/stdarg
 1.17 11-Jan-1997  tls kill 'register'
 1.16 16-Oct-1996  christos No need to have 2 declarations for the same constant string, one for K&R and
one for STDC...
 1.15 14-Sep-1995  jtc branches: 1.15.6;
Handle %q format directive; from Mike Long (PR #1454).
 1.14 11-May-1995  christos Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.13 21-Mar-1995  cgd convert to new RCS id conventions.
 1.12 23-Dec-1994  cgd pull prototypes into scope for string functions.
 1.11 05-Dec-1994  cgd clean up further. more patches from Jim Jegers
 1.10 11-Jun-1994  mycroft Add RCS ids.
 1.9 12-May-1994  jtc Include appropriate header files to bring function prototypes into scope.
 1.8 12-May-1994  jtc add const qualifier to get rid of compilation warnings.
 1.7 11-May-1994  jtc sync with 4.4lite
 1.6 04-May-1994  jtc Added const qualifier to char * function arguments to eliminate
compiler warning.
 1.5 05-Sep-1993  mycroft From Vincent Broman:
error.c: Add , in initializer list if ENOLINK defined.
output.c: Gratuitously remove extra ;.
mknodes.c: main() should return a value.
Not from Vincent Broman:
mknodes.c: main() should return an error condition when approriate, too.
 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.15.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.19.2.1 08-May-1998  mycroft Sync with trunk, per request of christos.
 1.29.4.1 18-Nov-2008  bouyer Pull up following revision(s) (requested by dholland in ticket #1232):
bin/echo/echo.c: revision 1.18
bin/sh/bltin/bltin.h: revision 1.13
bin/sh/bltin/echo.c: revision 1.14
bin/sh/output.c: revision 1.30
bin/sh/output.h: revision 1.19
Check ferror(stdout) and exit(1) if there's been a problem.
Fixes PR bin/39574 from Ed Ravin, but with a simpler patch.
output.c output.h: expose OUTPUT_ERR (flag for an exposed flags variable)
bltin.h: support ferror()
echo.c: use ferror() to fail on output write errors
Another piece of PR bin/39574.
 1.35.6.1 19-May-2017  pgoyette Resolve conflicts from previous merge (all resulting from $NetBSD
keywork expansion)
 1.36.2.1 23-Nov-2017  martin Pull up following revision(s) (requested by kre in ticket #384):
bin/sh/output.c: revision 1.37
Improve quoting in xtrace (-x) output ... if a string ("word") to be
output includes a single quote (') then see if using double-quotes
to quote it is reasonable (if no chars that are magic in " also appear).
If so, and if the string is not entirely the ' character, then
use " quoting. This avoids some ugly looking results (occasionally).
Also, fix a bug introduced about 20 months ago where null strings
in xtrace output are dropped, instead of made explicit ('').
To observe this, before you get the fix: set -x; echo '' (or similar.)
Move a comment from the wrong place to the right place.
 1.40.4.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.40.4.1 21-Apr-2020  martin Sync with HEAD
 1.41.2.1 02-Aug-2025  perseant Sync with HEAD
 1.28 10-Nov-2021  kre Add a couple of macro definitions for dealing with shell I/O errors.
(Macros akin to stdio's ferror() and clearerr()).

NFC: the macros are defined, but not yet used anywhere. Uses coming soonish.
 1.27 21-Nov-2017  kre branches: 1.27.4;
Remove the -X option from SMALL shells (as used on boot floppies,
some other install media, mini-roots, etc.) It is unlikely that
such a shell will be used for much script debugging (and the old -x
still exists of course) and it adds a little bloat, so, zap...

The ancient unused (unrelated) xioctl() function is gone as well
(from all shells).
 1.26 19-Nov-2017  kre Implement the -X option - an apparent variant of -x which sends all trace
output to the stderr which existed when the -X option was (last) enabled.
It also enables tracing by enabling -x (and when reset, +X, also resets
the 'x' flag (+x)). Note that it is still -x/+x which actually
enables/disables the trace output. Hence "apparent variant" - what -X
actually does (aside from setting -x) is just to lock the trace output,
rather than having it follow wherever stderr is later redirected.
 1.25 19-Nov-2017  kre Rearrange "struct output" to be slightly more friendly (I think)
to I32 P64 systems - keep nextc first, as that's used in macros,
and nleft next, as that's used (and both are updated) in the same macro,
which is used frequently, this increases the chance they're in the
same cache line (unchanged from before). Beyond that it matters less,
so just shuffle a bit to avoid internal padding when pointers are 64 bits.
Note that there are just 3 of these structs (currently), even if there was
to be a memory saving (there probably won't be, trailing padding will eat it)
it would be of the order of 12 or 24 bytes total, so all this really
just panders to my sense of rightness....

Note to anyone who might be tempted, please don't update the struct
initializers to use newer C forms - eventually sh is planned to become
a host tool, and a separable package, so it wants to remain able to be
compiled using older (though at least ansi) compilers that implement only
older C variants.
 1.24 15-Mar-2012  joerg Add __printflike attribution to use vprintf and friends with an argument
as format string.
 1.23 23-Aug-2011  christos branches: 1.23.2;
add more gcc printf format attributes
 1.22 29-Oct-2010  stacktic Make sh build in debug mode
 1.21 30-Aug-2010  christos dprintf is claimed by posix.
 1.20 31-Oct-2008  christos show better quoting output for sh -x, from Aleksey Cheusov
 1.19 12-Oct-2008  dholland output.c output.h: expose OUTPUT_ERR (flag for an exposed flags variable)
bltin.h: support ferror()
echo.c: use ferror() to fail on output write errors

Another piece of PR bin/39574.
 1.18 29-Mar-2008  apb Remove trailing ';' in definitions of out1c and out2c macros.
 1.17 07-Aug-2003  agc branches: 1.17.16;
Move UCB-licensed code from 4-clause to 3-clause licence.

Patches provided by Joel Baker in PR 22249, verified by myself.
 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 25-May-2002  wiz __STDC__ is always defined on NetBSD.
 1.14 31-Jan-1998  christos - Add gcc attributes to printf like functions
- Fix format strings to be const
- Fix buffer length to be size_t
- Add %p format
- Avoid code duplication in varargs/stdarg cases
 1.13 11-Apr-1997  christos branches: 1.13.2;
#if __STDC__ -> #ifdef __STDC__
 1.12 16-Oct-1996  christos PR/2808: Remove trailing whitespace (from FreeBSD)
 1.11 11-May-1995  christos branches: 1.11.6;
Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.10 21-Mar-1995  cgd convert to new RCS id conventions.
 1.9 05-Dec-1994  cgd clean up further. more patches from Jim Jegers
 1.8 11-Jun-1994  mycroft Add RCS ids.
 1.7 12-May-1994  jtc add const qualifier to get rid of compilation warnings.
 1.6 11-May-1994  jtc sync with 4.4lite
 1.5 04-May-1994  jtc Added const qualifier to char * function arguments to eliminate
compiler warning.
 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.11.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.13.2.1 08-May-1998  mycroft Sync with trunk, per request of christos.
 1.17.16.1 18-Nov-2008  bouyer Pull up following revision(s) (requested by dholland in ticket #1232):
bin/echo/echo.c: revision 1.18
bin/sh/bltin/bltin.h: revision 1.13
bin/sh/bltin/echo.c: revision 1.14
bin/sh/output.c: revision 1.30
bin/sh/output.h: revision 1.19
Check ferror(stdout) and exit(1) if there's been a problem.
Fixes PR bin/39574 from Ed Ravin, but with a simpler patch.
output.c output.h: expose OUTPUT_ERR (flag for an exposed flags variable)
bltin.h: support ferror()
echo.c: use ferror() to fail on output write errors
Another piece of PR bin/39574.
 1.23.2.1 17-Apr-2012  yamt sync with head
 1.27.4.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.27.4.1 21-Apr-2020  martin Sync with HEAD
 1.184 21-Oct-2024  kre Fix processing of unknown variable expansion types.

Our shell is (was) one of the last not to do this correctly.

Expansions are supposed to happen only when the command in which
they occur is being executed, not while it is being parsed.
If the expansion only happens them, errors should only be
detected then.

Make it work like that (I saw after I fixed this that FreeBSD
had done it, long ago, almost the same way - it is kind of an
obvious thing to do).

This will allow code like

if test it is shell X
then
commands using shell X specific expansion ops
else if it is shell Y
then
commands using shell Y specific expansion ops
else ...
fi

Previously expansion errors were detected while parsing, so
if we're not shell X, and don't implement something that it
does (some extension to the standard) that would have generated
a parser syntax error, and the script could not be executed
(despite the line with the error never being executed).

Note that this change does not handle all such possible
extensions, just this one. Others are much harder.

One side effect of this change is that sh will now continue
reading a variable expansion until it locates the terminating
'}' (in ${var} forms) regardless of how broken it obviously
is (to our shell) whereas previously it would have bailed out
as soon as an oddity was spotted.
 1.183 03-Oct-2024  rillig bin: fix lint warning "effectively discards 'const'"

For example: src/bin/ed/io.c(339): warning: call to 'strchr' effectively
discards 'const' from argument [346]

No binary change.
 1.182 12-Jul-2024  kre Implement expandvar() : runs var/arith/cmdsub expansions on var value

expandvar() is like expandenv() and expandstr() - each expands
variable values in different contexts, expandenv() when processing
environment vars at startup (and there is no existing state to lose),
but is always using unsafe data, so never runs command substitutions,
expandstr() while in the middle of processing commands (mostly to
expand the prompt variables, so there is probably half a command
tree in the process of being built) - it uses the promptcmds option
to decide whether to run command substitutions. expandvar() is for
intermediate situations, where a variable is to be used during
processing. It will run command substitutions if the variable
value concerned was not imported from the environment.

There are currently no uses of expandvar(), so this change alters
nothing in the shell - but there will be in the near future.
 1.181 20-Oct-2023  kre branches: 1.181.2;

Work around a probably gcc12 bug in detecting "potentially clobbered"
variables after longjmp() for some architectures (sh3 at least).

This should allow the workaround to disable those warnings for this
file to be removed.

In the affected function the extra var & assignment added should simply
be deleted by any good optimiser, but if not, it doesn't matter, as
performance of this function (expandonstack()) is almost irrelevant.
 1.180 07-Apr-2023  kre The great shell trailing whitespace cleanup of 2023...
Inspired by private e-mail comments from mouse@

NFCI.
 1.179 17-Apr-2022  andvar fix various typos in comments.
 1.178 16-Apr-2022  kre Avoid generating error messages implying that user errors are illegal.
 1.177 08-Dec-2021  andvar s/desireable/desirable/ in comments.
 1.176 05-Dec-2021  msaitoh s/existance/existence/ in comment.
 1.175 16-Nov-2021  kre Fix value of ${LINENO} in "for" commands.

This affects (as best I can tell) only uses of ${LINENO} in PS4
when -x is enabled (and perhaps only when the list contains no
expansions). "for" like "case" (which was already handled) is
special in that it generates trace output before actually executing
any kind of simple command.
 1.174 15-Sep-2021  kre Improve the solution for the 2nd access to a fd which shouldn't
be available ("13") issue reported by Jan Schaumann on netbsd-users.

This fixes a bug in the earlier fix (a day or so ago) which could allow the
shell's idea of which fd range was in use by the script to get wildly
incorrect, but now also actually looks to see which fd's are in use as
renamed other user fd's during the lifetime of a redirection which needs
to be able to be undone (most redirections occur after a fork and are
permanent in the child process). Attempting to access such a fd (as with
attempts to access a fd in use by the shell for its own purposes) is treated
as an attempt to access a closed fd (EBADF). Attempting to reuse the fd
for some other purpose (which should be rare, even for scripts attempting
to cause problems, since the shell generally knows which fds the script
wants to use, and avoids them) will cause the renamed (renumbered) fd
to be renamed again (moved aside to some other available fd), just as
happens with the shell's private fds.

Also, when a generic fd is required, don't give up because of EMFILE
or similar unless there are no available fds at all (we might prefer >10
or bigger, but if there are none there, use anything). This avoids
redirection errors when ulimit -n has been set small, and all the fds >10
that are available have been used, but we need somewhere to park the old
user of a fd while we reuse that fd for the redirection.
 1.173 14-Sep-2021  kre Deal with some issues where fds intended only for internal use
by the shell were available for manipulation by scripts (or the user).
These issues were reported by Jan Schaumann on netbsd-users.

The first allows the user to reference sh internal fds, and is
a simple fix - any sh internal fd is simply treated as if it were closed
when referenced by the script. These fds can be discovered by
examining /proc/N/fd so it is not difficult for a script to discover
which fd it should attempt to access.

The second allows the user to reference a user level fd which is
one that is normally available to it, but at a point where it should
no longer be visible (when that fd has been redirected, for a built
in command, so the original fd needs to be saved so it can be restored,
the saving fd should not be accessible). It is not as easy for the
script to determine which fd to attempt here, as the relevant one
exists only during the lifetime of a built-in command (and similar),
but there are ways in some cases (aside from looking at /proc from
another process).

Fix this one by watching which fds the user script is attempting
to use, and avoid using those as temporary fds. This is possible in
this case as we know what command is being run, before we need to
save the fds it uses. That's different from the earlier case where
when the shell allocates its fds we have no idea what it might
reference later.

Also clean up a couple of other minor code issues (NFC intended) that
I noticed while here...
 1.172 09-Sep-2021  kre Fix a bug with here document processing reported on the austin group list
by oguzismailuysal@gmail.com (2021-09-08) (applies to all ash descendant
shells).

There were places in the parser where newline tokens were handled
without reading any pending here documents (leaving those until a
later newline token).

Eg: in
: << do | for x in xxx
do
do echo $x
done

The here doc text (<<do) should start immediately after the next newline
(which is after xxx). But it wasn't happening until after the following
newline (after the line containing only "do").

Bizarrely, this
: << do | for x in xxx
do echo $x
do
done
"worked" because of that.

For other cases that also failed, see the hard_cases test case in
src/tests/bin/sh/t_here.sh Note that there's nothing magic about
the particular end delimiter word chosen here, any will do, using
the ones selected for the tests (and shown here) simply makes it
all more mysterious! The one here is the exact case reported.

Fix this by reading the here docs when processing newline tokens
when they are encountered in other than the "normal" way. Whether
this catches every possibility is unknown currently - may never be
known for certain, but there are no more I can currently think of.

No pullups needed, this isn't a significant enough bug (ie: no one
actually writes code like this) to warrant that.
 1.171 19-Aug-2020  kre For now, probably forever, prohibit unquoted $ and ` in the names of
functions being defined (they can still be included if quoted).

If we parsed the way POSIX specifies (leaving the exact input text of
$ and ` expansions unaltered, until required to be expanded) this would
not be needed, as the name of a function being defined does not underbo
parameter, command, or arith expansions, so xxx$3() { : ; } would just
work. But for many reasons we don't do that (and are unlikely to ever,
though maintaing both forms might be an option someday) - which led to
very obscure behaviour (if sh were compiled in DEBUG mode, even an abort())
and certainly nothing useful. So just prohibit these uses for now.
(A portable function name must be a "name" so this makes no difference
at all to posix compat applications/scripts).

A doc update is pending (the updated sh.1 also contains updates in other
areas not yet appropriate to commit).
 1.170 14-May-2020  msaitoh Remove extra semicolon.
 1.169 10-Dec-2019  kre Correct a typo in a comment, 08x0 was meant to be 0x80 (duh!). NFC.
 1.168 04-May-2019  kre Fix an (apparent) ancient ash bug, that was apparently fixed sometime
in the past, but managed to re-surface...

The expression "${0+\}}" should expand to "}" not "\}"
Almost all other shells handle it that way (incl FreeBSD & dash).

Issue pointed out by Martijn Dekker.

Add ATF sub-tests for the 4 old var expand operators (${var+word}
${var-word} ${var-word} and ${var?word} - including the forms
with the ':' included) and amongst those tests include test cases
for this issue, so if the bug tries to appear again, we can squash
it quicker. (The newer pattern matching operators are already
well tested as part of testing patterns.)
 1.167 27-Feb-2019  kre Finish the fixes from Feb 4 for handling of random data that
matches the internal CTL* chars.

The earlier fixes handled CTL* char values in var expansions,
but not in various other places they can occur (positional
parameters, $@ $* -- even potentially $0 and ~ expansions,
as well as byte strings generated from a \u in a $'' string).

These should all be correctly handled now. There is a new
ISCTL() macro to make the test, rather than using the old
BASESYNTAX[c]==CCTL form (which us still a viable alternative)
as the new way allows compiler optimisations, and less mem
references, so it should be smaller and faster.

Also, be sure in all cases to remove any CTLESC (or other)
CTL* chars from all strings before they are made available
for any external use (there was one case missed - which didn't
matter when we weren't bothering to escape the CTL* chars at
all.)

XXX pullup-8 (will need to be via a patch) along with the Feb 4 fixes.
 1.166 09-Feb-2019  kre Add a check that the file descriptor mentioned in a N> or N< type
redirect operator is within range of what the code tree node can
hold. Currently this is a no-op change (the new error can never
occur) as the code already checks that N is in range for an int
(and errors if not) and the field in the node in which we store N
is also an int, so we cannot overflow - but fd's do not really need
to be that big (the max a typical kernel supports is < 10000) so
this just adds validation in case it ever happens that we decide we
can save some node size (ie: sh memory) by making that field smaller.

Note this is parse time error detection, and has no bearing upon
the execution time error that will occur if a script attempts to use
an fd that exceeds the process's max fd limit.

NFCI (for now anyway.)
 1.165 04-Feb-2019  kre PR bin/53919

Suppress shell error messages while expanding $ENV (which also causes
errors while expanding $PS1 $PS2 and $PS4 to be suppressed as well).

This allows any random garbage that happens to be in ENV to not
cause noise when the shell starts (which is effectively all it did).

On a parse error (for any of those vars) we also use "" as the result,
which will be a null prompt, and avoid attempting to open any file for ENV.

This does not in any way change what happens for a correctly parsed command
substitution (either when it is executed when permitted for one of the
prompts, or when it is not (which is always for ENV)) and commands run
from those can still produce error output (but shell errors remain suppressed).
 1.164 22-Jan-2019  kre lexical analysis fixes. This fixes the tests just committed in
src/tests/bin/sh/t_here.sh

The "magicq" magic was all wrong - it cannot be simply a parameter
to readtoken1() as its value needs to alter during that routine
(eg: when magicq is set - processing here doc text, or whatever)
and we encountered ${var%pattern} "magicq" needs to be off for
"pattern" - and it wasn't.

To handle this magicq needs to be included in the token stack struct,
and simply init'd from the arg to readtoken1 (which we rename).
Then it can be manipulated as required.

Once we no longer have that problem, some other issues can be cleaned
up as well (some of this unbelievably fragile code was attempting to
cope with this in various ad-hoc - and mostly broken - ways).

Also, remove the magicq parameter from parsebackq() - it was not
used (at all) and should never be, a command substitution, wherever
it appears, always starts a new parsing context. How that applies
to old style command substitutions is less clear, but until we see
some real examples where we're not doing the right thing (slightly
less likely now than before ... nothing has changed here in the
way command substitutions are parsed, but quoting in general is
slightly better) I don't plan on worrying about it.

There are a couple of other minor cleanups, which make no actual
difference (like adding () around the use of the parameter in the
RETURN macro ... which is generally better, but makes no difference
here as the param is always a simple constant.

All the current ATF tests pass.
 1.163 22-Jan-2019  kre NFCI - DEBUG mode only change.

Add tracing of lexical analyser operations. This is deliberately
kept out of the normal "all on" set as it makes a *lot* of noise
when enabled (especially in verbose mode) - but when needed, it
helps (evidence for which is coming soon).

As usual, no doc, you need the sources (and of course, a specially
built sh to even be able to enable it.)
 1.162 21-Jan-2019  kre Fix an amazing crazy botch (of mine) when expanding prompt strings
(PS1 etc) which, if the shell were already exiting, and a prompt
were to be expanded (which only really happens if -x is enabled,
and an exit trap is set, so the commands in the trap need PS4
expanded and written, last thing, before the shell exits) the shell
would instead simply exit when it finished expanding PS4 (before
even writing it, or the xtrace output).

There were more conditions required to set up the environment for
this to actually occur (it seems to only happen when the exit trap
is set in a function, called in a command substitution) but that's
unimportant, the code was nonsense.

Problem noticed by Martijn Dekker.

XXX pullup -8
 1.161 15-Jan-2019  kre pgetc_linecont() needs to use pgetc() rather than pgetc_macro()
so the fake char returned by the latter when an alias ends (which
is there so we can correctly avoid alias recursion) is correctly
ignored where it is not wanted.
 1.160 09-Jan-2019  kre A similar fix to that added in 1.169 of eval.c, but here for when
processing command substitutions. If there is an error while processing,
the any pending queued input should be discarded. From FreeBSD.
 1.159 11-Dec-2018  kre PR standards/42829

Implement parameter and arithmetic expansion of $ENV
before using it as the name of a file from which to
read startup commands for the shell. This continues
to happen for all interactive shells, and non-interactive
shells for which the posix option is not set (-o posix).

On any actual error, or if an attempt is made to use
command substitution, then the value of ENV is used
unchanged as the file name.

The expansion complies with POSIX XCU 2.5.3, though that
only requires parameter expansion - arithmetic expansion
is an extension (but for us, it is much easier to do, than
not to do, and it allows some weird stuff, if you're so
inclined....) Note that there is no ~ expansion (use $HOME).
 1.158 09-Dec-2018  christos comment out unused.
 1.157 03-Dec-2018  kre Yet another foray into the mysterious world of $@ -- this time
to fix the (unusual) idiom "${1+$@}" (the quotes are part of it).
This seems to have broken about 5 or 6 years ago (somewhere
between -6 and -7), I believe.

Note this is not the same as "$@" and also not the same as ${1+"$@"}
(much more common idioms) which both worked.

Also attempt to deal with "" more correctly, especially when it
appears adjacent to "$@" (or one of the similar constructs.)

This stuff is still all as ugly and hackish (and fragile) as is
possible to imagine, but in an effort to allow some of the weirdness
to eventually go away, the parser output has been made more
regular and all quoted (parts of) words always now start with
CTLQUOTEMARK and end with CTLQUOTEEND regardless of where the
quotes appear.

This allows us to tell the difference between """$@" and "$@"
which was impossible before - yet they are required to generate
different output when there are no args (when "$@" simply vanishes).

Needless to say that change had ramifications all over the place.
To simplify any similar change in the future, there are some new
macros that can generally be used to detect the "noise" data when
processing words, rather than open coding that every time (which
meant that there would *always* be one which missed getting
updated...)

Several other bugs (of my making, and older ones) are also fixed.

The aim is that (aside from anything that is detecting the cases
that were broken before - which were all unlikely uses of sh
syntax) these changes should have no external visible impact.

Sure...
 1.156 03-Dec-2018  kre Revamp aliases - as dumb an idea as they are, if we're going
to have them, they should work as documented, not cause core
dumps, reference after free, incorrect replacements, failing
to implement alias after alias, ...

The big comment that ended:
This is a good idea ------- ***NOT***
and the hack it was describing are gone.

Note that most of this was from original CVS version 1.1
code (ie: came from the original import, even before 4.4-Lite
was merged. That is, May 1994. And no-one in 24.5 years
noticed (or at least complained about) all the bugs (or at
least, most of them)).

With these changes, aliases ought to work (if you can call it
that) as they are expected to by POSIX. Now if only we could
get POSIX to delete them (or make them optional)...

Changes partly inspired by similar changes made by FreeBSD,
(as was the previous change to alias.c, forgot ack in commit
log for that one, apologies) but done a little differently,
and perhaps with a slightly better outcome.
 1.155 01-Dec-2018  kre Rename the internal function "makename" to "makeword" to better reflect
what it actually does (makearg would have been an alternative).
While here, notice the one remaining place where it should have been
used, but was left open coded, and consume that one.

NFCI.
 1.154 01-Dec-2018  kre NFC. Need a grain of const
 1.153 18-Nov-2018  kre Rationalise (slightly) the way that expansions are processed
to hide meta-characters in the result when the expansion was
in (double) quotes, and so should not be further processed.

Most of this has been OK for a long while, but \ needs hiding
as well, which complicates things, as \ cannot simply be hidden
in the syntax tables as one of the group of random special characters.

This was fixed earlier for simple variable expansions, but
every variety has its own code path ($var uses different code
than $n which is different than $(...), which is different
again from ~ expansions, and also from what $'...' produces).

This could be fixed by moving them all to a common code path,
but that's harder than it seems. The form in which the data
is made available differs, so one common routine would need
a whole bunch of different "get the next char or indicate end"
methods - probably via passing in an accessor function.
That's all a lot of churn, and would probably slow the shell.

Instead, just make macros for doing the standard tests, and
use those instead of open coding (differently) each time.
This way some of the code paths don't end up forgetting to
handle '\' (which is different than all the others).

This removes one optimisation ... when no escaping is needed
(like just $var (unquoted) where magic chars (think '*') in
the value are intended to remain magic), the code avoided doing
two tests for each char ("do we need escapes" and "is this char
one that needs escaping") by choosing two different syntax
tables (choice made outside the loop) - one of which never
returns the magic "needs escaping" result, and the other does
when appropriate, and then just avoiding the "do we need escapes"
test for each character processed. Then when '\' was fixed,
there needed to be another test for it, as it cannot (for other
reasons) be the same as all the others for which "this char
need escaping" is true. So that added a 2nd test for each char...
Not all the code paths were updated. Hence the bugs...

nb: this is all rarely seen in the wild, so it is no big
surprised that no-one ever noticed.

Now the "use two different syntax tables" is gone (the two
returned the same for '\' which is why '\' needed special
processing) - and in order to avoid two tests for each
char (plus the \ test) we duplicate the loops, one of which
tests each char to see if it needs an escape, the 2nd just
copies them. This should be faster in the "no escapes"
code path (though that is not the point) and perhaps also
in the "escapes needed" path (no indirect reference to
the syntax table - though that would probably be in a
register) but makes the code slightly bigger. For /bin/sh
the text segment (on amd64) has grown by 48 bytes. But
it still uses the same number of 512 byte pages (and hence
also any bigger page size). The resulting file size
(/bin/sh) is identical before and after. So is /rescue/sh
(or /rescue/anything-else).
 1.152 09-Nov-2018  kre PR bin/53712

Avoid crash from redirect on null compound command.
 1.151 08-Nov-2018  kre Allow shells forked to run command substitutions while expanding
prompts to exit when they're done, rather than forcing them to
turn into interactive shells and start reading input ...

Completes a part of the previous changes (just 10+ weeks late...)

Should fix the prompt expansion issue reported by Ca�c on
current-users.
 1.150 19-Aug-2018  kre PR bin/48875 (is related, and ameliorated, but not exactly "fixed")

Import a whole set of tree evaluation enhancements from FreeBSD.

With these, before forking, the shell predicts (often) when all it will
have to do after forking (in the parent) is wait for the child and then
exit with the status from the child, and in such a case simply does not
fork, but rather allows the child to take over the parent's role.

This turns out to handle the particular test case from PR bin/48875 in
such a way that it works as hoped, rather than as it did (the delay there
was caused by an extra copy of the shell hanging around waiting for the
background child to complete ... and keeping the command substitution
stdout open, so the "real" parent had to wait in case more output appeared).

As part of doing this, redirection processing for compound commands gets
moved out of evalsubshell() and into a new evalredir(), which allows us
to properly handle errors occurring while performing those redirects,
and not mishandle (as in simply forget) fd's which had been moved out
of the way temporarily.

evaltree() has its degree of recursion reduced by making it loop to
handle the subsequent operation: that is instead of (for any binop
like ';' '&&' (etc)) where it used to
evaltree(node->left);
evaltree(node->right);
return;
it now does (kind of)
next = node;
while ((node = next) != NULL) {
next = NULL;

if (node is a binary op) {
evaltree(node->left);
if appropriate /* if && test for success, etc */
next = node->right;
continue;
}
/* similar for loops, etc */
}
which can be a good saving, as while the left side (now) tends to be
(usually) a simple (or simpleish) command, the right side can be many
commands (in a command sequence like a; b; c; d; ... the node at the
top of the tree will now have "a" as its left node, and the tree for
b; c; d; ... as its right node - until now everything was evaluated
recursively so it made no difference, and the tree was constructed
the other way).

if/while/... statements are done similarly, recurse to evaluate the
condition, then if the (or one of the) body parts is to be evaluated,
set next to that, and loop (previously it recursed).

There is more to do in this area (particularly in the way that case
statements are processed - we can avoid recursion there as well) but
that can wait for another day.

While doing all of this we keep much better track of when the shell is
just going to exit once the current tree is evaluated (with a new
predicate at_eof() to tell us that we have, for sure, reached the end
of the input stream, that is, this shell will, for certain, not be reading
more command input) and use that info to avoid unneeded forks. For that
we also need another new predicate (have_traps()) to determine of there
are any caught traps which might occur - if there are, we need to remain
to (potentially) handle them, so these optimisations will not occur (to
make the issue in PR 48875 appear again, run the same code, but with a
trap set to execute some code when a signal (or EXIT) occurs - note that
the trap must be set in the appropriate level of sub-shell to have this
effect, any caught traps are cleared in a subshell whenever one is created).

There is still work to be done to handle traps properly, whatever
weirdness they do (some of which is related to some of this.)

These changes do not need man page updates, but 48875 does - an update
to sh.1 will be forthcoming once it is decided what it should say...

Once again, all the heavy lifting for this set of changes comes directly
(with thanks) from the FreeBSD shell.

XXX pullup-8 (but not very soon)
 1.149 22-Jul-2018  kre Part 2 of pattern matching (glob etc) fixes.

Attempt to correctly deal with \ (both when it is a literal,
in appropriate cases, and when it appears as CTLESC when it was
detected as a quoting character during parsing).

In a pattern, in sh, no quoted character can ever be anything other
than a literal character. This is quite different than regular
expressions, and even different than other uses of glob matching,
where shell quoting is not an issue.

In something like

ls ?\*.c

the ? is a meta-character, the * is a literal (it was quoted). This
is nothing new, sh has handled that properly for ever.

But the same happens with
VAR='?\*.c'
and
ls $VAR

which has not always been handled correctly. Of course, in

ls "$VAR"

nothing in VAR is a meta-character (the entire expansion is quoted)
so even the '\' must match literally (or more accurately, no matching
happens - VAR simply contains an "unusual" filename). But if it had
been

ls *"$VAR"

then we would be looking for filenames that end with the literal 5
characters that make up $VAR.

The same kinds of things are requires of matching patterns in case
statements, and sub-strings with the % and # operators in variable
expansions.

While here, the final remnant of the ancient !! pattern matching
hack has been removed (the code that actually implemented it was
long gone, but one small piece remained, not doing any real harm,
but potentially wasting time - if someone gave a pattern which would
once have invoked that hack.)
 1.148 20-Jul-2018  kre First pass at fixing some of the more arcane pattern matching
possibilities that we do not currently handle all that well.

This mostly means (for now) making sure that quoted pattern
magic characters (as well as quoted sh syntax magic chars)
are properly marked, so they remain known as being quoted,
and do not turn into pattern magic. Also, make sure that an
unquoted \ in a pattern always quotes whatever comes next
(which, unlike in regular expressions, includes inside []
matches),
 1.147 13-Jul-2018  kre Remove atoi()

Mostly use number() (no longer implemented using atoi()) when an
unsigned integer is required, but use strtoXXX() when a conversion
is wanted, without the possibility or error (like setting OPTIND
and RANDOM). Always init OPTIND to 1 when sh starts (overriding
anything in environ.)
 1.146 21-Apr-2018  kre branches: 1.146.2;

PR bin/53201

Don't synerr on
${var-anything
more}

The newline in the middle of the var expansion is permitted.

Bug reported by Martijn Dekker from his modernish tests.

XXX pullup-8
 1.145 10-Nov-2017  kre branches: 1.145.2;
PR bin/52715

Correct a (relatively harmless) use after free in prompt expansion
processing [detected by asan.]

Relatively harmless: as (while incorrect) the way the data is (was)
used more or less guaranteed that the buffer contents would be
unaltered until well after they are (were) no longer wanted (this
is the expanded prompt string, it is just output (or copied into
libedit internal storage) and forgotten.

This should make no visible difference to anyone (not using asan or
similar.)

XXX pullup -8
 1.144 21-Aug-2017  kre Add support for $'...' quoting (based upon C "..." strings, with \ expansions.)

Implementation largely obtained from FreeBSD, with adaptations to meet the
needs and style of this sh, some updates to agree with the current POSIX spec,
and a few other minor changes.

The POSIX spec for this ( http://austingroupbugs.net/view.php?id=249 )
[see note 2809 for the current proposed text] is yet to be approved,
so might change. It currently leaves several aspects as unspecified,
this implementation handles those as:

Where more than 2 hex digits follow \x this implementation processes the
first two as hex, the following characters are processed as if the \x
sequence was not present. The value obtained from a \nnn octal sequence
is truncated to the low 8 bits (if a bigger value is written, eg: \456.)
Invalid escape sequences are errors. Invalid \u (or \U) code points are
errors if known to be invalid, otherwise can generate a '?' character.
Where any escape sequence generates nul ('\0') that char, and the rest of
the $'...' string is discarded, but anything remaining in the word is
processed, ie: aaa$'bbb\0ccc'ddd produces the same as aaa'bbb'ddd.

Differences from FreeBSD:
FreeBSD allows only exactly 4 or 8 hex digits for \u and \U (as does C,
but the current sh proposal differs.) reeBSD also continues consuming
as many hex digits as exist after \x (permitted by the spec, but insane),
and reject \u0000 as invalid). Some of this is possibly because that
their implementation is based upon an earlier proposal, perhaps note 590 -
though that has been updated several times.

Differences from the current POSIX proposal:
We currently always generate UTF-8 for the \u & \U escapes. We should
generate the equivalent character from the current locale's character set
(and UTF8 only if that is what the current locale uses.)
If anyone would like to correct that, go ahead.

We (and FreeBSD) generate (X & 0x1F) for \cX escapes where we should generate
the appropriate control character (SOH for \cA for example) with whatever
value that has in the current character set. Apart from EBCDIC, which
we do not support, I've never seen a case where they differ, so ...
 1.143 05-Aug-2017  kre PR bin/52458

Avoid mangling history when editing is enabled, and the prompt contains a \n

Also, allow empty input lines into history when they are being appended to
a previous (partial) command (but not when they would just make an empty entry).

For all the gory details, see the PR.

Note nothing here actually makes prompts containing \n work correctly
when editing is enabled, that's a libedit issue, which will be addressed
some other time.
 1.142 26-Jul-2017  kre PR bin/48498 PR bin/52426

Don't ignore unexpected reserved words after ';'
Don't allow any random token type as a case stmt pattern, only a word.
Those are ancient ash bugs and do not affect correct scripts.

Don't ignore redirects in a case stmt list where the list is nothing but
redirects (if the pattern matches, the redirects should be performed).
That was introduced when a redirect only case stmt list was allowed
(older shells had generated a syntax error.)

Random cleanups/refactoring taken from or inspired by the FreeBSD sh
parser ... use makename() consistently to create a NARG node - we
were using it in a couple of places but most NARG node creation was open
coded. Introduce consumetoken() (from FreeBSD) to handle the fairly
common case where exactly one token type must come next, and we need to
check that, and skip past it when found (or error) and linebreak() (new)
to handle places where optional \n's are permitted.
Both previously open coded.

Simplify list() by removing its second arg, which was only ever used when
handling the end of a `` (old style command substitution). Simply move
the code from inside list() to just after its call in the `` case (from
FreeBSD.)
 1.141 03-Jul-2017  kre Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.

While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
 1.140 30-Jun-2017  kre Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
 1.139 24-Jun-2017  kre Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).

Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).

Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
 1.138 17-Jun-2017  kre Many internal memory management type fixes.

PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)

echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)

(Recently added) Problems with ~ expansion fixed (mem management related).

Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)

And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.

Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,

More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.

[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]

More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).

User visible changes:

Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in

cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END

(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)

With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)

POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).

Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
 1.137 08-Jun-2017  kre (Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
 1.136 08-Jun-2017  kre Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
 1.135 07-Jun-2017  kre Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
 1.134 07-Jun-2017  kre A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)

This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)

The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.

This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).

I would not call the results of this perfect yet, but it is close.
 1.133 07-Jun-2017  kre An initial attempt at implementing LINENO to meet the specs.

Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.

Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)

This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.

POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)

This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.

This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).

Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
 1.132 03-Jun-2017  kre branches: 1.132.2;

When we record an arithmetic expression ($(( ))) as being quoted,
what matters is the quoting state just before we switch into arithmetic
syntax parsing mode, not the state after...

This fixes the regiression introduced earlier today (UTC) where
quoted arithmetic expressions were being subjected to word splitting.
 1.131 03-Jun-2017  kre Fixes to shell expand (that is, $ stuff) from FreeBSD (implemented
differently...)

In particular ${01} is now $1 not $0 (for ${0any-digits})

${4294967297} is most probably now ""
(unless you have a very large number of params)
it is no longer an alias for $1 (4294967297 & 0xFFFFFFFF) == 1

$(( expr $(( more )) stuff )) is no longer the same as
$(( expr (( more )) stuff )) which was sometimes OK, as in:
$(( 3 + $(( 2 - 1 )) * 3 ))
but not always as in:
$(( 1$((1 + 1))1 ))
which should be 121, but was an arith syntax error as
1((1 + 1))1
is meaningless.

Probably some more. This also sprinkles a little const, splits a big
func that had 2 (kind of unrelated) purposes into two simpler ones,
and avoids some (semi-dubious) modifications (and restores) in the input
string to insert \0's when they were needed.
 1.130 29-May-2017  kre NFC (normal builds): DEBUG only change - convert parser to newer trace method.

parser tracing is useful when debugging the parser (which admittedly is
fairly often...) but there is a lot of it, and it gets in the way when
looking at something else. Now we can turn it off when not wanted.
 1.129 27-May-2017  kre More standard (and saner) implementation of the ! reserved word.
Unless the shell is compiled with the (compilation time) option
BOGUS_NOT_COMMAND (as in CFLAGS+=-DBOGUS_NOT_COMMAND) which it
will not normally be, the ! command (reserved word) will only
be permitted at the start of a pipeline (which includes the
degenerate pipeline with no '|'s in it of course - ie: a simple cmd)
and not in the middle of a pipeline sequence (no "cmd | ! cmd" nonsense.)
If the latter is really required, then "cmd | { ! cmd; }" works as
a standard equivalent.

In POSIX mode, permit only one ! ("! pipeline" is ok. "! ! pipeline" is not).
Again, if needed (and POSIX conformance is wanted) "! { ! pipeline; }"
works as an alternative - and is safer, some shells treat "! ! cmd" as
being identical to "cmd" (this one did until recently.)
 1.128 14-May-2017  kre NFC: changes to comments only - expand/add comments relating to ${#...}
parsing, and all its peculiarities.
 1.127 11-May-2017  kre Fix some parser weirdness...
${#VAR:-foo} (or any other modifier on ${#VAR} is a syntax error.
On the other hand ${##} is not, nor is ${##13} though they mean
quite different things (the latter is an idiom everyone should learn,
... $# except we refuse to admit the possibility that it is 13...
Even I cannot explain what ${#-foo} used to do, but it wasn't sane!
(It should be just $# as $# is never unset, but ...)
Shell syntax is truly a wondrous thing!
 1.126 10-May-2017  kre NFC: Whitespace, KNF, and (some) consistency.
 1.125 09-May-2017  kre If we are going to permit
! ! pipeline
(And for now the other places where ! is permitted)
we should at least generate the logically correct exit
status:
! ! (exit 5); echo $?
should print 1, not 5. ksh and bosh do it this way - and it makes sense.
bash and the FreeBSD sh echo "5" (as did we until now.)
dash, zsh, yash all enforce the standard syntax, and prohibit this.
 1.124 09-May-2017  kre Remove bogus extra \n from syntax error message.
 1.123 04-May-2017  kre Implement the ';&' (used instead of ';;') case statement list terminator
which causes fall through the to command list of the following pattern
(wuthout evaluating that pattern). This has been approved for inclusion
in the next major version of the POSIX standard (Issue 8), and is
implemented by most other shells.

Now all form a circle and together attempt to summon the great wizd
in the hopes that his magic spells can transform the poor attempt
at documenting this feature into something rational...
 1.122 03-May-2017  kre Fix the heredoc line counting bug that I caused when the heredoc
processing was changed just over a year ago (rev 1.111).
 1.121 03-May-2017  kre Deal with \newline line continuations more correctly.
They can occur anywhere (*anywhere*) not only where it
happens to be convenient to the parser...

This fix from FreeBSD (thanks again folks).

To make this work, pushstring()'s signature needed to change to allow a
const char * as its string arg, which meant sprinkling some const other
places for a brighter appearance (and handling fallout).

All this because I wanted to see what number would come from

echo $\
{\
L\
I\
N\
E\
N\
O\
}

and was surprised at the result! That works now...

The bug would also affect stuff like

true &\
& false

and all kinds of other uses where the \newline occurred in the
"wrong" place.

An ATF test for sh syntax is coming... (sometime.)
 1.120 01-Jun-2016  kre branches: 1.120.6;

PR bin/51145 PR bin/48489
More fixes to the shell parser to prevent empty simple commands (where
empty means no significant text at all) - as discussed on tech-userlevel
this still allows { } (which can be useful in function definitions, not
really anywhere else though) except in posix mode. ( ) now generates
a syntax error, as should any other place where commands are required but
nothing is present. (nb, redirections, var assignments, even var expansions
that expand to nothing, are all OK, and avoid the error - just comments, or
whits space, are not.) This is (aside from allowing { } at all) all in
accordance with the posix spec.
 1.119 09-May-2016  kre PR bin/48489 -- Shell "simple commands" are now not allowed to be
completely empty, they must have something (var assignment, redirect,
or command, or multiple of those) to avoid a syntax error. This
matches the requirements of the grammar in the standard. Correct the
parser (using FreeBSD's sh as a guide) and update the man page to
remove text that noted a couple of places this was previously OK.

OK christos@
 1.118 03-May-2016  kre Allow function names to be any shell word not containing '/'.
This allows anything that could be a filesystem command to be
implemented as a function instead. The restriction on '/'
is because of the way that functions are (required to be) searched
for relative to PATH searching - a function with a name containing '/'
could never be executed, so simply prohibit defining such a thing.

ok christos@
 1.117 02-May-2016  christos Fix handing of user file descriptors outside the 0..9 range.
Also, move (most of) the shell's internal use fd's to much
higher values (depending upon what ulimit -n allows) so they
are less likely to clash with user supplied fd numbers. A future
patch will (hopefully) avoid this problem completely by dynamically
moving the shell's internal fds around as needed. (From kre@)
 1.116 04-Apr-2016  christos Allow a heredoc to be positioned outside a `` command substitution.
POSIX just says "here docs begin after the next newline [token]".
Nothing about "provided it is inside any `` the redirect operator
appears in... As best I can tell, NetBSD now has the only shell to
handle this "correctly" (which raises the question whether it is
correct - but if not, only erroneous scripts are affected.)
This is required by some (probably broken) autoconfigure related
scripts. (from kre@)
 1.115 31-Mar-2016  christos After discussions with Jilles Tjoelker (FreeBSD shell) and
following a suggestion from him, the way the fix to PR bin/50993
was implemented has changed a little. There are three steps involved
in processing a here document, reading it, parsing it, and then
evaluating it before applying it to the correct file descriptor for
the command to use. The third of those is not related to this
problem, and has not changed. The bug was caused by combining the
first two steps into one (and not doing it correctly - which would be
hard that way.) The fix is to split the first two stages into
separate events. The original fix moved the 2nd stage (parsing)
to just immediately before the 3rd stage (evaluation.) Jilles
pointed out some unwanted side effects from doing it that way, and
suggested moving the 2nd stage to immediately after the first.
This commit makes that change. The effect is to revert the changes
to expand.c and parser.h (which are no longer needed) and simplify
slightly the change to parser.c. (from kre@)
 1.114 31-Mar-2016  christos PR bin/51027 - fix the parsing of references to shell parameters
when given without braces (ie: $2 etc). Only the first 9 shell
parameters ($1 .. $9) and the special parameter ($0) can be
referenced this way, $10 is ${1}0 not ${10}. Make it so.
This bug brought to notice by Sven Mascheck's web pages which
discuss (among other things) the history of this (and other ash
based) shells .. see http://www.in-ulm.de/~mascheck/ (from kre@)
 1.113 31-Mar-2016  christos This is an internally visible change - no effect visible to the
user is expected. With the previous commits to parser.c, we no
longer need to handle reading here documents in the (massive)
readtoken1() function. That allows its code to be simplified and
made easier to read and understand (several goto's goto goto heaven.
RIP) (from kre@)
 1.112 27-Mar-2016  christos Move the parseredir internal subroutine out of readtoken1() into being
a real function of its own (also inspired by FreeBSD - though for
this one other sh differences require slightly different code.) (from kre@)
 1.111 27-Mar-2016  christos PR bin/50993 - this is a significant rewrite of the way that here
documents are processed. Now, when first detected, they are
simply read (the only change made to the text is to join lines
ended with a \ to the subsequent line, otherwise end marker detection
does not work correctly (for here docs with an unquoted endmarker
only of course.) This patch also moves the "internal subroutine"
for looking for the end marker out of readtoken1() (which had to
happen as readtoken1 is no longer reading the here doc when it is
needed) - that uses code mostly taken from FreeBSD's sh (thanks!)
and along the way results in some restrictions on what the end
marker can be being removed. We still do not allow all we should.
(from kre@)
 1.110 27-Mar-2016  christos Cease "support" for <redirect> fn() { ...
Any redirect (or redirects) before a function definition were
allowed by the parser, but otherwise totally ignored. The standard
syntax does not permit redirects there, now, neither do we. (from kre@)
 1.109 27-Mar-2016  christos Finish constifying the new parsebackquote() function. Save a
variable or two... Should change nothing. (from kre@)
 1.108 27-Mar-2016  christos General KNF and source code cleanups, avoid scattering the
magic string " \t\n" all over the place, slightly improved
syntax error messages, restructured some of the code for
clarity, don't allow IFS to be imported through the environment,
and remove the (never) conditionally compiled ATTY option.
Apart from one or two syntax error messages, and ignoring IFS
if present in the environment, this is intended to have no
user visible changes. (from kre@)
 1.107 21-Mar-2016  christos fix constness (from kre)
 1.106 20-Mar-2016  christos Move the command substitution "internal subroutine" part of
readtoken1() into a real function of its own (inspired by a
similar change made by FreeBSD - the other internal routines
they moved out are expected to move out here as well soon.)
This change helps avoid gcc 5.3 demanded (not required!) volatile
noise which would slow down parsing. (from kre)
 1.105 18-Mar-2016  christos sprinkle more volatile (needed for the rescue build with gcc-5.3)
 1.104 08-Mar-2016  christos put back some volatile, gcc complains (x86_64)
 1.103 08-Mar-2016  christos Remove most volatility from readtoken1() restoring execution
speed to approximately where it was before the changes made
in version 1.96 (which assumed this would eventually happen.)
 1.102 28-Feb-2016  christos Bug fixes to handling of unterminated here documents
(they should be, and now are, a syntax error), and
miscellaneous other minor cleanups. (from kre)
 1.101 27-Feb-2016  christos remove useless casts
 1.100 27-Feb-2016  christos CID 1354293: handle EOF
 1.99 23-Feb-2016  christos Fix quoting inside heredoc's. (from kre)
 1.98 22-Feb-2016  christos PR bin/43469 - correctly handle quoting of the pattern part of ${var%pat}
type expansions. (from kre)
 1.97 22-Feb-2016  christos Fix for PR bin/48631 - allow commands controlled
by case statements to be nothing more than redirects (from kre)
 1.96 22-Feb-2016  christos Finish the fix for PR/48631 - that is, make the parser correctly
handle the token syntax it really should be handling (including
some that posix does not require, but is right anyway.) This is
quite similar to, and to some extent inspired by the way the FreeBSD
sh parser.c works, but the actual implementation is quite different.
(from kre)
 1.95 22-Feb-2016  christos KNF / whitespace fixes. No changes of substance. (from kre)
 1.94 19-Feb-2016  christos PR/50827: Richard Hansen: Fix default variable assignment with arithmetic,
from kre.
 1.93 29-Aug-2014  christos remove unused assignment
 1.92 29-Aug-2014  christos Eat trailing backslash like bash and pdksh (not zsh). CBACK+CEOF = TEOF
 1.91 19-Aug-2014  christos PR/49125: Havard Eidnes: /bin/sh does not support redirecting to or from FDs > 9
According to:
http://pubs.opengroup.org/onlinepubs/009604599/utilities/xcu_chap02.html#tag_02_07

Redirection support for fds > 9 is optional but allowed.
 1.90 01-Jan-2014  christos branches: 1.90.4;
whitespace fixes
 1.89 01-Jan-2014  christos There was a case where \n did not increase plinno
 1.88 01-Jan-2014  christos clarify further.
 1.87 01-Jan-2014  christos explain the previous fix.
 1.86 31-Dec-2013  christos allow case statement without any patterns.
 1.85 02-Oct-2013  christos add stdio.h
 1.84 02-Oct-2013  christos add crude $LINENO support for FreeBSD
 1.83 17-Jun-2012  wiz branches: 1.83.2;
Initialize two variables for clang.
 1.82 28-Mar-2012  christos include <limits.h> for CHAR_MIN/CHAR_MAX
 1.81 25-Mar-2012  christos PR/43597: Don't break from parsing word tokens in we are in double quotes.
Fixes: sh -c 'echo "${foo:="first-word"} second-word"'
 1.80 31-Aug-2011  plunky branches: 1.80.2; 1.80.4;
NULL does not need a cast
 1.79 13-Dec-2010  christos PR/44229: Henning Petersen: Remove dup check for whitespace.
 1.78 17-Nov-2010  christos revert again, since this breaks libtool amongst other things.
 1.77 16-Nov-2010  christos PR/43469: Antii Kantee: test/util/sh/t_expand:strip fails.
Bring back fixes from revision 1.75:

- Fix a couple of bugs to make the following two echo statements print the
same output as they should:

line='#define bindir "/usr/bin" /* comment */'
echo "${line%%/\**}"
echo ${line%%/\**}

1. ISDBLQUOTE() was not working properly for non VSNORMAL expansions because
varnest was incremented before the variable was completely parsed. Add
an insub adjustment to keep track of that.
2. When we have a quoted backslash, we either need to escape twice, because
one level of escaping will be stripped later (in the variable substitution
case) or simply enter the backslash.
 1.76 14-Nov-2010  christos revert previous. breaks other stuff.
 1.75 14-Nov-2010  christos - Fix a couple of bugs to make the following two echo statements print the
same output as they should:

line='#define bindir "/usr/bin" /* comment */'
echo "${line%%/\**}"
echo ${line%%/\**}

1. ISDBLQUOTE() was not working properly for non VSNORMAL expansions because
varnest was incremented before the variable was completely parsed. Add
an insub adjustment to keep track of that.
2. When we have a quoted backslash, we need to escape twice, because one
level of escaping will be stripped later. (XXX: Do that when insub == 1
only?)

- Make macros statements
 1.74 18-Jan-2009  lukem fix -Wsign-compare issues
 1.73 08-Nov-2008  christos and if you don't succeed twice, try again.
 1.72 07-Nov-2008  christos Try a different fix for PR/11317: Don't ignore errors in list().
 1.71 07-Nov-2008  christos Break PR/11317 again. The counting parentheses fix does not handle case
statements properly. Fixes PR/39873.
 1.70 05-Nov-2008  christos PR/11317: Hubert Feyrer: Recognize mismatched parentheses inside old style
command substitution.
 1.69 23-Aug-2008  christos Fix here documents that end abruptly without NL before EOF.
(Andy Shevchenko)
 1.68 25-Apr-2008  christos branches: 1.68.2;
Detect unmatched quotes inside old style command substitution.
echo `"`
 1.67 27-Feb-2008  dsl branches: 1.67.2;
Change spaces to tabs for consistency with adjacent lines.
 1.66 15-Dec-2007  perry branches: 1.66.2;
convert __attribute__s to applicable cdefs.h macros
 1.65 07-Jun-2007  dsl branches: 1.65.4;
Fix sh -c 'true && ! true | false; echo $?'
Add some more TRACE((...)) calls to aid such debugging.
Fixes PR bin/36435
Clearly no one tried this test when the changes of rev 1.31 and 1.44 were done!
 1.64 13-Jan-2007  christos PR/35410: Valeriy E. Ushakov: /bin/sh mishandles shell function definitions
with function names that are not plain words
1. remove the escape annotations from the function name.
2. check if the function has a valid name before storing it.
 1.63 16-Oct-2006  christos branches: 1.63.2; 1.63.4;
sprinkle volatile.
 1.62 04-Oct-2006  christos Prefix "Syntax Error" with the program name, if the command name is not
available. At least this way we get an idea of what program gives us the
message.
 1.61 20-Jun-2006  christos PR/33775: YAMAMOTO Takashi: /bin/sh doesn't accept "(" before case patterns
 1.60 10-May-2006  mrg quell GCC 4.1 uninitialised variable warnings.

XXX: we should audit the tree for which old ones are no longer needed
after getting the older compilers out of the tree..
 1.59 21-Mar-2005  dsl Back out previous, amongst other things it breaks $((0x10))
 1.58 20-Mar-2005  dsl Treat $((x)) as equivalent to $(($x)) - posix seems to require this now.
 1.57 27-Jun-2004  dsl Fix treatment of ' inside a 'here document' with a quoted EOF marker.
Fixes a breakage from the previous version.
 1.56 26-Jun-2004  dsl Correctly apply IFS to unquoted text in ${x-text}.
Fixes PR/26058 and the 'for i in ${x-a b c}; do ...' and ${x-'a b' c}.
I can't find a PR for the latter problem.
Regression test goind in shortly.
 1.55 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.54 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.53 15-May-2002  christos implement noclobber. From Ben Harris, with minor tweaks from me. Two
unimplemented comments to go. Go Ben!
 1.52 20-Feb-2002  christos enami convinced me that it is a good idea to use the first word of
the allocated area.
 1.51 12-Feb-2002  christos Since we should be able to handle nested double quotes, don't use
the syntax maps to determine the beginning and end quotes (kill
CENDQUOTE). Handle single quotes opening and closing via checking
the current syntax map. Keep a bitmap of doublequote state one bit
per variable nesting level. For the first 32 nested double quotes,
we don't need any additional memory, but for more we allocate
dynamically.
 1.50 12-Feb-2002  ross back this directory up a day, systems won't even boot (rc.subr splodes)

suggested back-to-the-drawing-board test: $ echo "${PWD:-notlikely}"
 1.49 11-Feb-2002  christos PR/15579: Alan Barrett: }'s inside variable specs were taken into account
even if quoted:
foo=${foo:-"'{}'"}; echo $foo
would display '{'} instead of '{}'.
 1.48 02-Nov-2001  christos Fix switch alias handling. Inspired from FreeBSD, but corrected to handle
alias expansion inside the switch as appropriate. This is achieved by a
flag noalias which is turned on and off in as we parse. In the following
example [1] and [0] indicate the value of noalias.

[0] case <expr> in
[1] <lit> ) [0] <expr> ;;
[1] <lit> ) [0] <expr> ;;
...
[1] esac [0]

FreeBSD does:

[0] case <expr> in [1]
<lit> ) <expr> ;;
<lit> ) <expr> ;;
...
esac [0]

This handles the following shell script:

alias a=ls

case $1 in
a) echo a;
a;;
f) echo f;;
*) echo default;;
esac
 1.47 03-Apr-2001  christos PR/12533: Koji Mori: eval gets misparsed when it has a trailing semi-colon.
 1.46 04-Feb-2001  christos remove redundant declarations and nexted externs.
 1.45 27-Jul-2000  cgd un-__P functions declared in parser.h. host programs include parser.h,
and so it shouldn't use __P. (this should probably be done better, by
not declaring the parser functions in headers used by host programs,
but this works well enough.)
 1.44 27-Jan-2000  christos branches: 1.44.4;
Fix bin/9184, bin/9194, bin/9265, bin/9266
Exitcode and negation problems (From Martin Husemann)
 1.43 09-Jul-1999  christos compile with WARNS = 2
 1.42 04-Feb-1999  christos PR/4966: Joel Reicher: Implement <> redirections which are documented in
the man page.
 1.41 25-Jan-1999  mycroft Patches from Tor Egge (via Havard Eidnes) to fix various bugs in field
splitting and combining.
(Note: Some of this are not strictly bugs, but differences between traditional
Bourne shell and POSIX.)
 1.40 26-Sep-1998  itohy Fixed memory leak on old style command substitution
such as sh -c 'echo `echo foo`' .
The memory allocated with ckmalloc() at
parser.c:1349:readtoken1() (search for "done:" label)
was never freed.

I changed this to use 'string stack' framework of Ash.
Note that a string on string stack is properly freed on
exception and end of command parsing, and no explicit free
or signal handlings required.
See TOUR for an overview, and memalloc.[ch] for details
of string stack.
 1.39 28-Jul-1998  mycroft Be more retentive about use of NOTREACHED and noreturn.
 1.38 29-Mar-1998  mrg - change "extern" variables into int's
- remove extern'd variables not actually referenced
- don't use char as an array index
 1.37 15-Jul-1997  christos branches: 1.37.2;
Fix Sparcworks warnings.
 1.36 04-Jul-1997  christos Fix compiler warnings.
 1.35 14-Mar-1997  christos NO_HISTORY->SMALL
 1.34 26-Jan-1997  christos Fix parsing problem introduced in the previous ${10} fix, where $#digit
or $digit# would get mis-parsed as a positional parameter.
 1.33 24-Jan-1997  christos enable parsing of multi-digit positional arguments i.e. ${10} works and it
is not a bad substitution.
 1.32 11-Jan-1997  tls kill 'register'
 1.31 25-Nov-1996  christos - fix parsing bug reported by mycroft: ! was only recognized in the beginning
of pipelines. Now we are recognizing it everywhere like ksh, so:

! if [ a = b ]; then ! echo c && ! true; else ! echo d; fi

works.
 1.30 16-Oct-1996  christos PR/2808: - detect eof inside backquotes
- handle && and || shortcircuits properly
- tokens.def -> tokens.h
(from FreeBSD)
 1.29 09-May-1996  christos branches: 1.29.4;
Close PR/2384 backquoted backslash-newline was not eaten.
 1.28 05-Mar-1996  christos - parser.c: Fix prompting in old style backquote expansion. Fixes PR/2139
and many user complaints why the shell hangs in echo "`"
- eval.c: Fix exitstatus invalid resetting in `if' statements were:
if (exit 3); then
echo foo $?
else
echo bar $?
fi
printed 'bar 0' instead of bar 3
 1.27 19-Oct-1995  christos - fix PR1620, -DNO_HISTORY did not work.
- restore parsing state after parsing old style command substitution.
The ';' in '`echo z;`' broke the following:
for i in 1; do
cat > /dev/tty << __EOF__
`echo z;`
__EOF__
done

cVS: Enter Log. Lines beginning with `CVS: ' are removed automatically
 1.26 17-May-1995  christos Fixed bug where ${#} was interpreted incorrectly as ${#var} and thus
misparsed. Keith Bostic reported it.
 1.25 11-May-1995  christos Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.24 21-Mar-1995  cgd convert to new RCS id conventions.
 1.23 23-Jan-1995  christos I added the documented in the manual but not implemented variable expansions:

${#WORD}
${WORD%PAT}
${WORD%%PAT}
${WORD#PAT}
${WORD##PAT}
 1.22 05-Dec-1994  cgd clean up further. more patches from Jim Jegers
 1.21 23-Sep-1994  mycroft Eliminate uses of some obsolete functions.
 1.20 24-Aug-1994  mycroft Fix a core dump and another parse error related to null commands.
 1.19 07-Jul-1994  mycroft Fix some problems with empty commands.
 1.18 14-Jun-1994  jtc branches: 1.18.2;
From Christos:
1. Fix `-' quoting in [ ] expressions.
2. Fix expansion of variables in redirections
 1.17 11-Jun-1994  mycroft Add RCS ids.
 1.16 01-Jun-1994  jtc Fixed another case statement parsing bug that was introduced by my
last fix :-(. Thanks to Theo for letting me know about it...
 1.15 30-May-1994  jtc Re-worked case statement parsing. With luck, this fixes bug #268.
 1.14 21-May-1994  cgd a few more things to omit when NO_HISTORY defined. from noel@cs.oberlin.edu
 1.13 17-May-1994  jtc Fix backslash parsing within backquoted string
 1.12 11-May-1994  jtc Mark Weaver's background/list fix (for bug #236)
 1.11 11-May-1994  jtc sync with 4.4lite
 1.10 09-Sep-1993  cgd from jim wilson: (command): Handle TEOF like TNL.
 1.9 06-Sep-1993  mycroft Make `>file;' work.
 1.8 01-Aug-1993  mycroft Add RCS identifiers.
 1.7 15-Jul-1993  jtc Another change from Jim Wilson.
 1.6 07-Jul-1993  jtc IEEE 1003.2 (D11.2.2.3) requires that the system's true and false be accessed
instead of searching $PATH. The best way to satisfy this requirement is to
make them builtins.

True was allready builtin, this patch adds false.
 1.5 02-May-1993  sef Jim "wilson@moria.cygnus.com" Wilson's patches to make C News (and other
things) work.
 1.4 26-Apr-1993  dpassage Fixed incorrect calls to longjmp.
 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.18.2.2 24-Aug-1994  mycroft update from trunk
 1.18.2.1 08-Jul-1994  cgd from trunk: Fix some problems with empty commands.
 1.29.4.2 26-Jan-1997  rat Pullup request 1.33 -> 1.34 from Christos Zoulas.
"Fix parsing problem introduced in the previous ${10} fix, where $#digit
or $digit# would get mis-parsed as a positional parameter."
 1.29.4.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.37.2.1 08-May-1998  mycroft Sync with trunk, per request of christos.
 1.44.4.1 25-Nov-2001  he Pull up revision 1.48 (requested by hubertf):
Prevent alias expansion in case labels, where it is unwanted.
 1.63.4.1 03-Sep-2007  wrstuden Sync w/ NetBSD-4-RC_1
 1.63.2.2 13-Jun-2007  liamjfoy Pull up following revision(s) (requested by dsl in ticket #718):
bin/sh/parser.c: revision 1.64
PR/35410: Valeriy E. Ushakov: /bin/sh mishandles shell function definitions
with function names that are not plain words
1. remove the escape annotations from the function name.
2. check if the function has a valid name before storing it.
 1.63.2.1 13-Jun-2007  liamjfoy Pull up following revision(s) (requested by dsl in ticket #719):
bin/sh/parser.c: revision 1.65
Fix sh -c 'true && ! true | false; echo $?'
Add some more TRACE((...)) calls to aid such debugging.
Fixes PR bin/36435
Clearly no one tried this test when the changes of rev 1.31 and 1.44 were done!
 1.65.4.2 23-Mar-2008  matt sync with HEAD
 1.65.4.1 09-Jan-2008  matt sync with HEAD
 1.66.2.1 24-Mar-2008  keiichi sync with head.
 1.67.2.1 18-May-2008  yamt sync with head.
 1.68.2.1 18-Sep-2008  wrstuden Sync with wrstuden-revivesa-base-2.
 1.80.4.1 27-Aug-2016  bouyer Pull up following revision(s) (requested by kre in ticket #1397):
bin/sh/parser.c: revision 1.114 via patch
PR bin/51027 - fix the parsing of references to shell parameters
when given without braces (ie: $2 etc). Only the first 9 shell
parameters ($1 .. $9) and the special parameter ($0) can be
referenced this way, $10 is ${1}0 not ${10}. Make it so.
This bug brought to notice by Sven Mascheck's web pages which
discuss (among other things) the history of this (and other ash
based) shells .. see http://www.in-ulm.de/~mascheck/ (from kre@)
 1.80.2.3 22-May-2014  yamt sync with head.

for a reference, the tree before this commit was tagged
as yamt-pagecache-tag8.

this commit was splitted into small chunks to avoid
a limitation of cvs. ("Protocol error: too many arguments")
 1.80.2.2 30-Oct-2012  yamt sync with head
 1.80.2.1 17-Apr-2012  yamt sync with head
 1.83.2.1 19-Aug-2014  tls Rebase to HEAD as of a few days ago.
 1.90.4.2 10-Dec-2018  martin Pull up following revision(s) (requested by kre in ticket #1663):

bin/sh/parser.c: revision 1.152 (via patch)

PR bin/53712

Avoid crash from redirect on null compound command.
 1.90.4.1 27-Aug-2016  bouyer Pull up following revision(s) (requested by kre in ticket #1212):
bin/sh/parser.c: revision 1.114 via patch
PR bin/51027 - fix the parsing of references to shell parameters
when given without braces (ie: $2 etc). Only the first 9 shell
parameters ($1 .. $9) and the special parameter ($0) can be
referenced this way, $10 is ${1}0 not ${10}. Make it so.
This bug brought to notice by Sven Mascheck's web pages which
discuss (among other things) the history of this (and other ash
based) shells .. see http://www.in-ulm.de/~mascheck/ (from kre@)
 1.120.6.2 19-May-2017  pgoyette Resolve conflicts from previous merge (all resulting from $NetBSD
keywork expansion)
 1.120.6.1 11-May-2017  pgoyette Sync with HEAD
 1.132.2.7 12-Nov-2018  martin Pull up following revision(s) (requested by kre in ticket #1086):

bin/sh/parser.c: revision 1.152

PR bin/53712

Avoid crash from redirect on null compound command.
 1.132.2.6 10-Sep-2018  martin Pull up following revision(s) via patch (requested by kre in ticket #1015):

bin/sh/expand.c: revision 1.124
bin/sh/expand.c: revision 1.127
bin/sh/parser.c: revision 1.148
bin/sh/parser.c: revision 1.149
bin/sh/syntax.c: revision 1.6
bin/sh/syntax.h: revision 1.9 (partial)

First pass at fixing some of the more arcane pattern matching
possibilities that we do not currently handle all that well.

This mostly means (for now) making sure that quoted pattern
magic characters (as well as quoted sh syntax magic chars)
are properly marked, so they remain known as being quoted,
and do not turn into pattern magic. Also, make sure that an
unquoted \ in a pattern always quotes whatever comes next
(which, unlike in regular expressions, includes inside []
matches),

-

Part 2 of pattern matching (glob etc) fixes.
Attempt to correctly deal with \ (both when it is a literal,
in appropriate cases, and when it appears as CTLESC when it was
detected as a quoting character during parsing).

In a pattern, in sh, no quoted character can ever be anything other
than a literal character. This is quite different than regular
expressions, and even different than other uses of glob matching,
where shell quoting is not an issue.

In something like
ls ?\*.c
the ? is a meta-character, the * is a literal (it was quoted). This
is nothing new, sh has handled that properly for ever.

But the same happens with
VAR='?\*.c'
and
ls $VAR
which has not always been handled correctly. Of course, in
ls "$VAR"
nothing in VAR is a meta-character (the entire expansion is quoted)
so even the '\' must match literally (or more accurately, no matching
happens - VAR simply contains an "unusual" filename). But if it had
been
ls *"$VAR"
then we would be looking for filenames that end with the literal 5
characters that make up $VAR.

The same kinds of things are requires of matching patterns in case
statements, and sub-strings with the % and # operators in variable
expansions.

While here, the final remnant of the ancient !! pattern matching
hack has been removed (the code that actually implemented it was
long gone, but one small piece remained, not doing any real harm,
but potentially wasting time - if someone gave a pattern which would
once have invoked that hack.)
 1.132.2.5 25-Aug-2018  martin Pull up following revision(s) (requested by kre in ticket #988):

bin/sh/parser.c: revision 1.147
bin/sh/var.c: revision 1.70
bin/sh/mystring.c: revision 1.18
bin/sh/options.c: revision 1.53
bin/sh/histedit.c: revision 1.53

Remove atoi()

Mostly use number() (no longer implemented using atoi()) when an
unsigned integer is required, but use strtoXXX() when a conversion
is wanted, without the possibility or error (like setting OPTIND
and RANDOM). Always init OPTIND to 1 when sh starts (overriding
anything in environ.)
 1.132.2.4 06-May-2018  martin Pull up following revision(s) (requested by kre in ticket #804):

bin/sh/parser.c: revision 1.146

PR bin/53201

Don't synerr on
${var-anything
more}

The newline in the middle of the var expansion is permitted.

Bug reported by Martijn Dekker from his modernish tests.
XXX pullup-8
 1.132.2.3 17-Nov-2017  snj Pull up following revision(s) (requested by kre in ticket #355):
bin/sh/parser.c: revision 1.145
PR bin/52715
Correct a (relatively harmless) use after free in prompt expansion
processing [detected by asan.]
Relatively harmless: as (while incorrect) the way the data is (was)
used more or less guaranteed that the buffer contents would be
unaltered until well after they are (were) no longer wanted (this
is the expanded prompt string, it is just output (or copied into
libedit internal storage) and forgotten.
This should make no visible difference to anyone (not using asan or
similar.)
 1.132.2.2 09-Aug-2017  snj Pull up following revision(s) (requested by kre in ticket #199):
bin/sh/input.c: revision 1.61
bin/sh/parser.c: revision 1.143
PR bin/52458
Avoid mangling history when editing is enabled, and the prompt contains a \n
Also, allow empty input lines into history when they are being appended to
a previous (partial) command (but not when they would just make an empty entry)
.
For all the gory details, see the PR.
Note nothing here actually makes prompts containing \n work correctly
when editing is enabled, that's a libedit issue, which will be addressed
some other time.
 1.132.2.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.145.2.7 26-Jan-2019  pgoyette Sync with HEAD
 1.145.2.6 18-Jan-2019  pgoyette Synch with HEAD
 1.145.2.5 26-Dec-2018  pgoyette Sync with HEAD, resolve a few conflicts
 1.145.2.4 26-Nov-2018  pgoyette Sync with HEAD, resolve a couple of conflicts
 1.145.2.3 06-Sep-2018  pgoyette Sync with HEAD

Resolve a couple of conflicts (result of the uimin/uimax changes)
 1.145.2.2 28-Jul-2018  pgoyette Sync with HEAD
 1.145.2.1 22-Apr-2018  pgoyette Sync with HEAD
 1.146.2.4 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.146.2.3 21-Apr-2020  martin Sync with HEAD
 1.146.2.2 08-Apr-2020  martin Merge changes from current as of 20200406
 1.146.2.1 10-Jun-2019  christos Sync with HEAD
 1.181.2.1 02-Aug-2025  perseant Sync with HEAD
 1.30 21-Oct-2024  kre Fix processing of unknown variable expansion types.

Our shell is (was) one of the last not to do this correctly.

Expansions are supposed to happen only when the command in which
they occur is being executed, not while it is being parsed.
If the expansion only happens them, errors should only be
detected then.

Make it work like that (I saw after I fixed this that FreeBSD
had done it, long ago, almost the same way - it is kind of an
obvious thing to do).

This will allow code like

if test it is shell X
then
commands using shell X specific expansion ops
else if it is shell Y
then
commands using shell Y specific expansion ops
else ...
fi

Previously expansion errors were detected while parsing, so
if we're not shell X, and don't implement something that it
does (some extension to the standard) that would have generated
a parser syntax error, and the script could not be executed
(despite the line with the error never being executed).

Note that this change does not handle all such possible
extensions, just this one. Others are much harder.

One side effect of this change is that sh will now continue
reading a variable expansion until it locates the terminating
'}' (in ${var} forms) regardless of how broken it obviously
is (to our shell) whereas previously it would have bailed out
as soon as an oddity was spotted.
 1.29 12-Jul-2024  kre Implement expandvar() : runs var/arith/cmdsub expansions on var value

expandvar() is like expandenv() and expandstr() - each expands
variable values in different contexts, expandenv() when processing
environment vars at startup (and there is no existing state to lose),
but is always using unsafe data, so never runs command substitutions,
expandstr() while in the middle of processing commands (mostly to
expand the prompt variables, so there is probably half a command
tree in the process of being built) - it uses the promptcmds option
to decide whether to run command substitutions. expandvar() is for
intermediate situations, where a variable is to be used during
processing. It will run command substitutions if the variable
value concerned was not imported from the environment.

There are currently no uses of expandvar(), so this change alters
nothing in the shell - but there will be in the near future.
 1.28 13-Feb-2019  kre branches: 1.28.12;

Delete a no-longer-used #define that referred to a struct field that
no longer exists. Also correct a couple of typos in comments. NFC.
 1.27 11-Dec-2018  kre PR standards/42829

Implement parameter and arithmetic expansion of $ENV
before using it as the name of a file from which to
read startup commands for the shell. This continues
to happen for all interactive shells, and non-interactive
shells for which the posix option is not set (-o posix).

On any actual error, or if an attempt is made to use
command substitution, then the value of ENV is used
unchanged as the file name.

The expansion complies with POSIX XCU 2.5.3, though that
only requires parameter expansion - arithmetic expansion
is an extension (but for us, it is much easier to do, than
not to do, and it allows some weird stuff, if you're so
inclined....) Note that there is no ~ expansion (use $HOME).
 1.26 03-Dec-2018  kre Revamp aliases - as dumb an idea as they are, if we're going
to have them, they should work as documented, not cause core
dumps, reference after free, incorrect replacements, failing
to implement alias after alias, ...

The big comment that ended:
This is a good idea ------- ***NOT***
and the hack it was describing are gone.

Note that most of this was from original CVS version 1.1
code (ie: came from the original import, even before 4.4-Lite
was merged. That is, May 1994. And no-one in 24.5 years
noticed (or at least complained about) all the bugs (or at
least, most of them)).

With these changes, aliases ought to work (if you can call it
that) as they are expected to by POSIX. Now if only we could
get POSIX to delete them (or make them optional)...

Changes partly inspired by similar changes made by FreeBSD,
(as was the previous change to alias.c, forgot ack in commit
log for that one, apologies) but done a little differently,
and perhaps with a slightly better outcome.
 1.25 01-Dec-2018  kre NFC. Need a grain of const
 1.24 21-Aug-2017  kre branches: 1.24.2; 1.24.4;
Add support for $'...' quoting (based upon C "..." strings, with \ expansions.)

Implementation largely obtained from FreeBSD, with adaptations to meet the
needs and style of this sh, some updates to agree with the current POSIX spec,
and a few other minor changes.

The POSIX spec for this ( http://austingroupbugs.net/view.php?id=249 )
[see note 2809 for the current proposed text] is yet to be approved,
so might change. It currently leaves several aspects as unspecified,
this implementation handles those as:

Where more than 2 hex digits follow \x this implementation processes the
first two as hex, the following characters are processed as if the \x
sequence was not present. The value obtained from a \nnn octal sequence
is truncated to the low 8 bits (if a bigger value is written, eg: \456.)
Invalid escape sequences are errors. Invalid \u (or \U) code points are
errors if known to be invalid, otherwise can generate a '?' character.
Where any escape sequence generates nul ('\0') that char, and the rest of
the $'...' string is discarded, but anything remaining in the word is
processed, ie: aaa$'bbb\0ccc'ddd produces the same as aaa'bbb'ddd.

Differences from FreeBSD:
FreeBSD allows only exactly 4 or 8 hex digits for \u and \U (as does C,
but the current sh proposal differs.) reeBSD also continues consuming
as many hex digits as exist after \x (permitted by the spec, but insane),
and reject \u0000 as invalid). Some of this is possibly because that
their implementation is based upon an earlier proposal, perhaps note 590 -
though that has been updated several times.

Differences from the current POSIX proposal:
We currently always generate UTF-8 for the \u & \U escapes. We should
generate the equivalent character from the current locale's character set
(and UTF8 only if that is what the current locale uses.)
If anyone would like to correct that, go ahead.

We (and FreeBSD) generate (X & 0x1F) for \cX escapes where we should generate
the appropriate control character (SOH for \cA for example) with whatever
value that has in the current character set. Apart from EBCDIC, which
we do not support, I've never seen a case where they differ, so ...
 1.23 30-Jun-2017  kre Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
 1.22 07-Jun-2017  kre A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)

This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)

The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.

This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).

I would not call the results of this perfect yet, but it is close.
 1.21 31-Mar-2016  christos branches: 1.21.8;
After discussions with Jilles Tjoelker (FreeBSD shell) and
following a suggestion from him, the way the fix to PR bin/50993
was implemented has changed a little. There are three steps involved
in processing a here document, reading it, parsing it, and then
evaluating it before applying it to the correct file descriptor for
the command to use. The third of those is not related to this
problem, and has not changed. The bug was caused by combining the
first two steps into one (and not doing it correctly - which would be
hard that way.) The fix is to split the first two stages into
separate events. The original fix moved the 2nd stage (parsing)
to just immediately before the 3rd stage (evaluation.) Jilles
pointed out some unwanted side effects from doing it that way, and
suggested moving the 2nd stage to immediately after the first.
This commit makes that change. The effect is to revert the changes
to expand.c and parser.h (which are no longer needed) and simplify
slightly the change to parser.c. (from kre@)
 1.20 27-Mar-2016  christos PR bin/50993 - this is a significant rewrite of the way that here
documents are processed. Now, when first detected, they are
simply read (the only change made to the text is to join lines
ended with a \ to the subsequent line, otherwise end marker detection
does not work correctly (for here docs with an unquoted endmarker
only of course.) This patch also moves the "internal subroutine"
for looking for the end marker out of readtoken1() (which had to
happen as readtoken1 is no longer reading the here doc when it is
needed) - that uses code mostly taken from FreeBSD's sh (thanks!)
and along the way results in some restrictions on what the end
marker can be being removed. We still do not allow all we should.
(from kre@)
 1.19 22-Feb-2016  christos PR bin/43469 - correctly handle quoting of the pattern part of ${var%pat}
type expansions. (from kre)
 1.18 02-Oct-2013  christos add crude $LINENO support for FreeBSD
 1.17 26-Jun-2004  dsl branches: 1.17.48; 1.17.54;
Correctly apply IFS to unquoted text in ${x-text}.
Fixes PR/26058 and the 'for i in ${x-a b c}; do ...' and ${x-'a b' c}.
I can't find a PR for the latter problem.
Regression test goind in shortly.
 1.16 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.15 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.14 27-Jul-2000  cgd un-__P functions declared in parser.h. host programs include parser.h,
and so it shouldn't use __P. (this should probably be done better, by
not declaring the parser functions in headers used by host programs,
but this works well enough.)
 1.13 09-Jul-1999  christos compile with WARNS = 2
 1.12 25-Jan-1999  mycroft Patches from Tor Egge (via Havard Eidnes) to fix various bugs in field
splitting and combining.
(Note: Some of this are not strictly bugs, but differences between traditional
Bourne shell and POSIX.)
 1.11 16-Oct-1996  christos PR/2808: Remove trailing whitespace (from FreeBSD)
 1.10 11-May-1995  christos branches: 1.10.6;
Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.9 21-Mar-1995  cgd convert to new RCS id conventions.
 1.8 23-Jan-1995  christos I added the documented in the manual but not implemented variable expansions:

${#WORD}
${WORD%PAT}
${WORD%%PAT}
${WORD#PAT}
${WORD##PAT}
 1.7 14-Jun-1994  jtc From Christos:
1. Fix `-' quoting in [ ] expressions.
2. Fix expansion of variables in redirections
 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.10.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.17.54.1 19-Aug-2014  tls Rebase to HEAD as of a few days ago.
 1.17.48.1 22-May-2014  yamt sync with head.

for a reference, the tree before this commit was tagged
as yamt-pagecache-tag8.

this commit was splitted into small chunks to avoid
a limitation of cvs. ("Protocol error: too many arguments")
 1.21.8.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.24.4.3 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.24.4.2 21-Apr-2020  martin Sync with HEAD
 1.24.4.1 10-Jun-2019  christos Sync with HEAD
 1.24.2.1 26-Dec-2018  pgoyette Sync with HEAD, resolve a few conflicts
 1.28.12.1 02-Aug-2025  perseant Sync with HEAD
 1.76 11-Nov-2024  kre This commit is intended to be what was intended to happen in the
commit of Sun Nov 10 01:22:24 UTC 2024, see:

http://mail-index.netbsd.org/source-changes/2024/11/10/msg154310.html

The commit message for that applies to this one (wholly). I believe that
the problem with that version which caused it to be reverted has been found
and fixed in this version (a necessary change was made as part of one of
the fixes, but the side-effect implications of that were missed -- bad bad me.)

In addition, I found some more issues with setting close-on-exec on other
command lines

With:
func 3>whatever

fd 3 (anything > 2) got close on exec set. That makes no difference
to the function itself (nothing gets exec'd therefore nothing gets closed)
but does to any exec that might happen running a command within the function.

I believe that if this is done (just as if "func" was a regular command,
and not a function) such open fds should be passed through to anything
they exec - unless the function (or other command) takes care to close the
fd passed to it, or explicitly turn on close-on exec.

I expect this usage to be quite rare, and not make much practical difference.

The same applies do builtin commands, but is even less relevant there, eg:

printf 3>whatever

would have set close-on-exec on fd 3 for printf. This is generally
completely immaterial, as printf - and most other built-in commands -
neither uses any fd other than (some of) 0 1 & 2, nor do they exec anything.

That is, except for the "exec" built-in which was the focus of the original
fix (mentioned above) and which should remain fixed here, and for the "."
command.

Because of that last one (".") close-on-exec should not be set on built-in
commands (any of them) for redirections on the command line. This will
almost never make a difference - any such redirections last only as long
as the built-in command lasts (same with functions) and so will generally
never care about the state of close-on-exec, and I have never seen a use
of the "." command with any redirections other than stderr (which is unaffected
here, fd's <= 2 never get close-on-exec set). That's probably why no-one
ever noticed.

There are still "fd issues" when running a (non #!) shell script, that
are hard to fix, which we should probably handle the way most other shells
have, by simply abandoning the optimisation of not exec'ing a whole new
shell (#! scripts do that exec) and just doing it that way. Issues solved!
One day.
 1.75 10-Nov-2024  kre Revert the recent change until I can work out how things are broken.
 1.74 10-Nov-2024  kre Back out the fcntl() 3rd arg -> (void *) change, leave it as an
untouched int. The other way seems to break things.
 1.73 10-Nov-2024  kre exec builtin command redirection fixes

Several changes, all related to the exec special built in command,
or to close on exec, one way or another. (Except a few white space
and comment additions, KNF, etc)

1. The bug found by Edgar Fuß reported in:
http://mail-index.netbsd.org/tech-userlevel/2024/11/05/msg014588.html
has been fixed, now "exec N>whatever" will set close-on-exec for fd N
(as do ksh versions, and allowed by POSIX, though other shells do not)
which has happened now for many years. But "exec cmd N>whatever"
(which looks like the same command when redirections are processed)
which was setting close-on-exec on N, now no longer does, so fd N
can be passed to cmd as an open fd.

For anyone who cares, the big block of change just after "case CMDBUILTIN:"
in evalcommand() in eval.c is the fix for this (one line replaced by
about 90 ... though most of that is comments or #if 0'd example code
for later). It is a bit ugly, and will get worse if our exec command
ever gets any options, as others have, but it does work.

2. when the exec builtin utility is used to alter the shell's redirections
it is now "all or nothing". Previously the redirections were executed
left to right. If one failed, no more were attempted, but the earlier
ones remained. This makes no practical difference to a non-interactive
shell, as a redirection error causes that shell to exit, but it makes
a difference to interactive shells. Now if a redirection fails, any
earlier ones which had been performed are undone. Note however that
side-effects of redirections (like creating, or truncating, files in
the filesystem, cannot be reversed - just the shell's file descriptors
returned to how they were before the error).

Similarly usage errors on exec now exist .. our exec takes no options
(but does handle "--" as POSIX says it must - has done for ages).
Until now, that was the only magic piece of exec, running
exec -a name somecommand
(which several other shells support) would attempt to exec the "-a"
command, and most likely fail, causing immediate exit from the shell.
Now that is a usage error - a non-interactive shell still exits, as
exec is a special builtin, and any error from a special builtin causes
a non-interactive shell to exit. But now, an interactive shell will
no longer exit (and any redirections that were on the command will be
undone, the same as for a redirection error).

3. When a "close on exec" file descriptor is temporarily saved, so the
same fd can be redirected for another command (only built-in commands
and functions matter, redirects for file system commands happen after
a fork() and at that stage if anything goes wrong, the child simply
exits - but for non-forking commands, doing something like printf >file
required the previous stdout to be saved elsewhere, "file" opened to
be the new stdout, then when printf is finished, the old stdout moved
back. Anyway, if the fd being moved had close on exec set, then
when it was moved back, the close on exec was lost. That is now fixed.

4. The fdflags command no longer allows setting close on exec on stdin,
stdout, or stderr - POSIX requires that those 3 fd's always be open
(to something) when any normal command is invoked. With close-on-exec
set on one of these, that is impossible, so simply refuse it (when
"exec N>file" sets close on exec, it only does it for N>2).

Minor changes (should be invisible)

a. The shell now keeps track of the highest fd number it sees doing
normal operations (there are a few internal pipe() calls that aren't
monitored and a couple of others, but in general the shell will now
know the highest fd it ever saw allocated to it). This is mostly
for debugging.

b. calls to fcntl() passing an int as the "arg" are now all properly
cast to the void * that the fcntl kernel is expecting to receive.
I suspect that makes no actual difference to anything, but ...
 1.72 22-Nov-2021  kre branches: 1.72.4;

PR bin/53550

Here we go again... One more time to redo how here docs are
processed (it has been a few years since the last time!)

This is actually a relatively minor change, mostly to timimg
(to just when things happen). Now here docs are expanded at the
same time the "filename" word in a redirect is expanded, rather than
later when the heredoc was being sent to its process. This actually
makes things more consistent - but does break one of the ATF tests
which was testing that we were (effectively) internally inconsistent
in this area.

Not all shells agree on the context in which redirection expansions
should happen, some make any side effects visible to the parent shell
(the majority do) others do the redirection expansions in a subshell
so any side effcts are lost. We used to have a foot in each camp,
with the majority for everything but here docs, and the minority for
here docs. Now we're all the way with LBJ ... (or something like that).
 1.71 16-Nov-2021  kre Detect write errors to stdout, and exit(1) from some built-in
commands which (primarily) are used just to generate output
(or with a particular option combination do so).
 1.70 10-Nov-2021  kre DEBUG mode changes only. NFC (NC) for any normally compiled shell.

Mostly adding DEBUG mode tracing (when appropriate verbose tracing
is enabled generally) whenever a shell (including sushell) process
exits, so shells that the tracing should indicate why ehslls that
vanish did that.

Note for future investigators: if the relevant tracing is enabled,
and a (sub-)shell still simply seems to have vanished without trace,
the likely cause is that it was killed by a signal - and of those,
the most common that occurs is SIGPIPE.
 1.69 15-Sep-2021  kre Fix an ordering error in the previous (and even earlier, going back
a way, but made more serious with the recent changes).

The n>&n operation (more or less a no-op, except it clears CLOEXEC)
should precede almost everything else - and simply be made to fail if
an attempt is made to apply it to a sh internal fd.

We were renumbering the internal fd (the n> part considered first)
which was dumb, but OK, before, but now rejecting the operation
(the >&n) part when n should not be visible to the script. That
made something of a mess (and could lead to the shell believing its
job control tty was at a fd it never got moved to).

Do things in the correct order, and simply fail that case for internal
fds (for every other n>xxx for any xxx sh simply renumbers its internal fd
n to some other fd before attempting the operation, even n>&- ... those are
all fine).

[In all the above the '>' is used in place of any redirect operator].
 1.68 15-Sep-2021  kre Improve the solution for the 2nd access to a fd which shouldn't
be available ("13") issue reported by Jan Schaumann on netbsd-users.

This fixes a bug in the earlier fix (a day or so ago) which could allow the
shell's idea of which fd range was in use by the script to get wildly
incorrect, but now also actually looks to see which fd's are in use as
renamed other user fd's during the lifetime of a redirection which needs
to be able to be undone (most redirections occur after a fork and are
permanent in the child process). Attempting to access such a fd (as with
attempts to access a fd in use by the shell for its own purposes) is treated
as an attempt to access a closed fd (EBADF). Attempting to reuse the fd
for some other purpose (which should be rare, even for scripts attempting
to cause problems, since the shell generally knows which fds the script
wants to use, and avoids them) will cause the renamed (renumbered) fd
to be renamed again (moved aside to some other available fd), just as
happens with the shell's private fds.

Also, when a generic fd is required, don't give up because of EMFILE
or similar unless there are no available fds at all (we might prefer >10
or bigger, but if there are none there, use anything). This avoids
redirection errors when ulimit -n has been set small, and all the fds >10
that are available have been used, but we need somewhere to park the old
user of a fd while we reuse that fd for the redirection.
 1.67 14-Sep-2021  kre Deal with some issues where fds intended only for internal use
by the shell were available for manipulation by scripts (or the user).
These issues were reported by Jan Schaumann on netbsd-users.

The first allows the user to reference sh internal fds, and is
a simple fix - any sh internal fd is simply treated as if it were closed
when referenced by the script. These fds can be discovered by
examining /proc/N/fd so it is not difficult for a script to discover
which fd it should attempt to access.

The second allows the user to reference a user level fd which is
one that is normally available to it, but at a point where it should
no longer be visible (when that fd has been redirected, for a built
in command, so the original fd needs to be saved so it can be restored,
the saving fd should not be accessible). It is not as easy for the
script to determine which fd to attempt here, as the relevant one
exists only during the lifetime of a built-in command (and similar),
but there are ways in some cases (aside from looking at /proc from
another process).

Fix this one by watching which fds the user script is attempting
to use, and avoid using those as temporary fds. This is possible in
this case as we know what command is being run, before we need to
save the fds it uses. That's different from the earlier case where
when the shell allocates its fds we have no idea what it might
reference later.

Also clean up a couple of other minor code issues (NFC intended) that
I noticed while here...
 1.66 01-Mar-2019  kre The previous commit was obviously made by a broken mindless automoton
with an IQ that underflows when one attempts to enter it as an
unnormalised 160 bit long long double...

Whoever would believe that (~0 & anything) was a meaningful thing
to write? And three times in one #define. That could not possibly
have been me, could it?

Simplify, simplify, simplify. NFC.
 1.65 01-Mar-2019  kre Inspired by (really the need for) Maya's patch to pkgsrc/shells/bash
to allow bash to build fdflags on Solaris 10, here are some mods that
fix that, and some other similar issues in the NetBSD version of fdflags.

The bash implementation of fdflags is based upon the one Christos did for
the NetBSD sh, so the issues are similar ... the NetBSD sh cannot yet
(easily anyway) build on anything except NetBSD, so this change makes
no current difference at all (just adds some compile time tests (#ifdef)
which always work out the way things did before, when built on NetBSD).

However, there is no system on which any modern shell can hope to work
which does not support close on exec, or fcntl(F_SETFD,...) to set it.
The O_CLOEXEC and FD_CLOEXEC definitions might not exist, but close on
exec can still be manipulated. Since the primary rationale for
the fdflags builtin was to be able to manipulate that state bit from
scripts, it would be annoying to lose that one, and keep all the (less
important) others, just because O_CLOEXEC is not defined, so do the
fix (workaround) a different way than was done in the bash patch.

Further, more than fdflags() will fail if O_CLOEXEC is not defined,
so handle that as well.

Also fix another oddity ... (noticed by reading the code) - if
fcntl(F_GETFL,...) returned any bits set that we don't understand,
the code was supposed to simply print their values as a hex constant,
when fdflags is run with -v. However, the getflags() function was
clearing all bits that the code did not know about ... so there is
no way any unknown bit could ever make it out to be printed. Handle
that a different way - instead of clearing unknown bits, clear any
bits that get returned which we understand, but do not want to deal
with (stuff like O_WRONLY, which should not be returned from the
fcntl(), but who knows...) Leave any unknown bits that happen to be
set, set, so that printone() can display them if appropriate.
(This is most likely to happen when running an older shell on a new
kernel where the kernel supports some new flag that the shell has
not been taught to understand).

NFCI that anyone should notice anytime soon.
 1.64 09-Feb-2019  kre DEBUG mode change only. Add one extra trace point. NFC for normal builds.
 1.63 09-Feb-2019  kre INTON / INTOFF audit and cleanup.

No visible differences expected - there is a remote chance that
some internal lossage may no longer occur in interactive shells
that receive SIGINT (untrapped) at inopportune times, but you would
have had to have been very unlucky to have ever suffered from that.
 1.62 26-Nov-2018  kamil Fix typo: O_ALTIO -> O_ALT_IO

Noted by @jbeich via GitHub.
 1.61 23-Nov-2018  kre Fix the <> redirection operator, which has been broken since it was
first implemented in response to PR bin/4966 (PR Feb 1998, fix Feb 1999).

The file named should not be truncated.

No other shell truncates the file (<> was added to FreeBSD sh in Oct 2000,
and did not include O_TRUNC) and POSIX certainly does not suggest that
should happen (just that the file is to be created if it does not exist.)

Bug pointed out in off-list e-mail by Martijn Dekker
 1.60 13-Aug-2018  kre NFC: DEBUG (compile time) mode only change:
Add some extra redirection (fd manipulation) tracing.
While here, some white space fixes, and very minor KNF.
 1.59 15-Nov-2017  kre branches: 1.59.2; 1.59.4;
DEBUG mode only change. Add some tracing. NFC (without DEBUG).
 1.58 30-Jun-2017  kre Include redirections in trace output from "set -x"
 1.57 29-May-2017  kre branches: 1.57.2;

Now that the shell is protecting its internal fds properly, moving
them whenever the user tries to step on one, we can change our behaviour
back to what the kernel considers to be that of a well behaved shell
(wrt file descriptor usage). If our user causes problems, we will soon
move into recalcitrant process territory, but that should normally be
rare. This should reduce kernel overheads a little.
 1.56 18-May-2017  kre Allow abbreviations of option names for the "fdflags -s" command.
While documenting that, cleanup markup of the fdflags section of the
man page.
 1.55 14-May-2017  kre When opening a file descritor with "exec n>/file" (and similar) only
set the close-on-exec bit when not in posix mode (to comply with posix...)
OK: christos@
 1.54 29-Apr-2017  kre Keep track of which file descriptors the shell is using for its
own purposes, and move them elsewhere whenever a user redirection
happens to pick the same number. With this we can move the shell
file descriptors back to lower values (be slightly kinder to the kernel)
since we can no longer clash. (Also get rid of a little old unneeded code.)

This also completes the fdflags command, which no longer permits access
to (by way or either obtaining, or changing) the shell's internal fds.
 1.53 22-Apr-2017  kre branches: 1.53.2;

Keep track of the biggest fd used by, or available to, the user/script
and use that to control which fd's are examined by a (bare) fdflags
(with no fd args).

Usually this will mean that fdflags will no longer show the shell's
internal use fds, only user fds.

This is only a partial fix however, a user can easily discover the
shell's fd usage (eg: using fstat) and can then still use fdflags to
manipulate those fds (or even send output to them).

The shell needs to monitor its own fd usage better, and keep out of
the way of user fds - coming sometime later...
 1.52 22-Apr-2017  kre When verifying the size of the fd arg for fdflags skip leading 0's
(fdflags 0000000001 should work, fdflags 10000000 should not)
 1.51 03-Feb-2017  kre Fiddle the (new) fdflags implementation:

Remove some unnecessary cuteness that limited error reporting.
Permit just one -s arg to fdflags
Be deterministic in the case of fdflags -s +cloexec,-cloexec 0
(and similar) - use the last specified, always.
Allow:
FD_0_FLAGS=$( fdflags -v 0 )
# do stuff, manipulating the flags
fdflags -s "FD_0_FLAGS" 0
to save/restore flags for a fd.
Correctly mask result of fcntl(fd, F_GETFD) with FD_CLOEXEC as the
specs require before deciding close on exec is set.

Improve portability as a tool, don't assume strtoi(), nor __arraycount()
and avoid needlessly requiring recent C versions (ie: there's no need to
sprinkle declarations in the middle of the code, it just makes them hard
to find, and benefits nothing.)

Still to do: As currently implemented, both user, and shell internal fds
are reported, and can be manipulated. Allowing users to touch the shell's
internal fds is bogus, and providing this easy way to allow users to
discover which values they have is poor. Fixing this means getting rid
of the use of fcntl(F_MAXFD) and replacing it with a shell maintained
memory of what fds the user (script) has allocated. The shell's fd
manipulation really still needs major work (including properly fixing
bin/48875)
 1.50 02-Feb-2017  christos Add fdflags builtin. Discussed with Chet and he has implemented it for
bash too.
 1.49 21-Jan-2017  christos Don't let set cloexec for "exec n>&1" like ksh does (but not bash). Unit
tests pass... If we don't like that, we should add some unittests that fail.
 1.48 10-Jan-2017  christos branches: 1.48.2;
add missing <sys/stat.h>
 1.47 12-May-2016  kre branches: 1.47.2;

More work on file descriptors... This is the copyfd() cleanup.
copyfd() duplicates file descriptors - it used to be widely used,
but these days has seen its popularity dwindle. Strip it of an
option that ceased to be variable (simplifying code) and cause all
its users to check its result, so it does not need to handle errors
itself (simplifying code further), and make it become a private inernal
routine in redir.c (all callers from other places have switched to a
more modern interface.) Make sure we error() if N>&N fails (if N is closed.)
 1.46 09-May-2016  kre Finish the fd reassignment fixes from 1.43 and 1.45 ... if we are moving
a fd to an unspecified high fd number, we certainly do not want to hand
that high fd off to other processes after an exec, so always set close-on-exec
on the result (even if lack of fd's means no fd alteration happens.)
This will (eventually) allow some other code that sets close-on-exec to
be removed, but for now, doing it twice won't hurt. Also, in a N>&M
type redirection, do not set close-on-exec if we don't want it.

OK christos@
 1.45 08-May-2016  kre PR bin/51123 - make >&- work in all cases, and while doing that fix
things so that >/dev/stdout </dev/stdin (etc) work as well (in all cases).

ok christos@
 1.44 08-May-2016  kre Whitespace fixes. No functional change.
 1.43 02-May-2016  christos Fix handing of user file descriptors outside the 0..9 range.
Also, move (most of) the shell's internal use fd's to much
higher values (depending upon what ulimit -n allows) so they
are less likely to clash with user supplied fd numbers. A future
patch will (hopefully) avoid this problem completely by dynamically
moving the shell's internal fds around as needed. (From kre@)
 1.42 13-Mar-2016  christos dedup.
 1.41 13-Mar-2016  christos Test for REDIR_KEEP in the non-copy case:
$ cat other1
#!/bin/sh
./other2 3>out

$ cat other2
#!/bin/sh
echo other2 1>&3

$ ./other1
 1.40 12-Mar-2016  christos Don't close-on-exec redirections created explicitly for the command being
ran; i.e. we want this to work:
$ cat succ1
#!/bin/sh
./succ2 6>out

$ cat succ2
#!/bin/sh
echo succ2 >&6

$ ./succ1

And this to fail:
$ cat fail1
#!/bin/sh
exec 6> out
echo "fail1" >&6
./fail2
exec 6>&-

$ cat fail2
#!obj.amd64/sh
echo "fail2" >&6

$ ./fail1
./fail2: 6: Bad file descriptor

XXX: Do we want a -k (keep flag on exec to make redirections not close-on-exec?
 1.39 04-Jan-2016  christos PR/50619: Fix reversed test.
 1.38 04-Jan-2016  christos Don't leak redirected rescriptors to exec'ed processes. This is what ksh
does, but bash does not. For example:

$ cat test1
#!/bin/sh
exec 6> out
echo "test" >&6
sh ./test2
exec 6>&-
$ cat test2
echo "test2" >&6
$ ./test1
./test2: 6: Bad file descriptor

This fixes by side effect the problem of the rc system leaking file descriptors
7 and 8 to all starting daemons:

$ fstat -p 1359
USER CMD PID FD MOUNT INUM MODE SZ|DV R/W
root powerd 1359 wd / 2 drwxr-xr-x 512 r
root powerd 1359 0 / 63029 crw-rw-rw- null rw
root powerd 1359 1 / 63029 crw-rw-rw- null rw
root powerd 1359 2 / 63029 crw-rw-rw- null rw
root powerd 1359 3* kqueue pending 0
root powerd 1359 4 / 64463 crw-r----- power r
root powerd 1359 7 flags 0x80034<ISTTY,MPSAFE,LOCKSWORK,CLEAN>
root powerd 1359 8 flags 0x80034<ISTTY,MPSAFE,LOCKSWORK,CLEAN>
root powerd 1359 9* pipe 0xfffffe815d7bfdc0 -> 0x0 w

Note fd=7,8 pointing to the revoked pty from the parent rc process.
 1.37 23-Oct-2014  christos simplify and eliminate TOCTOU.
 1.36 15-Oct-2014  christos PR/48201: Miwa Susumu: Fix set -C (no clobber) for POSIX; from FreeBSD
Can't use O_EXCL because of device nodes; also truncate.
 1.35 27-Jun-2013  yamt fix descriptor leaks. PR/47805

this fix was taken from FreeBSD SVN rev 199953 (Jilles Tjoelker)
------------------------------------------------------------------------
r199953 | jilles | 2009-11-30 07:33:59 +0900 (Mon, 30 Nov 2009) | 16 lines

Fix some cases where file descriptors from redirections leak to programs.

- Redirecting fds that were not open before kept two copies of the
redirected file.
sh -c '{ :; } 7>/dev/null; fstat -p $$; true'
(both fd 7 and 10 remained open)
- File descriptors used to restore things after redirection were not
set close-on-exec, instead they were explicitly closed before executing
a program normally and before executing a shell procedure. The latter
must remain but the former is replaced by close-on-exec.
sh -c 'exec 7</; { exec fstat -p $$; } 7>/dev/null; true'
(fd 10 remained open)

The examples above are simpler than the testsuite because I do not want to
use fstat or procstat in the testsuite.
 1.34 12-Jun-2013  yamt constify
 1.33 20-Mar-2012  matt branches: 1.33.2;
Use C89 function definitions
 1.32 31-Aug-2011  plunky branches: 1.32.2;
NULL does not need a cast
 1.31 17-Feb-2011  pooka Tell copyfd if the caller wants the exact tofd to just fd >= tofd.
Fixes "echo foo > /rump/bar" in a rump hijacked shell.

reviewed by christos
 1.30 21-Jan-2008  msaitoh branches: 1.30.22;
Conform to XCU Section 2.8.2 (Exit Status for Commands)
 1.29 08-Jul-2004  christos branches: 1.29.2; 1.29.10; 1.29.16;
PR/25699: David Laight: sh(1) hangs opening a named pipe as stdin for
background process
This happens because we vfork, and then open a named pipe with O_RDONLY
and block in the child. We avoid this, by opening the file with O_NONBLOCK,
and then reset it if we are vforked. XXX: this is an ugly fix.
 1.28 07-Aug-2003  agc branches: 1.28.2;
Move UCB-licensed code from 4-clause to 3-clause licence.

Patches provided by Joel Baker in PR 22249, verified by myself.
 1.27 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.26 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.25 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.24 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.23 15-May-2002  christos implement noclobber. From Ben Harris, with minor tweaks from me. Two
unimplemented comments to go. Go Ben!
 1.22 22-May-2000  elric branches: 1.22.6;
Back out previous vfork changes.
 1.21 13-May-2000  elric Now we use vfork(2) instead of fork(2) when we can.
 1.20 04-Feb-1999  christos PR/4966: Joel Reicher: Implement <> redirections which are documented in
the man page.
 1.19 28-Jul-1998  mycroft Be more retentive about use of NOTREACHED and noreturn.
 1.18 28-Jul-1998  mycroft Delint.
 1.17 27-Jul-1998  christos PR/5848: David Holland: Use PIPE_BUF instead of hardcoding 4k
 1.16 04-Jul-1997  christos Fix compiler warnings.
 1.15 21-Apr-1997  christos PR/3452: Jerry Peek: Redirections of unopened fd to file failed.
for arg in a b c
do
echo hi this is $arg 1>&3
done 3> foo
 1.14 11-Jan-1997  tls kill 'register'
 1.13 16-Oct-1996  christos PR/2808: fix redirection to the same file descriptor
better error messages for failed pipes
(from FreeBSD)
 1.12 11-May-1995  christos branches: 1.12.6;
Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.11 21-Mar-1995  cgd convert to new RCS id conventions.
 1.10 23-Dec-1994  cgd pull prototypes into scope for string functions.
 1.9 05-Dec-1994  cgd clean up further. more patches from Jim Jegers
 1.8 11-Jun-1994  mycroft Add RCS ids.
 1.7 11-May-1994  jtc sync with 4.4lite
 1.6 25-Apr-1994  cgd lseek long lossage.
 1.5 01-Aug-1993  mycroft Add RCS identifiers.
 1.4 02-May-1993  sef Jim "wilson@moria.cygnus.com" Wilson's patches to make C News (and other
things) work.
 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 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.22.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.28.2.1 22-Aug-2004  tron Pull up revision 1.29 (requested by chs in ticket #777):
PR/25699: David Laight: sh(1) hangs opening a named pipe as stdin for
background process
This happens because we vfork, and then open a named pipe with O_RDONLY
and block in the child. We avoid this, by opening the file with O_NONBLOCK,
and then reset it if we are vforked. XXX: this is an ugly fix.
 1.29.16.1 23-Mar-2008  matt sync with HEAD
 1.29.10.1 26-Feb-2009  snj Pull up following revision(s) (requested by msaitoh in ticket #1281):
bin/sh/redir.c: revision 1.30
Conform to XCU Section 2.8.2 (Exit Status for Commands)
 1.29.2.1 26-Feb-2009  snj Pull up following revision(s) (requested by msaitoh in ticket #1992):
bin/sh/redir.c: revision 1.30
Conform to XCU Section 2.8.2 (Exit Status for Commands)
 1.30.22.1 05-Mar-2011  bouyer Sync with HEAD
 1.32.2.4 22-May-2014  yamt sync with head.

for a reference, the tree before this commit was tagged
as yamt-pagecache-tag8.

this commit was splitted into small chunks to avoid
a limitation of cvs. ("Protocol error: too many arguments")
 1.32.2.3 12-Jun-2013  yamt revert the previous (wrong branch)
 1.32.2.2 12-Jun-2013  yamt constify
 1.32.2.1 17-Apr-2012  yamt sync with head
 1.33.2.2 19-Aug-2014  tls Rebase to HEAD as of a few days ago.
 1.33.2.1 23-Jun-2013  tls resync from head
 1.47.2.2 26-Apr-2017  pgoyette Sync with HEAD
 1.47.2.1 20-Mar-2017  pgoyette Sync with HEAD
 1.48.2.1 21-Apr-2017  bouyer Sync with HEAD
 1.53.2.2 19-May-2017  pgoyette Resolve conflicts from previous merge (all resulting from $NetBSD
keywork expansion)
 1.53.2.1 02-May-2017  pgoyette Sync with HEAD - tag prg-localcount2-base1
 1.57.2.2 07-Dec-2018  martin Pull up following revision(s) (requested by kre in ticket #1125):

bin/sh/redir.c: revision 1.61

Fix the <> redirection operator, which has been broken since it was
first implemented in response to PR bin/4966 (PR Feb 1998, fix Feb 1999).

The file named should not be truncated.

No other shell truncates the file (<> was added to FreeBSD sh in Oct 2000,
and did not include O_TRUNC) and POSIX certainly does not suggest that
should happen (just that the file is to be created if it does not exist.)

Bug pointed out in off-list e-mail by Martijn Dekker
 1.57.2.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.59.4.3 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.59.4.2 21-Apr-2020  martin Sync with HEAD
 1.59.4.1 10-Jun-2019  christos Sync with HEAD
 1.59.2.3 26-Dec-2018  pgoyette Sync with HEAD, resolve a few conflicts
 1.59.2.2 26-Nov-2018  pgoyette Sync with HEAD, resolve a couple of conflicts
 1.59.2.1 06-Sep-2018  pgoyette Sync with HEAD

Resolve a couple of conflicts (result of the uimin/uimax changes)
 1.72.4.1 02-Aug-2025  perseant Sync with HEAD
 1.29 11-Nov-2024  kre This commit is intended to be what was intended to happen in the
commit of Sun Nov 10 01:22:24 UTC 2024, see:

http://mail-index.netbsd.org/source-changes/2024/11/10/msg154310.html

The commit message for that applies to this one (wholly). I believe that
the problem with that version which caused it to be reverted has been found
and fixed in this version (a necessary change was made as part of one of
the fixes, but the side-effect implications of that were missed -- bad bad me.)

In addition, I found some more issues with setting close-on-exec on other
command lines

With:
func 3>whatever

fd 3 (anything > 2) got close on exec set. That makes no difference
to the function itself (nothing gets exec'd therefore nothing gets closed)
but does to any exec that might happen running a command within the function.

I believe that if this is done (just as if "func" was a regular command,
and not a function) such open fds should be passed through to anything
they exec - unless the function (or other command) takes care to close the
fd passed to it, or explicitly turn on close-on exec.

I expect this usage to be quite rare, and not make much practical difference.

The same applies do builtin commands, but is even less relevant there, eg:

printf 3>whatever

would have set close-on-exec on fd 3 for printf. This is generally
completely immaterial, as printf - and most other built-in commands -
neither uses any fd other than (some of) 0 1 & 2, nor do they exec anything.

That is, except for the "exec" built-in which was the focus of the original
fix (mentioned above) and which should remain fixed here, and for the "."
command.

Because of that last one (".") close-on-exec should not be set on built-in
commands (any of them) for redirections on the command line. This will
almost never make a difference - any such redirections last only as long
as the built-in command lasts (same with functions) and so will generally
never care about the state of close-on-exec, and I have never seen a use
of the "." command with any redirections other than stderr (which is unaffected
here, fd's <= 2 never get close-on-exec set). That's probably why no-one
ever noticed.

There are still "fd issues" when running a (non #!) shell script, that
are hard to fix, which we should probably handle the way most other shells
have, by simply abandoning the optimisation of not exec'ing a whole new
shell (#! scripts do that exec) and just doing it that way. Issues solved!
One day.
 1.28 10-Nov-2024  kre Revert the recent change until I can work out how things are broken.
 1.27 10-Nov-2024  kre exec builtin command redirection fixes

Several changes, all related to the exec special built in command,
or to close on exec, one way or another. (Except a few white space
and comment additions, KNF, etc)

1. The bug found by Edgar Fuß reported in:
http://mail-index.netbsd.org/tech-userlevel/2024/11/05/msg014588.html
has been fixed, now "exec N>whatever" will set close-on-exec for fd N
(as do ksh versions, and allowed by POSIX, though other shells do not)
which has happened now for many years. But "exec cmd N>whatever"
(which looks like the same command when redirections are processed)
which was setting close-on-exec on N, now no longer does, so fd N
can be passed to cmd as an open fd.

For anyone who cares, the big block of change just after "case CMDBUILTIN:"
in evalcommand() in eval.c is the fix for this (one line replaced by
about 90 ... though most of that is comments or #if 0'd example code
for later). It is a bit ugly, and will get worse if our exec command
ever gets any options, as others have, but it does work.

2. when the exec builtin utility is used to alter the shell's redirections
it is now "all or nothing". Previously the redirections were executed
left to right. If one failed, no more were attempted, but the earlier
ones remained. This makes no practical difference to a non-interactive
shell, as a redirection error causes that shell to exit, but it makes
a difference to interactive shells. Now if a redirection fails, any
earlier ones which had been performed are undone. Note however that
side-effects of redirections (like creating, or truncating, files in
the filesystem, cannot be reversed - just the shell's file descriptors
returned to how they were before the error).

Similarly usage errors on exec now exist .. our exec takes no options
(but does handle "--" as POSIX says it must - has done for ages).
Until now, that was the only magic piece of exec, running
exec -a name somecommand
(which several other shells support) would attempt to exec the "-a"
command, and most likely fail, causing immediate exit from the shell.
Now that is a usage error - a non-interactive shell still exits, as
exec is a special builtin, and any error from a special builtin causes
a non-interactive shell to exit. But now, an interactive shell will
no longer exit (and any redirections that were on the command will be
undone, the same as for a redirection error).

3. When a "close on exec" file descriptor is temporarily saved, so the
same fd can be redirected for another command (only built-in commands
and functions matter, redirects for file system commands happen after
a fork() and at that stage if anything goes wrong, the child simply
exits - but for non-forking commands, doing something like printf >file
required the previous stdout to be saved elsewhere, "file" opened to
be the new stdout, then when printf is finished, the old stdout moved
back. Anyway, if the fd being moved had close on exec set, then
when it was moved back, the close on exec was lost. That is now fixed.

4. The fdflags command no longer allows setting close on exec on stdin,
stdout, or stderr - POSIX requires that those 3 fd's always be open
(to something) when any normal command is invoked. With close-on-exec
set on one of these, that is impossible, so simply refuse it (when
"exec N>file" sets close on exec, it only does it for N>2).

Minor changes (should be invisible)

a. The shell now keeps track of the highest fd number it sees doing
normal operations (there are a few internal pipe() calls that aren't
monitored and a couple of others, but in general the shell will now
know the highest fd it ever saw allocated to it). This is mostly
for debugging.

b. calls to fcntl() passing an int as the "arg" are now all properly
cast to the void * that the fcntl kernel is expecting to receive.
I suspect that makes no actual difference to anything, but ...
 1.26 15-Sep-2021  kre branches: 1.26.4;
Improve the solution for the 2nd access to a fd which shouldn't
be available ("13") issue reported by Jan Schaumann on netbsd-users.

This fixes a bug in the earlier fix (a day or so ago) which could allow the
shell's idea of which fd range was in use by the script to get wildly
incorrect, but now also actually looks to see which fd's are in use as
renamed other user fd's during the lifetime of a redirection which needs
to be able to be undone (most redirections occur after a fork and are
permanent in the child process). Attempting to access such a fd (as with
attempts to access a fd in use by the shell for its own purposes) is treated
as an attempt to access a closed fd (EBADF). Attempting to reuse the fd
for some other purpose (which should be rare, even for scripts attempting
to cause problems, since the shell generally knows which fds the script
wants to use, and avoids them) will cause the renamed (renumbered) fd
to be renamed again (moved aside to some other available fd), just as
happens with the shell's private fds.

Also, when a generic fd is required, don't give up because of EMFILE
or similar unless there are no available fds at all (we might prefer >10
or bigger, but if there are none there, use anything). This avoids
redirection errors when ulimit -n has been set small, and all the fds >10
that are available have been used, but we need somewhere to park the old
user of a fd while we reuse that fd for the redirection.
 1.25 03-Apr-2020  joerg Don't define max_user_fd in the header.
 1.24 30-Jun-2017  kre branches: 1.24.6;

Include redirections in trace output from "set -x"
 1.23 29-Apr-2017  kre branches: 1.23.2;

Keep track of which file descriptors the shell is using for its
own purposes, and move them elsewhere whenever a user redirection
happens to pick the same number. With this we can move the shell
file descriptors back to lower values (be slightly kinder to the kernel)
since we can no longer clash. (Also get rid of a little old unneeded code.)

This also completes the fdflags command, which no longer permits access
to (by way or either obtaining, or changing) the shell's internal fds.
 1.22 22-Apr-2017  kre branches: 1.22.2;

Keep track of the biggest fd used by, or available to, the user/script
and use that to control which fd's are examined by a (bare) fdflags
(with no fd args).

Usually this will mean that fdflags will no longer show the shell's
internal use fds, only user fds.

This is only a partial fix however, a user can easily discover the
shell's fd usage (eg: using fstat) and can then still use fdflags to
manipulate those fds (or even send output to them).

The shell needs to monitor its own fd usage better, and keep out of
the way of user fds - coming sometime later...
 1.21 12-May-2016  kre branches: 1.21.2;

More work on file descriptors... This is the copyfd() cleanup.
copyfd() duplicates file descriptors - it used to be widely used,
but these days has seen its popularity dwindle. Strip it of an
option that ceased to be variable (simplifying code) and cause all
its users to check its result, so it does not need to handle errors
itself (simplifying code further), and make it become a private inernal
routine in redir.c (all callers from other places have switched to a
more modern interface.) Make sure we error() if N>&N fails (if N is closed.)
 1.20 03-May-2016  kre Remove unnecessary extern var declaration that was a
remnant of an earlier version of the previous (fd>10) fixes.

ok christos@
 1.19 02-May-2016  christos Fix handing of user file descriptors outside the 0..9 range.
Also, move (most of) the shell's internal use fd's to much
higher values (depending upon what ulimit -n allows) so they
are less likely to clash with user supplied fd numbers. A future
patch will (hopefully) avoid this problem completely by dynamically
moving the shell's internal fds around as needed. (From kre@)
 1.18 12-Mar-2016  christos Don't close-on-exec redirections created explicitly for the command being
ran; i.e. we want this to work:
$ cat succ1
#!/bin/sh
./succ2 6>out

$ cat succ2
#!/bin/sh
echo succ2 >&6

$ ./succ1

And this to fail:
$ cat fail1
#!/bin/sh
exec 6> out
echo "fail1" >&6
./fail2
exec 6>&-

$ cat fail2
#!obj.amd64/sh
echo "fail2" >&6

$ ./fail1
./fail2: 6: Bad file descriptor

XXX: Do we want a -k (keep flag on exec to make redirections not close-on-exec?
 1.17 04-Jan-2016  christos Don't leak redirected rescriptors to exec'ed processes. This is what ksh
does, but bash does not. For example:

$ cat test1
#!/bin/sh
exec 6> out
echo "test" >&6
sh ./test2
exec 6>&-
$ cat test2
echo "test2" >&6
$ ./test1
./test2: 6: Bad file descriptor

This fixes by side effect the problem of the rc system leaking file descriptors
7 and 8 to all starting daemons:

$ fstat -p 1359
USER CMD PID FD MOUNT INUM MODE SZ|DV R/W
root powerd 1359 wd / 2 drwxr-xr-x 512 r
root powerd 1359 0 / 63029 crw-rw-rw- null rw
root powerd 1359 1 / 63029 crw-rw-rw- null rw
root powerd 1359 2 / 63029 crw-rw-rw- null rw
root powerd 1359 3* kqueue pending 0
root powerd 1359 4 / 64463 crw-r----- power r
root powerd 1359 7 flags 0x80034<ISTTY,MPSAFE,LOCKSWORK,CLEAN>
root powerd 1359 8 flags 0x80034<ISTTY,MPSAFE,LOCKSWORK,CLEAN>
root powerd 1359 9* pipe 0xfffffe815d7bfdc0 -> 0x0 w

Note fd=7,8 pointing to the revoked pty from the parent rc process.
 1.16 17-Feb-2011  pooka Tell copyfd if the caller wants the exact tofd to just fd >= tofd.
Fixes "echo foo > /rump/bar" in a rump hijacked shell.

reviewed by christos
 1.15 07-Aug-2003  agc branches: 1.15.50;
Move UCB-licensed code from 4-clause to 3-clause licence.

Patches provided by Joel Baker in PR 22249, verified by myself.
 1.14 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.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 Now we use vfork(2) instead of fork(2) when we can.
 1.10 16-Oct-1996  christos PR/2808: Remove trailing whitespace (from FreeBSD)
 1.9 11-May-1995  christos branches: 1.9.6;
Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.8 21-Mar-1995  cgd convert to new RCS id conventions.
 1.7 11-Jun-1994  mycroft Add RCS ids.
 1.6 11-May-1994  jtc sync with 4.4lite
 1.5 01-Aug-1993  mycroft Add RCS identifiers.
 1.4 02-May-1993  sef Jim "wilson@moria.cygnus.com" Wilson's patches to make C News (and other
things) work.
 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.9.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 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.15.50.1 05-Mar-2011  bouyer Sync with HEAD
 1.21.2.1 26-Apr-2017  pgoyette Sync with HEAD
 1.22.2.1 02-May-2017  pgoyette Sync with HEAD - tag prg-localcount2-base1
 1.23.2.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.24.6.3 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.24.6.2 21-Apr-2020  martin Sync with HEAD
 1.24.6.1 08-Apr-2020  martin Merge changes from current as of 20200406
 1.26.4.1 02-Aug-2025  perseant Sync with HEAD
 1.272 24-Jun-2025  andvar sh(1): fix few relatively recently introduced typos (rev 1.265).
s/agument/argument/
s/suport/support/
s/prvileges/privileges/
 1.271 09-Apr-2025  kre Better explain the expansions in case statements.

nb: no Dd bump, this change is not significant enough to warrant that.
 1.270 11-Nov-2024  kre This commit is intended to be what was intended to happen in the
commit of Sun Nov 10 01:22:24 UTC 2024, see:

http://mail-index.netbsd.org/source-changes/2024/11/10/msg154310.html

The commit message for that applies to this one (wholly). I believe that
the problem with that version which caused it to be reverted has been found
and fixed in this version (a necessary change was made as part of one of
the fixes, but the side-effect implications of that were missed -- bad bad me.)

In addition, I found some more issues with setting close-on-exec on other
command lines

With:
func 3>whatever

fd 3 (anything > 2) got close on exec set. That makes no difference
to the function itself (nothing gets exec'd therefore nothing gets closed)
but does to any exec that might happen running a command within the function.

I believe that if this is done (just as if "func" was a regular command,
and not a function) such open fds should be passed through to anything
they exec - unless the function (or other command) takes care to close the
fd passed to it, or explicitly turn on close-on exec.

I expect this usage to be quite rare, and not make much practical difference.

The same applies do builtin commands, but is even less relevant there, eg:

printf 3>whatever

would have set close-on-exec on fd 3 for printf. This is generally
completely immaterial, as printf - and most other built-in commands -
neither uses any fd other than (some of) 0 1 & 2, nor do they exec anything.

That is, except for the "exec" built-in which was the focus of the original
fix (mentioned above) and which should remain fixed here, and for the "."
command.

Because of that last one (".") close-on-exec should not be set on built-in
commands (any of them) for redirections on the command line. This will
almost never make a difference - any such redirections last only as long
as the built-in command lasts (same with functions) and so will generally
never care about the state of close-on-exec, and I have never seen a use
of the "." command with any redirections other than stderr (which is unaffected
here, fd's <= 2 never get close-on-exec set). That's probably why no-one
ever noticed.

There are still "fd issues" when running a (non #!) shell script, that
are hard to fix, which we should probably handle the way most other shells
have, by simply abandoning the optimisation of not exec'ing a whole new
shell (#! scripts do that exec) and just doing it that way. Issues solved!
One day.
 1.269 10-Nov-2024  kre Revert the recent change until I can work out how things are broken.
 1.268 10-Nov-2024  kre exec builtin command redirection fixes

Several changes, all related to the exec special built in command,
or to close on exec, one way or another. (Except a few white space
and comment additions, KNF, etc)

1. The bug found by Edgar Fuß reported in:
http://mail-index.netbsd.org/tech-userlevel/2024/11/05/msg014588.html
has been fixed, now "exec N>whatever" will set close-on-exec for fd N
(as do ksh versions, and allowed by POSIX, though other shells do not)
which has happened now for many years. But "exec cmd N>whatever"
(which looks like the same command when redirections are processed)
which was setting close-on-exec on N, now no longer does, so fd N
can be passed to cmd as an open fd.

For anyone who cares, the big block of change just after "case CMDBUILTIN:"
in evalcommand() in eval.c is the fix for this (one line replaced by
about 90 ... though most of that is comments or #if 0'd example code
for later). It is a bit ugly, and will get worse if our exec command
ever gets any options, as others have, but it does work.

2. when the exec builtin utility is used to alter the shell's redirections
it is now "all or nothing". Previously the redirections were executed
left to right. If one failed, no more were attempted, but the earlier
ones remained. This makes no practical difference to a non-interactive
shell, as a redirection error causes that shell to exit, but it makes
a difference to interactive shells. Now if a redirection fails, any
earlier ones which had been performed are undone. Note however that
side-effects of redirections (like creating, or truncating, files in
the filesystem, cannot be reversed - just the shell's file descriptors
returned to how they were before the error).

Similarly usage errors on exec now exist .. our exec takes no options
(but does handle "--" as POSIX says it must - has done for ages).
Until now, that was the only magic piece of exec, running
exec -a name somecommand
(which several other shells support) would attempt to exec the "-a"
command, and most likely fail, causing immediate exit from the shell.
Now that is a usage error - a non-interactive shell still exits, as
exec is a special builtin, and any error from a special builtin causes
a non-interactive shell to exit. But now, an interactive shell will
no longer exit (and any redirections that were on the command will be
undone, the same as for a redirection error).

3. When a "close on exec" file descriptor is temporarily saved, so the
same fd can be redirected for another command (only built-in commands
and functions matter, redirects for file system commands happen after
a fork() and at that stage if anything goes wrong, the child simply
exits - but for non-forking commands, doing something like printf >file
required the previous stdout to be saved elsewhere, "file" opened to
be the new stdout, then when printf is finished, the old stdout moved
back. Anyway, if the fd being moved had close on exec set, then
when it was moved back, the close on exec was lost. That is now fixed.

4. The fdflags command no longer allows setting close on exec on stdin,
stdout, or stderr - POSIX requires that those 3 fd's always be open
(to something) when any normal command is invoked. With close-on-exec
set on one of these, that is impossible, so simply refuse it (when
"exec N>file" sets close on exec, it only does it for N>2).

Minor changes (should be invisible)

a. The shell now keeps track of the highest fd number it sees doing
normal operations (there are a few internal pipe() calls that aren't
monitored and a couple of others, but in general the shell will now
know the highest fd it ever saw allocated to it). This is mostly
for debugging.

b. calls to fcntl() passing an int as the "arg" are now all properly
cast to the void * that the fcntl kernel is expecting to receive.
I suspect that makes no actual difference to anything, but ...
 1.267 14-Oct-2024  kre Add a -r (version) option to sh

This new -r (or +r) option is for command line use only.
When encountered, the shell simply prints its version info
(such as it has, which isn't much) and exits (immediately).

This allows "funny" uses like
sh -version
the -v and -e options are standard, and processed as normal
(changing nothing, yet, except setting the option). Then the
'r' option is seen, the version info is printed, and the shell
exits. Any remaining "options" (there is no "-o n" option) are
ignored, as are any other args given to the shell.

The string printed (currently) is just "NetBSD shell:" followed
by the value of the NETBSD_SHELL variable (which has been established
already by the time options are processed).
 1.266 11-Oct-2024  kre Add -b and -nMAX options to the read builtin.

As requested on (perhaps more than one) mailing list, this adds
a -n MAX option, to allow the amount of data read by the read
builtin to be limited to MAX bytes (in case the record delimiter
doesn't appear in the input for a long time). There is
currently an upper bound of 8MiB on the value of MAX.

Also add a -b option, which allows for buffered input (with
some usage caveats) rather than 1 byte at a time.

Neither option exists in SMALL shells.

Note that the proposed -z option got deleted ... I couldn't
find a rational way to explain what the final state would be
if a \0 on input generated an error, so rather than have
things ambiguous, better just not to have the option, and
simply keep ignoring input \0's as always.

See the (updated) sh(1) man page for more details.

No pullups planned (new feature, only for new releases).
 1.265 09-Oct-2024  kre PR bin/58687 -- implement suspend as a builtin in sh

Requested by uwe@ in PR bin/58687 without objections from
anyone except me, here is an implementation of a suspend
builtin command for /bin/sh

The sh.1 man page is updated, naturally, to describe it.

This new builtin does not exist in SMALL shells -- as used
on (some) boot media, etc.

If this turns out not to be useful, it can easily be removed.
 1.264 21-Sep-2024  kre In !TINYPROG versions of sh, make the builtin "shift" builtin command
perform a rotate instead or shift if given a numeric arg (which is
otherwise an error).

"set -- a b c; shift -1; echo $*" will echo "c a b".

While here, make the shift builtin comply with POSIX, and accept
(and ignore) a '--' arg before the shift (or rotate) count.

Document the variant of shift in sh(1)

Adapt the shell test for shift to not expect "shift -1" to be an
error, test that rotate works as expected, and include some tests
that use the (useless, but required) "--" arg.
 1.263 10-Aug-2024  uwe sh(1): fix up formatting of syntax examples

.Bd -literal with all lines explicitly formatted (usually with .Ic)
doesn't seem to work too well with mandoc shipped with the heirloom
doctools - the next paragraph after the display remains literal.
Use .Bd -unfilled instead.
 1.262 13-Jul-2024  kre Implement the HISTFILE and HISTAPPEND variables.

See the (newly updated) sh(1) for details.
Also add the -z option to fc (clear history).

None of this exists in SMALL shells.
 1.261 13-Jul-2024  kre Remove caveat about $'' quoting, now POSIX.1-2004 exists.

nb: no Dd bump, that's coming soon (not needed for this change anyway)
 1.260 12-Apr-2024  kre branches: 1.260.2;
Edgar Fuß pointed out that sh(1) did not mention comments (at all).
This has been true forever, and no-one else (including me) ever seems
to have noticed this ommission.

Correct that.

While in the area, improve the general sections on the Lexical structure
of the shell's input, and including some refinements to how quoting is
described.
 1.259 16-Jan-2024  kre Remove an ancient incorrect notion which somehow survived intact for ages.
"$@" is (as it is in double quotes) not subject to field splitting. "$@"
generates (potentially) multiple words, but field splitting has nothing
to do with it.

While here, rename the section from "White Space Splitting (Field Splitting)"
to simply be "Field Splitting" as white space is only relevant if it happens
to occur in IFS (which is the default case, but IFS can be anything, and
isn't required to contain any white space at all).
 1.258 12-Oct-2023  uwe sh(1): touch up markup for the ENV example

Don't use Dq in a literal display, ascii quotes are \*q
While here mark up as literal a few things around this example.
 1.257 01-Sep-2023  kre At the request of bad@ enhance the synopsis of the set built-in
command to include explicit mention of the -o opt and +o opt forms.

Fix the synopsis to have the 4 forms that the description of the
utility discusses, rather than expecting users to understand that
the 3rd and 4th forms of the command were combined into the 3rd
synopsis format. After doing that, the options in the 3rd format
no longer need to be optional, so now all 4 formats are distinct
(previously, the third, omitting everything that was optional, and
the first, could not be distinguished).

While here, some wording and formatting "improvements" as well (nothing
too serious).
 1.256 04-Aug-2023  jschauma tyops:
* redicection -> redirection
* escaoed -> escaped

Noted by J. Lewis Muir on netbsd-docs@
 1.255 20-Dec-2022  kre More markup errors. \+ was intended to be \&+ and .EV .Ev of course.
As best I can tell, the rest of what mandoc -Wall complains about is
incorrect (it could probably be avoided by adding more markup, but
there doesn't seem to be any point).
 1.254 20-Dec-2022  kre Using .Cm Cm makes no sense at all - no idea what I was thinking there
(perhaps just an editing error).
 1.253 20-Dec-2022  uwe sh(1): Fix markup. -compact must be last.
 1.252 11-Dec-2022  kre branches: 1.252.2;

It appears that POSIX intends to add a -d X option to the read command
in its next version, so it can be used as -d '' (to specify a \0 end
character for the record read, rather than the default \n) to accompany
find -print0 and xargs -0 options (also likely to be added).

Add support for -d now. While here fix a bug where escaped nul
chars (\ \0) in non-raw mode were not being dropped, as they are
when not escaped (if not dropped, they're still not used in any
useful way, they just ended the value at that point).
 1.251 30-Oct-2022  kre Note in the description of "jobs -p" that the process id returned is
also the process group identifier (that's a requirement from POSIX, and
is what we have always done - just not been explicit about in sh.1).
Add a note that this value and $! are not necessarily the same (currently,
and perhaps forever, never the same in a pipeline with 2 or more elements).
 1.250 18-Sep-2022  kre Add the -l option (aka -o login): be a login shell. Meaningful only on
the command line (with both - and + forms) - overrides the presence (or
otherwise) of a '-' as argv[0][0].

Since this allows any shell to be a login shell (which simply means that
it runs /etc/profile and ~/.profile at shell startup - there are no other
side effects) add a new, always set at startup, variable NBSH_INVOCATION
which has a char string as its value, where each char has a meaning,
more or less related to how the shell was started. See sh(1).
This is intended to allow those startup scripts to tailor their behaviour
to the nature of this particular login shell (it is possible to detect
whether a shell is a login shell merely because of -l, or whether it would
have been anyway, before the -l option was added - and more). The
var could also be used to set different values for $ENV for different
uses of the shell.
 1.249 16-Sep-2022  kre More wording improvements. There might be more to come.
 1.248 16-Sep-2022  kre Minor wording improvements.

Note these do not alter anything about what the man page specifies,
just say a couple of things in a slightly better way, hence no Dd
update accompanies this change (deliberately).
 1.247 16-Sep-2022  kre Move a comment that used to be in the correct place, once upon a time,
back where it belongs, and make it stand out more, so other text is
less likely to find itself pushed between the comment and the text
to which it appears. This change should make no visible difference
to the man page displayed.
 1.246 16-Sep-2022  kre Whitespace.
 1.245 15-Sep-2022  kre Correct spelling of terminal (it doesn't have a 2nd m).
 1.244 19-Aug-2022  kre Improve the description of the read builtin command.
 1.243 07-Jan-2022  lukem sh(1): improve getopts docs for optstring leading :

getopts has different behaviour if the leading character
of optstring is `:', so describe in more detail:
- no errors are printed (already there)
- unknown options set var to `?' and OPTARG to the unknown option
- missing arguments set var to `:' and OPTARG to the option name

Slight rewording of other paragraphs for more clarity.
 1.242 07-Jan-2022  lukem sh(1): fix formatting warnings
 1.241 21-Nov-2021  kre Improve the however-many-negatives wording even more.
 1.240 20-Nov-2021  rillig sh.1: replace triple negation with single negation, fix typo
 1.239 20-Nov-2021  kre Improve the wording of the "Argument List Processing" section (where
all the sh options, also used with "set", are listed) in response to
a discussion on icb conveyed to me by Darrin B. Jewell.
A few improvements to the description of the "set" built-in as well.

Bump Dd to cover all of this month's changes (so far).
 1.238 16-Nov-2021  rillig sh.1: fix typos
 1.237 16-Nov-2021  kre PR bin/56491

Make "hash" exit(!=0) (ie: exit(1)) if it writes an error message to
stderr as required by POSIX (it was writing "not found" errors, yet
still doing exit(0)).

Whether, when doing "hash foobar", and "foobar" is not found as a command
(not a built-in, not a function, and not found via a PATH search), that
should be considered an error differs between shells. All of the ksh
descendant shells say "no", write no error message in this case, and
exit(0) if no other errors occur. Other shells (essentially all) do
consider it an error, write a message to stderr, and exit(1) when this happens.

POSIX isn't clear, the bug report:
https://austingroupbugs.net/view.php?id=1460
which is not yet resolved, suggests that the outcome will be that
this is to be unspecified. Given the diversity, there might be no
other choice.

Have a foot in both camps - default to the "other shell" behaviour,
but add a -e option (no errors ... applies only to these "not found"
errors) to generate the ksh behaviour. Without other errors (like an
unknown option, etc) "hash -e anyname" will always exit(0).

See the PR for details on how it all works now, or read the updated man page.

While here, when hash is in its other mode (reporting what is in the
table) check for I/O errors on stdout, and exit(1) (with an error
message!) if any occurred. This does not apply to output generated
by the -v option when command names are given (that output is incidental).

In sh.1 document all of this. Also add documentation for a bunch of
other options the hash command has had for years, but which were never
documented. And while there, clean up some other sections I noticed
needed improving (either formatting or content or both).
 1.236 31-Oct-2021  kre PR bin/45390

Be explicit about what happens to PWD after a successful cd command.
Also be very clear that "cd" and "cd -P" are the same thing, and
the only cd variant implemented.

Also, when it is appropriate to print the new directory after a cd
command, note that it happens if interactive (as it always has here)
and also if the posix option is set (for POSIX compat, where "interactive"
is irrelevant). Mention that "cd -" is a case where the new directory
is printed (along with paths relative to a non-empty CDPATH entry,
and where the "cd old new" (string replacement in curdir) is used.

While here document the new -e option to cd.

XXX pullup -9
 1.235 26-Oct-2021  kre PR bin/56464

After almost 30 years, finally do the right thing and read $HOME/.profile
rather than .profile in the initial directory (it was that way in version
1.1 ...) All other ash descendants seem to have fixed this long ago.

While here, copy a feature from FreeBSD which allows "set +p" (if a
shell run by a setuid process with the -p flag is privileged) to reset
the privileges. Once done (the set +p) it cannot be undone (a later
set -p sets the 'p' flag, but that's all it does) - that just becomes a
one bit storage location.

We do this, as (also copying from FreeBSD, and because it is the right
thing to do) we don't run .profile in a privileged shell - FreeBSD run
/etc/suid_profile in that case (not a good name, it also applies to setgid
shells) but I see no real need for that, we run /etc/profile in any case,
anything that would go in /etc/suid_profile can just go in /etc/profile
instead (with suitable guards so the commands only run in priv'd shells).

One or two minor DEBUG mode changes (notably having priv'd shells identify
themselves in the DEBUG trace) and sh.1 changes with doc of the "set +p"
change, the effect that has on $PSc and a few other wording tweaks.

XXX pullup -9 (not -8, this isn't worth it for the short lifetime
that has left - if it took 28+ years for anyone to notice this, it
cannot be having all that much effect).
 1.234 15-Sep-2021  kre Have the ulimit command watch for ulimit -n (alter number of available fds)
and keep the rest of the shell aware of any changes.

While here, modify 'ulimit -aSH' to print both the soft and hard limits
for the resources, rather than just (in this case, as H comes last) the
hard limit. In any other case when both S and H are present, and we're
examining a limit, use the soft limit (just as if neither were given).

No change for setting limits (both are set, unless exactly one of -H
or -S is given). However, we now check for overflow when converting
the value to be assigned, rather than just truncating the value however
it happens to work out...
 1.233 12-Sep-2021  wiz Mark up NULL with Dv.
 1.232 12-Sep-2021  kre Improve the formatting of the list of Built-in commands for those
commands with multiple synopsis lines (eg: trap).

But there really must be a better way to achieve this effect than
the way it is accomplished here, and I'm hoping some wizard who
understands mdoc much better than I do will revert this change and
do it using some inspired magic incantation instead.
 1.231 12-Sep-2021  kre Don't dereference NULL on "jobs -Z" (with no title given), instead
do setproctitle(NULL) (which is not the same thing at all). Do the
same with jobs -Z '' as setting the title to "sh: " isn't useful.

Improve the way this is documented, and note that it is only done
this way because zsh did it first (ie: pass on the balme, doing this
in the jobs command is simply absurd.)
 1.230 11-Sep-2021  christos Add jobs -Z (like in zsh(1)) to setproctitle(3).
 1.229 18-Sep-2020  wiz Remove superfluous Ed.
 1.228 18-Sep-2020  kre Correct an incorrectly quoted (unquoted, but should be) example used in
the "local" built-in command description (pointed out by mrg@ via uwe@ in
private e-mail).

Add a description to the export command of why this quoting is required,
and then refer to it from local and readonly (explained in export as that
one comes first).

Note that some shells parse export/local/readonly (and often more) as
"declarative" commands, and this quoting isn't needed (provided the
command name is literal and not the result of an expansion) making
X=$Y type args not require quoting, as they often don't in a regular
variable assignment (preceding, or not part of, another command).
POSIX is going to allow, but not require, that behaviour. We do not
implement it.
 1.227 25-Aug-2020  kre Idiot typo, generated by an idiot, fixed by the same one.
 1.226 21-Aug-2020  wiz Remove unmatched .El and mark up signal name with Dv.
 1.225 20-Aug-2020  kre Man page enhancements.

Better describe the command search procedure.
Document "trap -P"
Describe what works as a function name.
More accurate description of reserved word recognition.
Be more accurate about when field splittng happens after
expansions (and in particular note that tilde expansions are
not subject to field splitting). Be clear that "$@" is
not field split, it simply produces multiple fields as part
of its expansion (hence IFS is irrelevant to this), but if
used as $@ (unquoted) each field produced is potentially subject
to field splitting. Other minor wording changes.
 1.224 20-Feb-2020  pgoyette Typo: s/./,/
 1.223 22-Apr-2019  kre branches: 1.223.2;

Bump date for previous.
 1.222 22-Apr-2019  kre PR standards/40554

Update the description of the <& and >& redirection operators
(as indicated would happen in a message appended to the PR a week ago,
which received no opposition - no feedback).

Some rewriting of the section on redirects (including how the word
expansion of the "file" works) to make this simpler & more accurate.
 1.221 15-Apr-2019  uwe -compact must come last
 1.220 14-Feb-2019  kre Add the "specialvar" built-in command. Discussed (well, mentioned
anway) on tech-userlevel with no adverse response.

This allows the magic of vars like HOSTNAME SECONDS, ToD (etc) to be
restored should it be lost - perhaps by having a var of the same name
imported from the environment (which needs to remove the magic in case
a set of scripts are using the env to pass data, and the var name chosen
happens to be one of our magic ones).

No change to SMALL shells (or smaller) - none of the magic vars (except
LINENO, which is exempt from all of this) exist in those, hence such a
shell has no need for this command either.
 1.219 04-Feb-2019  wiz Remove leading zero from date.
 1.218 04-Feb-2019  kre PR bin/53919

Suppress shell error messages while expanding $ENV (which also causes
errors while expanding $PS1 $PS2 and $PS4 to be suppressed as well).

This allows any random garbage that happens to be in ENV to not
cause noise when the shell starts (which is effectively all it did).

On a parse error (for any of those vars) we also use "" as the result,
which will be a null prompt, and avoid attempting to open any file for ENV.

This does not in any way change what happens for a correctly parsed command
substitution (either when it is executed when permitted for one of the
prompts, or when it is not (which is always for ENV)) and commands run
from those can still produce error output (but shell errors remain suppressed).
 1.217 21-Jan-2019  kre Add an explanation of the error (warning)
RANDOM initialisation failed
when the shell might print after RANDOM has been reseeded
(which includes at sh startup) the next time RANDOM is accessed.
It indicates that /dev/urandom was not available or did not
provide data - in that case, sh uses a (weak) seed made out of
the pid and time (but otherwise nothing else changes).
 1.216 12-Dec-2018  kre Reverse a decision made when the printsignals() routines from
kill and sh were merged so that the shell (for trap -l) and
kill (for kill -l) can use the same routine, and site that function
in the shell, rather than in kill (use the code that is in kill as
the basis for that routine). This allows access to sh internals,
and in particular to the posix option, so the builtin kill can
operate in posix mode where the standard requires just a single
character (space of newline) between successive signal names (and
we prefer nicely aligned columns instead)..

In a SMALL shell, use the ancient sh printsignals routine instead,
it is smaller (and very much dumber).

/bin/kill still uses the routine that is in its source, and is
not posix compliant. A task for some other day...
 1.215 12-Dec-2018  kre More fixes for the SYNPOSIS of the readonly built-in.
The SYNOPSIS for "readonly -q" cannot have the -q be
optional ... Also harmonise the output appearance with
that of the export command.

wiz: have at it...
 1.214 12-Dec-2018  kre Fix Oo Op Oc syntax error (which seemed to work OK to me....)
Pointed out by wiz@
 1.213 12-Dec-2018  kre Implement:
readonly -q VAR...
readonly -p VAR...
export -q [-x] VAR...
export -p [-x] VAR...

all available only in !SMALL shells - and while here, limit
"export -x" to full sized shells as well.

Also, do a better job of arg checking and validating of the
export and readonly commands (which is really just one built-in)
and of issuing error messages when something bogus is detected.

Since these commands are special builtin commands, any error
causes shell exit (for non-interactive shells).
 1.212 11-Dec-2018  kre PR standards/42829

Implement parameter and arithmetic expansion of $ENV
before using it as the name of a file from which to
read startup commands for the shell. This continues
to happen for all interactive shells, and non-interactive
shells for which the posix option is not set (-o posix).

On any actual error, or if an attempt is made to use
command substitution, then the value of ENV is used
unchanged as the file name.

The expansion complies with POSIX XCU 2.5.3, though that
only requires parameter expansion - arithmetic expansion
is an extension (but for us, it is much easier to do, than
not to do, and it allows some weird stuff, if you're so
inclined....) Note that there is no ~ expansion (use $HOME).
 1.211 04-Dec-2018  kre Alter a design botch when magic (self modifying) variables
were added to sh ... in other shells, setting such a variable
(for most of them) causes it to lose its special properties,
and act the same as any other variable. I had assumed that
was just implementor laziness... I was wrong.

From now on the NetBSD shell will act like the others, and if vars
like HOSTNAME (and SECONDS, etc) are used as variables in a script
or whatever, they will act just like normal variables (and unless
this happens when they have been made local, or as a variable-assignment
as a prefix to a command, the special properties they would have had
otherwise are lost for the remainder of the life of the (sub-)shell
in which the variables were set).

Importing a value from the environment counts as setting the
value for this purpose (so if HOSTNAME is set in the environment,
the value there will be the value $HOSTNAME expands to).

The two exceptions to this are LINENO and RANDOM. RANDOM
needs to be able to be set to (re-)set its seed. LINENO needs to
be able to be set (at least in the "local" command) to achieve
the desired functionality. It is unlikely that any (sane) script
is going to want to use those two as normal vars however.

While here, fix a minor bug in popping local vars (fn return) that need
to notify the shell of changes in value (like PATH).

Change sh(1) to reflect this alteration. Also add doc of the
(forgotten) magic var EUSER (which has been there since the others
were added), and add a few more vars (which are documented
in other places in sh(1) - like ENV) into the defined or used
variable list (as well as wherever else they appear).

XXX pullup -8
 1.210 03-Dec-2018  kre Cleanup traps a bit - attempt to handle weird uses in traps, such
as traps that issue break/continue/return to cause the loop/function
executing when the trap occurred to break/continue/return, and
generating the correct exit code from the shell including when a
signal is caught, but the trap handler for it exits.

All that from FreeBSD.

Also make
T=$(trap)
work as it is supposed to (also trap -p).

For now this is handled by the same technique as $(jobs) - rather
than clearing the traps in subshells, just mark them invalid, and
then whenever they're invalid, clear them before executing anything
other than the special blessed "trap" command. Eventually we will
handle these using non-subshell command substitution instead (not
creating a subshell environ when the commands in a command-sub alter
nothing in the environment).
 1.209 23-Nov-2018  kre Avoid long option names that differ only in character case.
Change Xtrace (the name) to xlock instead. Aside from the different
name, there is no change to functionality.
 1.208 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.207 25-Aug-2018  kre PR bin/48875

Add a paragraph (briefer than previously posted to mailing lists)
to explain that there is no guarantee that the results of a command
substitution will be available before all commands started by the
cmdsub have completed.

Include the original proposed text (much longer) as *roff comments, so
it will at least be available to those who browse the man page sources.

While here, clean up the existing text about command substitutions to
make it a little more accurate (and to advise against using the `` form).
 1.206 03-May-2018  wiz branches: 1.206.2;
Remove Pps without effect.
 1.205 03-May-2018  kre Simplify convoluted language, and remove incorrect statement
(that I added a while ago) about what is required by POSIX.
 1.204 02-May-2018  pgoyette Minor grammatical correction (don't end a sentence/phrase with a
preposition).
 1.203 17-Mar-2018  uwe Drop "show or set the limit on" legalese from the description of each
and every option to ulimit built-in. The show-or-set text is already
supplied *both* before and after the list. Pedantically repeating it
for each option just adds a lot of visual clutter that gets in the way
of actually using this fragment of the manual page as a quick
reference.
 1.202 17-Mar-2018  uwe Tweak "ulimit" synopsis.
 1.201 17-Mar-2018  uwe Cleanup markup in the "Command Line Editing" section.
 1.200 17-Mar-2018  uwe Cleanup markup in the "Job Control" section.
 1.199 17-Mar-2018  uwe Use .Dv, not .Ev, to refer to LINENO, it's not an environment variable.
 1.198 16-Mar-2018  uwe Default values of PS1 and friends have only single space. Use .Li to
typeset them to make that space more visible in PostScript output.
 1.197 16-Mar-2018  uwe Use .Bd -literal for code example.
 1.196 16-Mar-2018  kre Markup fixes (partly from uwe@) and change some tabs to spaces, they
seem to work better...
 1.195 16-Mar-2018  kre Restore some (*roff) comments deleted in previous (partially unshave
the yak) for which the purpose was misunderstood. But trim one more hair.
 1.194 16-Mar-2018  kre Give the yak a quick trim and shave, and make one or two minor
wording changes (which are, hopefully, improvements).
 1.193 15-Mar-2018  uwe Start adding more gaudy markup. Use .Li or .Dv when referring to
parameters. Use more .Ic and .Ar when defining syntax.

The manual is still rather inconsistent e.g. when referring to
parameters where it randomly uses both $0 and 0 or $@ and @ - but I'm
not shaving that yak at least for now.
 1.192 14-Mar-2018  uwe Compute tag width for the list of options in Argument List Processing,
mandoc *is* up to that. Remove the part of the comment before the
list that was wondering about that.
 1.191 14-Mar-2018  uwe Small markup tweaks in Argument List Processing
 1.190 14-Mar-2018  uwe Instead of .Oo/.Oc use .Op directly where possible.
 1.189 14-Mar-2018  uwe Revert previous. Fix the real problem properly.
 1.188 14-Mar-2018  wiz Remove Ic macro without effect.
 1.187 13-Mar-2018  uwe Try to improve markup in the Built-ins section.
Mostly sprinkle missing .Ic and .Ar
 1.186 13-Mar-2018  uwe Try to improve markup in the Parameter Expansion section.
 1.185 13-Mar-2018  uwe Try to improve markup of the redirections definitions.
 1.184 13-Mar-2018  uwe Fix horrendous markup abuse in the here-document example.
Consistently spell "here-document" in full.
 1.183 13-Mar-2018  uwe Spell "here-document" with a hyphen, don't mark it up as a command.
 1.182 13-Mar-2018  uwe Mark up "in" (of the "for" command) appropriately.
 1.181 13-Mar-2018  uwe Use \(or not \*(Ba when discussing case patterns.
 1.180 13-Mar-2018  uwe Use \(em for em-dash
 1.179 13-Mar-2018  uwe Standalone | means \[ba] while we want \[or] so add \& protection to
the few places where it was missing.
 1.178 13-Mar-2018  uwe .Dl is a a single line .Bd -literal -offset indent so don't abuse
multiple consecutive .Dl and use proper .Bd instead.
 1.177 13-Mar-2018  uwe .Bd expects the display type to come first, so move -compact to the end.
 1.176 13-Mar-2018  uwe Add missing word.
 1.175 15-Jan-2018  kre branches: 1.175.2;

Paul Goyette suggested improvements to parts of the description of
LINENO ... this is what resulted (with thanks for the grammar lessons,
and sundry references provided!)

No date (Dd) bump - there is no change of substance here, just (hopefully)
a clearer way of saying the same thing.
 1.174 19-Nov-2017  kre Implement the -X option - an apparent variant of -x which sends all trace
output to the stderr which existed when the -X option was (last) enabled.
It also enables tracing by enabling -x (and when reset, +X, also resets
the 'x' flag (+x)). Note that it is still -x/+x which actually
enables/disables the trace output. Hence "apparent variant" - what -X
actually does (aside from setting -x) is just to lock the trace output,
rather than having it follow wherever stderr is later redirected.
 1.173 15-Nov-2017  kre Correct a typo: s/ at / an /
 1.172 30-Oct-2017  wiz Minor spellchecking changes.
 1.171 29-Oct-2017  kre Correct a markup typo (Sv -> Dv)
 1.170 28-Oct-2017  kre 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.169 25-Oct-2017  kre Add options to the builtin jobid command to allow discovering the
process group (-g), the process leader pid (-p) ($! if the job was &'d)
and the job identifier (-j) (the %n that refers to the job) in addition to
(default) the list of all pids in the job (which it has always done).
No change to the (single) "job" arg, which is a specifier of the job:
the process leader pid, or one of the % forms, and defaults to %% (aka %+).
(This is all now documented in sh(1))

Also document the jobs command properly (no change to the command, just
document what it actually is.)

And while here, a whole new section in sh(1) "Job Control". It probably
needs better wording, but this is (perhaps) better than the nothing that
was there before.
 1.168 15-Oct-2017  pgoyette Fix typo: s/one or mode/one or more/
 1.167 06-Oct-2017  kre Three fixes and a change to ~ expansions

1. A serious bug introduced 3 1/2 months ago (approx) (rev 1.116) which
broke all but the simple cases of ~ expansions is fixed (amazingly,
given the magnitude of this problem, no-one noticed!)

2. An ancient bug (probably from when ~ expansion was first addedin 1994, and
certainly is in NetBSD-6 vintage shells) where ${UnSeT:-~} (and similar)
does not expand the ~ is fixed (note that ${UnSeT:-~/} does expand,
this should give a clue to the cause of the problem.

3. A fix/change to make the effects of ~ expansions on ${UnSeT:=whatever}
identical to those in UnSeT=whatever In particular, with HOME=/foo
${UnSeT:=~:~} now assigns, and expands to, /foo:/foo rather than ~:~
just as VAR=~:~ assigns /foo:/foo to VAR. Note this is even after the
previous fix (ie: appending a '/' would not change the results here.)

It is hard to call this one a bug fix for certain (though I believe it is)
as many other shells also produce different results for the ${V:=...}
expansions than they do for V=... (though not all the same as we did).

POSIX is not clear about this, expanding ~ after : in VAR=whatever
assignments is clear, whether ${U:=whatever} assignments should be
treated the same way is not stated, one way or the other.

4. Change to make ':' terminate the user name in a ~ expansion in all cases,
not only in assignments. This makes sense, as ':' is one character that
cannot occur in user names, no matter how otherwise weird they become.
bash (incl in posix mode) ksh93 and bosh all act this way, whereas most
other shells (and POSIX) do not. Because this is clearly an extension
to POSIX, do this one only when not in posix mode (not set -o posix).
 1.166 27-Aug-2017  wiz Whitespace fixes. Fix a typo. Refer to emacs using Ic, since emacs(1)
does not exist in the base system.
 1.165 27-Aug-2017  wiz Remove unnecessary Tn macro.
 1.164 21-Aug-2017  kre Add support for $'...' quoting (based upon C "..." strings, with \ expansions.)

Implementation largely obtained from FreeBSD, with adaptations to meet the
needs and style of this sh, some updates to agree with the current POSIX spec,
and a few other minor changes.

The POSIX spec for this ( http://austingroupbugs.net/view.php?id=249 )
[see note 2809 for the current proposed text] is yet to be approved,
so might change. It currently leaves several aspects as unspecified,
this implementation handles those as:

Where more than 2 hex digits follow \x this implementation processes the
first two as hex, the following characters are processed as if the \x
sequence was not present. The value obtained from a \nnn octal sequence
is truncated to the low 8 bits (if a bigger value is written, eg: \456.)
Invalid escape sequences are errors. Invalid \u (or \U) code points are
errors if known to be invalid, otherwise can generate a '?' character.
Where any escape sequence generates nul ('\0') that char, and the rest of
the $'...' string is discarded, but anything remaining in the word is
processed, ie: aaa$'bbb\0ccc'ddd produces the same as aaa'bbb'ddd.

Differences from FreeBSD:
FreeBSD allows only exactly 4 or 8 hex digits for \u and \U (as does C,
but the current sh proposal differs.) reeBSD also continues consuming
as many hex digits as exist after \x (permitted by the spec, but insane),
and reject \u0000 as invalid). Some of this is possibly because that
their implementation is based upon an earlier proposal, perhaps note 590 -
though that has been updated several times.

Differences from the current POSIX proposal:
We currently always generate UTF-8 for the \u & \U escapes. We should
generate the equivalent character from the current locale's character set
(and UTF8 only if that is what the current locale uses.)
If anyone would like to correct that, go ahead.

We (and FreeBSD) generate (X & 0x1F) for \cX escapes where we should generate
the appropriate control character (SOH for \cA for example) with whatever
value that has in the current character set. Apart from EBCDIC, which
we do not support, I've never seen a case where they differ, so ...
 1.163 25-Jul-2017  wiz Remove trailing whitespace.
 1.162 24-Jul-2017  kre Implement the "pipefail" option (same semantics as in other shells)
to cause (when set, which it is not by default) the exit status of a
pipe to be 0 iff all commands in the pipe exited with status 0, and
otherwise, the status of the rightmost command to exit with a non-0
status.

In the doc, while describing this, also reword some of the text about
commands in general, how they are structured, and when they are executed.
 1.161 24-Jul-2017  kre Add support for ++ and -- (pre & post) and ',' to arithmetic.
 1.160 24-Jul-2017  kre Document the times builtin command, reported as lost in space
by rudolf at eq.cz on tech-userlevel (July 15, 2017.)

Also correct a typo, de-correct some entirely proper English so
the doc remains written in American instead. And note that
interactive mode is set when stdin & stderr are terminals, not
stding and stdout.
 1.159 01-Jul-2017  wiz Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
 1.158 30-Jun-2017  kre Correct a markup typo (why did I not see this before the prev commit??)
 1.157 30-Jun-2017  kre Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
 1.156 28-Jun-2017  kre Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
 1.155 27-Jun-2017  kre Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
 1.154 27-Jun-2017  wiz Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
 1.153 27-Jun-2017  kre Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
 1.152 17-Jun-2017  kre Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
 1.151 08-Jun-2017  kre Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
 1.150 07-Jun-2017  wiz New sentence, new line. Whitespace.
 1.149 07-Jun-2017  kre A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)

This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)

The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.

This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).

I would not call the results of this perfect yet, but it is close.
 1.148 06-Jun-2017  kre Fix a typo (or rather a remnant of an earlier intent).
 1.147 04-Jun-2017  kre Make cd (really) do cd -P, and not just claim that is what it is doing
while doing a half-hearted, broken, partial, version of cd -L instead.
The latter (as the manual says) is not supported, what's more, it is an
abomination, and should never be supported (anywhere.)

Fix the doc so that the pretense that we notice when a path given crosses
a symlink (and turns on printing of the destination directory) is claimed
no more (that used to be true until late Dec 2016, but was changed). Now
the print happens if -o cdprint is set, or if an entry from CDPATH that is
not "" or "." is used (or if the "cd dest repl" cd cmd variant is used.)

Fix CDPATH processing: avoid the magic '%' processing that is used for
PATH and MAILPATH from corrupting CDPATH. The % magic (both variants)
remains undocumented.

Also, don't double the '/' if an entry in PATH or CDPATH ends in '/'
(as in CDPATH=":/usr/src/"). A "cd usr.bin" used to do
chdir("/usr/src//usr.bin"). No more. This is almost invisible,
and relatively harmless, either way....

Also fix a bug where if a plausible destination directory in CDPATH
was located, but the chdir() failed (eg: permission denied) and then
a later "." or "" CDPATH entry succeeded, "print" mode was turned on.
That is:
cd /tmp; mkdir bin
mkdir -p P/bin; chmod 0 P/bin
CDPATH=/tmp/P:
cd bin
would cd to /tmp/bin (correctly) but print it (incorrectly).

Also when in "cd dest replace" mode, if the result of the replacement
generates '-' as the path named, as in:
cd $PWD -
then simply change to '-' (or attempt to, with CDPATH search), rather
than having this being equivalent to "cd -")

Because of these changes, the pwd command (and $PWD) essentially
always acts as pwd -P, even when called as pwd -L (which is still
the default.) That is, even more than it did before.

Also fixed a (kind of minor) mem management error (CDPATH related)
"whosoever shall padvance must stunalloc before repeating" (and the
same for MAILPATH).
 1.146 02-Jun-2017  abhinav branches: 1.146.2;
Fix typo
 1.145 27-May-2017  kre More standard (and saner) implementation of the ! reserved word.
Unless the shell is compiled with the (compilation time) option
BOGUS_NOT_COMMAND (as in CFLAGS+=-DBOGUS_NOT_COMMAND) which it
will not normally be, the ! command (reserved word) will only
be permitted at the start of a pipeline (which includes the
degenerate pipeline with no '|'s in it of course - ie: a simple cmd)
and not in the middle of a pipeline sequence (no "cmd | ! cmd" nonsense.)
If the latter is really required, then "cmd | { ! cmd; }" works as
a standard equivalent.

In POSIX mode, permit only one ! ("! pipeline" is ok. "! ! pipeline" is not).
Again, if needed (and POSIX conformance is wanted) "! { ! pipeline; }"
works as an alternative - and is safer, some shells treat "! ! cmd" as
being identical to "cmd" (this one did until recently.)
 1.144 27-May-2017  kre It turns out that most shells do not do variable value/attribute
inheritance when a variable is declared local, but instead leave
the local var unset (if not given a value) in the function.
Only ash derived shells do inheritance it seems.

So, to compensate for that, and get one step closer to making
"local" part of POSIX, so we can really rely upon it, a compromise
has been suggested, where "local x" is implementation defined
when it comes to this issue, and we add "local -I x" to specify
inheritance, and "local -N x" to specify "not" (something...)
(not inherited, or not set, or whatever you prefer to imagine!)
The option names took a lot of hunting to find something reasonable
that no shell (we know of) had already used for some other purpose...
The I was easy, but 'u' 'U' 'X' ... all in use somewhere.

This implements that (well, semi-) agreement.

While here, add "local -x" (which many other shells already have)
which causes the local variable to be made exported. Not a lot
of gain in that (since "export x" can always be done immediately
after "local x") but it is very cheap to add and allows more other
scripts to work with out shell.

Note that while 'local x="${x}"' always works to specify inheritance
(while making the shell work harder), "local x; unset x" does not
always work to specify the alternative, as some shells have
"re-interpreted" unset of a local variable to mean something that
would best be described as "unlocal" instead - ie: after the unset
you might be back with the variable from the outer scope, rather
than with an unset local variable.

Also add "unset -x" to allow unsetting a variable without removing
any exported status it has.

There are gazillions of other options that are not supported here!
 1.143 18-May-2017  kre Allow abbreviations of option names for the "fdflags -s" command.
While documenting that, cleanup markup of the fdflags section of the
man page.
 1.142 18-May-2017  kre Command line, and "set" command options processing cleanup.

sh +c "command string" no longer works (it must be -c)
sh +o and sh -o no longer work (if you could call what they did
before working.) nb: this is without an option name.
-ooo Opt1 Opt2 Opt3 no longer works (set & cmd line), this should be
-o Opt1 -o Opt2 -o Opt3 (same with +ooo of course).
-oOpt is now supported - option value (name of option in
this case) immediately following -o (or +o).
(as with other commands that use std opt parsing)
Both set comamnd and command line.

In addition, the output from "set +o" has shrunk dramatically, by borrowing
a trick from ksh93 (but implemented in a more traditional syntax).
"set +o" is required to produce a command (or commands) which when executed
later, will return all options to the state they were in when "set +o"
was done. Previously that was done by generating a set command, with
every option listed (set -o opt +o other-opt ...) to set them all back
to their current setings. Now we have a new "magic option" ("default")
which sets all options to their default values, so now set +o output
need only be "set -o default -o changed-opt ..." (only the options that
have been changed from their default values need be explicitly mentioned.)
The definition of "default value" for this is the value the shell set the
option to, after startup, after processing the command line (with any
flags, or -o option type settings), but before beginning processing any
user input (incuding startup files, like $ENV etc).

Anyone can execute "set -o default" of course, but only from a "set"
command (it makes no sense at all as a -o option to sh). This also
causes "set +o" to be slightly more useful as a general command, as
ignoring the "set -o default" part of the result, it lists just those
options that have been altered after sh startup. There is no +o default.
There isn't an option called "default" at all...

This causes some of the commented out text from sh.1 to become uncommented.
 1.141 14-May-2017  kre When opening a file descritor with "exec n>/file" (and similar) only
set the close-on-exec bit when not in posix mode (to comply with posix...)
OK: christos@
 1.140 14-May-2017  kre Add mention of ;& in the list of control operators (forgotten before).
Document the (slightly) enhanced NETBSD_SHELL.
Fix a typo (one of my typos...)
Move a commented out section to align with current planned changes
(and fix its commented out markup.)
 1.139 14-May-2017  wiz Use more, or more appropriate, markup.
 1.138 12-May-2017  kre Improve the description of option processing (including the shell's
arg list processing), and the set command in general.
Also add some (new) commented out text related to options which may
be commented back in sometime soon...
 1.137 12-May-2017  kre Corrected some typos, added some (hopefully improving) extra text,
sorted stuff that needed sorting, and added some (probably incorrect)
markup...
 1.136 07-May-2017  kre Enhance the trap command to make it possible to do what POSIX wants
(even if no shell in existence, that I am aware of, does that).

That is, POSIX says ... [of the trap command with no args]

The shell shall format the output, including the proper use of
quoting, so that it is suitable for re-input to the shell as commands
that achieve the same trapping results. For example:

save_traps=$(trap)

...

eval "$save_traps"

It is obvious what the intent is there. But no shell makes it work.

An example using bash (as the NetBSD shell, still does not do the save_traps=
stuff correctly - but that is a problem for a different time and place...)

Given this script

printf 'At start: '; trap
printf '\n'

traps=$(trap)
trap 'echo hello' INT
printf 'inside : '; trap
printf '\n'
eval "${traps}"

printf 'At end : '; trap
printf '\n'

One would expect that (assuming no traps are set at the start, and
there aren't) that the first trap will print nothing, then the inside
trap will show the trap that was set, and then when we get to the
end everything will be back to nothing again.

But:

At start:
inside : trap -- 'echo hello' SIGINT

At end : trap -- 'echo hello' SIGINT

And of course. when you think about it, it is obvious why this happens.
The first "trap" command prints nothing ... nothing has changed when we
get to the "traps=$(trap)" command ... that trap command also prints
nothing. So this does traps=''. When we do eval "${traps}" we are
doing eval "", and it is hardly surprising that this accomplishes nothing!

Now we cannot rationally change the "trap" command without args to
behave in a way that would make it useful for the posix purpose (and
here, what they're aiming for is good, it should be possible to
accomplish that objective) so is there some other way?

I think I have seen some shell (but I do not remember which one) that
actually has "trap -" that resets all traps to the default, so with that,
if we changed the 'eval "${traps}"' line to 'trap -; eval "${traps}"'
then things would actually work - kind of - that version has race conditions,
so is not really safe to use (it will work, most of the time...)

But, both ksh93 and bash have a -p arg to "trap" that allows information
about the current trap status of named signals to be reported. Unfortunately
they don't do quite the same thing, but that's not important right now,
either would be usable, and they are, but it is a lot of effort, not
nearly as simple as the posix example.

First, while "trap -p" (with no signals specified) works, it works just
the same (in both bash and ksh93, aside from output format) as "trap".
That is, that is useless. But we can to

trap_int=$(trap -p int)
trap_hup=$(trap -p hup)
...

and then reset them all, one by one, later...

(bash syntax)
test -n "${trap_int}" && eval "${trap_int}" || trap - int
test -n "${trap_hup}" && eval "${trap_hup}" || trap - hup
(ksh93 syntax)
trap "${trap_int:-}" int
trap "${trap_hup:-}" hup

the test (for bash) and variable with default for ksh93, is needed
because they both still print nothing if the signal action is the default.

So, this modification attempts to fix all of that...

1) we add trap -p, but make it always output something for every signal
listed (all of the signals if none are given) even if the signal
action is the default.

2) choose the bash output format for trap -p, over the ksh93 format,
even though the simpler usage just above makes the ksh93 form seem
better. But it isn't. Consider:

ksh93$ trap -p int hup
echo hello

One of the two traps has "echo hello" as its action, the other is
still at the default, but which?

From bash...
bash$ trap -p int hup
trap -- 'echo hello' SIGINT

And now we know! Given the bash 'trap -p' format, the following function
produces ksh93 format output (for use with named signals only) instead...

ksh93_trap_p() {
for _ARG_ do
_TRAP_=$(trap -p "${_ARG_}") || return 1
eval set -- "${_TRAP_}"
printf '%s' "$3${3:+
}"
done
return 0
}

[ It needs to be entered without the indentation, that '}"' line has to be
at the margin. If the shell running that has local vars (bash does) then
_ARG_ and _TRAP_ should be made local. ]

So the bash format was chosen (except we do not include the "SIG" on the
signal names. That's irrelevant.)

If no traps are set, "trap -p" will say (on NetBSD of course)...

trap -- - EXIT HUP INT QUIT ILL TRAP ABRT EMT FPE KILL BUS SEGV SYS
trap -- - PIPE ALRM TERM URG STOP TSTP CONT CHLD TTIN TTOU IO XCPU XFSZ
trap -- - VTALRM PROF WINCH INFO USR1 USR2 PWR RT0 RT1 RT2 RT3 RT4 RT5
trap -- - RT6 RT7 RT8 RT9 RT10 RT11 RT12 RT13 RT14 RT15 RT16 RT17 RT18
trap -- - RT19 RT20 RT21 RT22 RT23 RT24 RT25 RT26 RT27 RT28 RT29 RT30

Obviously if traps are set, the relevant signal names will be removed from
that list, and additional lines added for the trapped signals.

With args, the signals names are listed, one line each, whatever
the status of the trap for that signal is:

$ trap -p HUP INT QUIT
trap -- - HUP
trap -- 'echo interrupted' INT
trap -- - QUIT

3) we add "trap -" to reset all traps to default. (It is easy, and seems
useful.)

4) While here, lots of generic cleanup. In particular, get rid of the
NSIG+1 nonsense, and anything that ever believes a signo == NSIG
is in any way rational. Before there was a bunch of confusion,
as we need all the signals for traps, plus one more for the EXIT
trap, which looks like we then need NSIG+1. But EXIT is 0, NSIG
includes signals from 0..NSIG-1 but there is no signal 0, EXIT
uses that slot, so we do not need to add and extra one, NSIG is
enough. (To see the effect of this, use a /bin/sh from before
this fix, and compare the output from

trap '' 64
and trap '' 65

both invalid signal numbers.

Then try just "trap" and watch your shell drop core...)

Eventually NSIG needs to go away completely (from user apps), it
is not POSIX, it isn't really useful (unless we make lots of
assumptions about how signals are numbered, which are not guaranteed,
so even if apps, like this sh, work on NetBSD, they're not portable,)
and it isn't necessary (or will not be, soon.)

But that is for another day...

5) As is kind of obvious above, when listing "all" traps, list all the
ones still at their defaults, and all the ignored signals, on as
few lines as possible (it could all be on one line - technically it
would work as well, but it would have made this cvs log message
really ugly...) Signals with a non-null action still get listed
one to a line (even if several do have the exact same action.)

6) Man page updates as well.

After this change, the following script:

printf 'At start: '; trap
printf '\n'

trap -p >/tmp/out.$$
trap 'echo hello' INT
printf 'inside : '; trap
printf '\n'
. /tmp/out.$$; rm /tmp/out.$$

printf 'At end : '; trap
printf '\n'

which is just the example from above,
using "trap -p" instead of just "trap" to save the traps,
and modified to a form that will work with the NetBSD shell today
produces:

At start:
inside : trap -- 'echo hello' INT

At end :

[Do I get a prize for longest commit log message of the year?]
 1.135 04-May-2017  kre Implement the ';&' (used instead of ';;') case statement list terminator
which causes fall through the to command list of the following pattern
(wuthout evaluating that pattern). This has been approved for inclusion
in the next major version of the POSIX standard (Issue 8), and is
implemented by most other shells.

Now all form a circle and together attempt to summon the great wizd
in the hopes that his magic spells can transform the poor attempt
at documenting this feature into something rational...
 1.134 03-May-2017  kre Undocument (comment out) the description of the unimplemented MAILCHECK
variable, and while here, enhance the description of MAIL a little.
 1.133 30-Apr-2017  wiz Uppercase UID. Fix typo.
 1.132 29-Apr-2017  kre Correct description of the trap command (make it posix compatible)
and add a couple more examples. Also terminate a few sentences...
 1.131 14-Apr-2017  abhinav branches: 1.131.2;
Fix mandoc -Tlint warnings:
s/PP/Pp
Remove Pp before It
 1.130 14-Apr-2017  abhinav Instead of removing markup as I did in the last commit, use markup but properly.
Hint taken from FreeBSD man page.

ok wiz@
 1.129 03-Apr-2017  abhinav Use \- instead of .Fl for the -number argument.

.Fl causes the -number argument to be rendered in bold, which causes confusion
with the [+]number argument right above it.

ok wiz@
 1.128 23-Mar-2017  kre PR bin/14578

Add a reference to editline(7) so we document the "-o vi" and "-o emacs"
bindings (defaults, and what can be set.)
 1.127 20-Mar-2017  kre At the suggestion of Matthew Sporleder (on current-users@) reword some
of the description of arithmetic expressions to make it a bit more
human friendly.

While here fix a few other minor errors, and bump date.
 1.126 20-Mar-2017  kre Finish support for all required $(( )) (shell arithmetic) operators,
closing PR bin/50958

That meant adding the assignment operators ('=', and all of the +=, *= ...)
Currently, ++, --, and ',' are not implemented (none of those are required
by posix) but support for them (most likely ',' first) might be added later.

To do this, I removed the yacc/lex arithmetic parser completely, and
replaced it with a hand written recursive descent parser, that I obtained
from FreeBSD, who earlier had obtained it from dash (Herbert Xu).

While doing the import, I cleaned up the sources (changed some file names
to avoid requiring a clean build, or signifigant surgery to the obj
directories if "build.sh -u" was to be used - "build.sh -u" should work
fine as it is now) removed some dashisms, applied some KNF, ...
 1.125 04-Feb-2017  wiz Remove trailing space.
 1.124 02-Feb-2017  christos Add fdflags builtin. Discussed with Chet and he has implemented it for
bash too.
 1.123 12-May-2016  kre branches: 1.123.2; 1.123.4;

Document that a N>&N (or N<&N) redirection turns off close-on-exec for N
(where N is a decimal fd number) either when used as
some-command N>&N
(where fd N is passed, open, to some-command - which is obviously what is
wanted)

Or as
exec N>&N
which effects fd N for all future commands.

Note that this means
exec N>foo N>&N
returns to the old behaviour of leaving the file descriptor open
when commands are run (as do most shells, other than ksh) and works for
both new and old NetBSD shells (old ones never set close-on-exec, and treat
N>&N as a rather meaingless no-op request, and just ignore it), new ones
set close-on-exec on the first redirection, then disable it again on the
second.

Everything here about >& for output fds applies to <& for input ones.

OK christos@
 1.122 09-May-2016  kre PR bin/48489 -- Shell "simple commands" are now not allowed to be
completely empty, they must have something (var assignment, redirect,
or command, or multiple of those) to avoid a syntax error. This
matches the requirements of the grammar in the standard. Correct the
parser (using FreeBSD's sh as a guide) and update the man page to
remove text that noted a couple of places this was previously OK.

OK christos@
 1.121 04-Apr-2016  wiz Remove some double quotes.

Parity is kept.
 1.120 31-Mar-2016  christos Document the NETBSD_SHELL variable, the enhancements to export,
the posix option, and a whole bunch of miscellaneous updates and
corrections. (from kre@)
 1.119 24-Feb-2016  wiz file system police.
 1.118 24-Feb-2016  christos Make sh.1 catch up with reality. Document -h (such as it is...)
and also added doc for some other stuff that was missing.

Take the opportunity to clean up the way the flags are set in the
man page, so every new flag doesn't have to be added 6 times!
(Some of the lists were different from others, in ordering, and
content, for no good reason at all.)

Make a few other cleanups ... Add text about AND-OR lists,
This can be also used to justify closing an open PR:
(that "sh -c 'command &&'" is not a syntax error...).

Add doc for -F, which should default to set if the shell somehow
gets compiled without DO_SHAREDVFORK defined, (to be committed
separately)

XXX: Consider disabling DO_SHAREDVFORK if SMALL is defined?

From kre
 1.117 06-Jan-2016  wiz Whitespace.
 1.116 05-Jan-2016  christos Document close-on-exec redirection behavior.
 1.115 26-May-2015  christos Drop privileges when executed set{u,g}id unless -p is specified like other
shells do to avoid system() and popen() abuse.
 1.114 01-Jun-2014  christos PR/48843: Jarmo Jaakkola: Soften the language in the manual page,
making less promises about behavior not explicitly stated in the standard.
 1.113 31-May-2014  christos PR/48843: Jarmo Jaakkola: dot commands mess up scope nesting tracking

Evaluation of commands goes completely haywire if a file containing
a break/continue/return command outside its "intended" scope is sourced
using a dot command inside its "intended" scope. The main symptom is
not exiting from the sourced file when supposed to, leading to evaluation
of commands that were not supposed to be evaluated. A secondary symptom
is that these extra commands are not evaluated correctly, as some of them
are skipped. Some examples are listed in the How-To-Repeat section.

According to the POSIX standard, this is how it should work:
dot:
The shell shall execute commands from the file in the current
environment.
break:
The break utility shall exit from the smallest enclosing for, while,
or until loop, [...]
continue:
The continue utility shall return to the top of the smallest
enclosing for, while, or until loop, [...]
return:
The return utility shall cause the shell to stop executing
the current function or dot script. If the shell is not currently
executing a function or dot script, the results are unspecified.

It is clear that return should return from a sourced file, which
it does not do. Whether break and continue should work from the sourced
file might be debatable. Because the dot command says "in the current
environment", I'd say yes. In any case, it should not fail in weird
ways like it does now!

The problems occur with return (a) and break/continue (b) because:
1) dotcmd() does not record the function nesting level prior to
sourcing the file nor does it touch the loopnest variable,
leading to either
2 a) returncmd() being unable to detect that it should not set
evalskip to SKIPFUNC but SKIPFILE, or
b) breakcmd() setting evalskip to SKIPCONT or SKIPBREAK,
leading to
3) cmdloop() not detecting that it should skip the rest of
the file, due to only checking for SKIPFILE.
The result is that cmdloop() keeps executing lines from the file
whilst evalskip is set, which is the main symptom. Because
evalskip is checked in multiple places in eval.c, the secondary
symptom appears.
>How-To-Repeat:
Run the following script:

printf "break\necho break1; echo break2" >break
printf "continue\necho continue1; echo continue2" >continue
printf "return\necho return1; echo return2" >return

while true; do . ./break; done

for i in 1 2; do . ./continue; done

func() {
. ./return
}
func

No output should be produced, but instead this is the result:
break1
continue1
continue1
return1

The main symptom is evident from the unexpected output and the secondary
one from the fact that there are no lines with '2' in them.
>Fix:
Here is patch to src/bin/sh to fix the above problems. It keeps
track of the function nesting level at the beginning of a dot command
to enable the return command to work properly.

I also changed the undefined-by-standard functionality of the return
command when it's not in a dot command or function from (indirectly)
exiting the shell to being silently ignored. This was done because
the previous way has at least one bug: the shell exits without asking
for confirmation when there are stopped jobs.

Because I read the standard to mean that break and continue should have
an effect outside the sourced file, that's how I implemented it. For what
it's worth, this also seems to be what bash does. Also laziness, because
this way required no changes to loopnesting tracking. If this is not
wanted, it might make sense to move the nesting tracking to the inputfile
stack.

The patch also does some clean-up to reduce the amount of global
variables by moving the dotcmd() and the find_dot_file() functions from
main.c to eval.c and making in_function() a proper function.
 1.112 20-Jan-2014  roy branches: 1.112.2;
Add wctype(3) support to Shell Patterns.
Obtained from FreeBSD.
 1.111 02-Oct-2013  christos document LINENO
XXX: someone should fix all the .Ev stuff because some of them are just
shell variables .Va and are not really exported to the environment. See
the FreeBSD man page.
 1.110 09-May-2013  simonb Document that a here-document can finish at an EOF as well as at the
delimiter.
 1.109 03-Oct-2012  wiz - Correct macro usage;
- improve wording, including creating more consistency therein.

From Bug Hunting.
 1.108 26-Aug-2012  wiz branches: 1.108.2;
- improve punctuation;
- improve (create more consistency in) spelling;
- remove unnecessary (and in part ignored) macros, as well as an
unnecessary argument to `.Bl' (fixes mandoc(1) warnings);
- improve wording;
- bump date.

Patch from Bug Hunting.
 1.107 11-Jun-2012  njoly Allow thread limit queries by adding the new -r flag to ulimit. Add
the corresponding documentation in the man page.
 1.106 05-Oct-2011  christos branches: 1.106.2;
Merge duplicate information.
 1.105 04-Oct-2011  apb .Dq Dv \&:
 1.104 04-Oct-2011  christos Mention what happens when we don't include :. It would be nice to use
.Dv :
but it produces ``'':
 1.103 11-Sep-2011  dholland A feature that wasn't implemented for 4.4alpha and still isn't implemented
is just plain not implemented.
 1.102 13-Jun-2011  wiz Sort sections. Remove trailing whitespace.
 1.101 13-Jun-2011  uebayasi Typos.
 1.100 11-Jun-2011  christos document OLDPWD and cd -
 1.99 03-Jun-2010  dholland branches: 1.99.4;
Note that set -o tabcomplete requires either set -o emacs or set -o vi
to work.
 1.98 01-Mar-2010  joerg \\ -> \e
 1.97 01-Jan-2010  wiz Bump date for cd -P support.
 1.96 01-Jan-2010  dholland fix another typo
 1.95 01-Jan-2010  dholland Make the cd builtin accept and ignore -P, which is a kshism that has been
allowed to leak into POSIX and selects the behavior cd already implements.
Closes PR bin/42557 and also relevant to PR pkg/42168.

I suppose this should probably be pulled up to both -4 and -5...
 1.94 01-Jan-2010  dholland fix typo
 1.93 29-Mar-2009  wiz Bump date for previous.
 1.92 29-Mar-2009  mrg - add new RLIMIT_AS (aka RLIMIT_VMEM) resource that limits the total
address space available to processes. this limit exists in most other
modern unix variants, and like most of them, our defaults are unlimited.
remove the old mmap / rlimit.datasize hack.

- adds the VMCMD_STACK flag to all the stack-creation vmcmd callers.
it is currently unused, but was added a few years ago.

- add a pair of new process size values to kinfo_proc2{}. one is the
total size of the process memory map, and the other is the total size
adjusted for unused stack space (since most processes have a lot of
this...)

- patch sh, and csh to notice RLIMIT_AS. (in some cases, the alias
RLIMIT_VMEM was already present and used if availble.)

- patch ps, top and systat to notice the new k_vm_vsize member of
kinfo_proc2{}.

- update irix, svr4, svr4_32, linux and osf1 emulations to support
this information. (freebsd could be done, but that it's best left
as part of the full-update of compat/freebsd.)


this addresses PR 7897. it also gives correct memory usage values,
which have never been entirely correct (since mmap), and have been
very incorrect since jemalloc() was enabled.

tested on i386 and sparc64, build tested on several other platforms.

thanks to many folks for feedback and testing but most espcially
chuq and yamt for critical suggestions that lead to this patch not
having a special ugliness i wasn't happy with anyway :-)
 1.91 10-Mar-2009  joerg Explicitly escape -- as it is not an argment to the Cm macro.
 1.90 10-Mar-2009  joerg Don't use .Xo/.Xc to workaround ancient macro argument limit.
 1.89 09-Mar-2009  joerg Fix preamble to match order set out by mdoc(7). Discussed with wiz.
 1.88 11-Dec-2008  yamt branches: 1.88.2;
document "EXIT" pseudo signal.
 1.87 24-Jun-2007  christos branches: 1.87.18;
PR/36533: Greg A. Woods: minor doc fixes for sh(1)
 1.86 25-Mar-2007  apb Document that shell arithmetic now uses intmax_t. Document that
variables in shell arithmetic don't need "$" signs.
 1.85 04-Sep-2006  dsl branches: 1.85.2;
Fix typo, update date.
Fixes PR/34472
 1.84 10-Sep-2005  wiz In mdoc, use .Pp for new paragraphs, not .br.
 1.83 20-Aug-2005  dsl Don't apply CDPATH if the the first component of the target is "." or "..".
Fixes PR/30973 and applies the principle of least surprise.
Update documentation to match (including date).
(matches behaviour of pdksh - if not it's documentation)
 1.82 15-Jul-2005  wiz Aspell, fix an Xref, drop trailing whitespace.
 1.81 15-Jul-2005  christos Allow trap to work on ignored signals when the shell is interactive.
 1.80 24-May-2005  wiz Whitespace and punctuation fixes.
 1.79 07-May-2005  dsl If 'set -o tabcomplete' it set, then bind <tab> to the libedit filename
completion function.
Note that the libedit code will probably want fine-tuning!
While editing the man page, add a note that non-whitespace IFS chars are
terminators and can generate null arguments.
 1.78 03-Jun-2004  hubertf Fix typo: and the -> and then
 1.77 23-Apr-2004  wiz Fix typo noted by Patrick Welche.
 1.76 17-Apr-2004  wiz Bump date for previous.
 1.75 17-Apr-2004  christos understand rlimit sbsize
 1.74 21-Dec-2003  wiz Fix example added in previous.
 1.73 21-Dec-2003  jdolecek add a note to Short-Circuit operators section about the somewhat
nonintuitive evaluation in case there is both || and && specified
pointed out in bin/23814 by VaX#n8
 1.72 18-Dec-2003  heas correct 2 typos
 1.71 14-Nov-2003  dsl Posix requires that 'pwd -P' reset the shells saved cwd value - so a
subsequent 'pwd -L' will report the same value.
Update man page to be a closer match to reality.
 1.70 27-Oct-2003  wiz passwd(5), not passwd(4). From Igor Sobrado in PR 23278.
 1.69 27-Oct-2003  wiz Do not xref alias(1) since that points to csh(1).
Noted by Igor Sobrado in PR 23278, fixed following a suggestion by Greg A. Woods.
 1.68 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.67 27-Jun-2003  wiz Quote some punctuation.
 1.66 06-May-2003  wiz Drop trailing space.
 1.65 04-May-2003  gmcgarry Add new builtin 'inputrc' which allows keybindings to be redefined
for the current shell. From Arne H Juul in PR#10097.
 1.64 02-May-2003  gmcgarry Expand documentation of emacs and vi modes. From
Jeremy C. Reed in PR#14578.
 1.63 12-Apr-2003  zuntum add missing parenthesis
 1.62 22-Mar-2003  kristerw Change "if" to "if and only if" per discussion in PR 20794.
 1.61 25-Feb-2003  wiz .Nm does not need a dummy argument ("") before punctuation or
for correct formatting of the SYNOPSIS any longer.
 1.60 12-Feb-2003  wiz New sentence, new line; bump date for last change.
 1.59 12-Feb-2003  gmcgarry Introduce LANG environment variable and Xref to nls(7).
Comment out the statement: "We expect POSIX conformance
by the time 4.4BSD is released."
 1.58 23-Jan-2003  wiz Fix indentation of continuation of first line in SYNOPSIS.
 1.57 22-Jan-2003  wiz More markup, more commas, less typos.
 1.56 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.55 28-Dec-2002  uebayasi trap '' SIGINT -> trap '' INT.
 1.54 19-Dec-2002  kleink Another it's -> its.
 1.53 12-Dec-2002  uebayasi `` [n1]>&n2 Duplicate standard output (or n1) _TO_ n2.''
 1.52 02-Oct-2002  wiz filesystem -> file system, automaticly -> automatically.
 1.51 01-Oct-2002  wiz Use more mdoc, particularly to get rid of some \*[Lt] and \*[Gt].
 1.50 25-Sep-2002  wiz New policy: New sentences start on a new line.
Patches by Robert Elz <kre at munnari oz au>, with minimal changes by me.
 1.49 15-May-2002  bjh21 Implement sh -a (allexport). Code (all two lines of it) from FreeBSD
(FreeBSD var.c 1.13, sh.1 1.27).
 1.48 15-May-2002  christos implement noclobber. From Ben Harris, with minor tweaks from me. Two
unimplemented comments to go. Go Ben!
 1.47 15-May-2002  christos Implement unset variable error messages from Ben Harris.
 1.46 24-Feb-2002  lukem first variable argument to "read" is not optional
 1.45 08-Feb-2002  ross Generate <>& symbolically. I'm avoiding .../dist/... directories for now.
 1.44 20-Dec-2001  wiz Punctuation nits, drop unnecessary .Pps, sort sections.
 1.43 03-Apr-2001  wiz Don't xref set(1) and case(1), since they are builtins and we don't
have separate man pages for them.
Xref passwd 5 instead of 4, environ 7 instead of 5, and comment out xref
to profile(4), which we don't have.
Improve markup of SYNOPSIS.
Some whitespace fixes while I'm here.
 1.42 01-Apr-2001  toddpw Correct {list;} example and fix formatting/typo in the operator lists.
 1.41 18-Mar-2001  wulf Extended functionality of the trap builtin, which now closely follows
POSIX recommendations.

- trap now accepts signal names and signal numbers
e.g. INT, SIGINT, 2
- added option -l that outputs a list of valid signals
- added signal EXIT to list of valid signals
- a `-' in the action part will reset specified signal to their
default behaviour
- changed standard output format to make it suitable as an input
to another shell that achieves the same trapping results
 1.40 20-Nov-2000  christos fix typo.
 1.39 20-Nov-2000  christos Add an example on how to use getopts, stolen from the getopt manual page :-)
 1.38 21-Sep-2000  phil .Bl takes parameter "-offset indent", not "-indent".
 1.37 04-Sep-2000  kleink For commands and utilities, use EXIT STATUS rather than RETURN VALUES as
appropriate (and documented in mdoc(7)).
 1.36 28-Aug-2000  hubertf Add 'RETURN VALUE' section header.
 1.35 18-Jul-2000  jhawk Various mandoc updates to the Builtins
section; mostly .Ic, a few other nits.
 1.34 17-Jul-2000  jhawk Note the meaning of 'trap 0' (execute on exit from shell)
 1.33 16-Nov-1999  hubertf branches: 1.33.4;
Add under which conditions the "read" builtin returns success/failure.

Suggested in PR 8813 by Eric Mumpower <nocturne@arepa.com>
 1.32 28-Sep-1999  bouyer xref sysctl(8) (for proc.<pid>.rlimits)
 1.31 27-Sep-1999  mjl Mention -c option to sh(1), noticed by Matthew Aldous in PR/8499.
 1.30 06-Jul-1999  christos branches: 1.30.2;
add -q in the synopsis line
 1.29 23-Mar-1999  ross Make the `...' actually appear in the case/esac syntax section.
Fix a space botch in the $@ example.
Kill warnings caused by the effective but wrong use of \[ and \] to
perform the function of \&[ and \&].
 1.28 04-Feb-1999  cjs Add -q option, which when used with -v and/or -x, turns off the tracing
during the execution of /etc/profile, .profile and $ENV.
 1.27 28-Jan-1999  kleink Add support for the export and readonly -p option.
 1.26 11-Jan-1999  garbled Massive fixup:
Rewrite man page in mandoc format rather than nasty man format.
Fix a ton of parsing errors, and generate proper .Xr's.
document all known environment variables.
suggest ksh rather than bash.

The last two fix PR #1966. Wheee!

Somebody with access to the POSIX spec needs to go in here, and document
our adherence, or lack thereof.
 1.25 17-Nov-1998  msaitoh fix some bugs
 1.24 29-Oct-1998  garbled Modify to better document getopts. This fixes PR# 704. Much thanks to
Christos for helping me out with this.
 1.23 04-Jul-1998  ross Small edit to n1>&n2 description.
 1.22 05-Nov-1997  kleink Per 1003.2, the (builtin) read utility shall treat the backslash as an
escape character (including line continuation), unless the `-r' option
is specified:
* adopt to this behaviour, add the `-r' option to disable it;
* remove the `-e' option, which was previously necessary to get this behaviour.
 1.21 10-Jul-1997  phil branches: 1.21.2;
Add a missing ) in the description of the builtin "set".
 1.20 23-May-1997  cjs Add documentation for ulimit command, courtsey of
Eric Fischer <eric@fudge.uchicago.edu>.
 1.19 08-Mar-1997  mouse alternate -> alternative, per PR 2643
 1.18 06-Feb-1997  christos add type builtin.
 1.17 16-Oct-1996  christos PR/2808: Add HISTORY section and documentation of getopts. (from FreeBSD)
 1.16 02-Sep-1996  christos Apply PR#2721 from VaX#n8: make man page more lucid in places.
 1.15 11-May-1995  christos branches: 1.15.6;
Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.14 21-Mar-1995  cgd convert to new RCS id conventions.
 1.13 23-Jan-1995  christos I added the documented in the manual but not implemented variable expansions:

${#WORD}
${WORD%PAT}
${WORD%%PAT}
${WORD#PAT}
${WORD##PAT}
 1.12 12-Jan-1995  jtc Describe the : shell builtin.
Fixes PR #712.
 1.11 11-Jun-1994  mycroft Add RCS ids.
 1.10 11-May-1994  jtc sync with 4.4lite
 1.9 04-May-1994  jtc Comment out sections of the manpages that are not, and will probably never
be, appropriate for ash as configured for NetBSD. In particular the /u
"magic" directory, and atty(1) support.
 1.8 03-Feb-1994  jtc spelling mistakes
 1.7 27-Jan-1994  jtc Remove text describing how the dot command does not do a $PATH search,
since we added that behavior to get closer to POSIX.2.
 1.6 01-Aug-1993  mycroft Add RCS identifiers.
 1.5 02-May-1993  mycroft Fix typo.
 1.4 22-Apr-1993  mycroft Fix various bugs in man pages (from 386BSD patch 130).
 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.15.6.2 04-Mar-1997  mycroft Pull up latest sh(1). Fixes yet more bugs.
 1.15.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.21.2.1 06-Nov-1997  mellon Pull rev 1.22 up from trunk (kleink)
 1.30.2.1 27-Dec-1999  wrstuden Pull up to last week's -current.
 1.33.4.7 23-Feb-2002  he Pull up revision 1.41 (requested by jonb):
Extend functionality of the trap builtin, which now more closely
follows POSIX recommendations:
o accept signal names as well as signal numbers
o add ``-l'' option which outputs list of valid signals
o add signal EXIT to list of valid signals
o an ``-'' in the action part will reset signal to default behaviour
o changed standard output of ``trap'' to make it suitable as
subsequent input
 1.33.4.6 04-Apr-2001  he Pull up revision 1.43 (via patch, requested by wiz):
Don't xref set(1) and case(1), since they are builtins and we don't
have separate man pages for them.
Xref passwd 5 instead of 4, environ 7 instead of 5, and comment out xref
to profile(4), which we don't have.
Improve markup of SYNOPSIS.
Some whitespace fixes while I'm here.
 1.33.4.5 18-Mar-2001  wulf Reversed submission of trap.c and sh.1 to wrong branch
 1.33.4.4 17-Mar-2001  wulf Extended functionality of the trap builtin, which now closely follows
POSIX recommendations.

- trap now accepts signal names and signal numbers
e.g. INT, SIGINT, 2
- added option -l that outputs a list of valid signals
- added signal EXIT to list of valid signals
- a `-' in the action part will reset specified signal to their
default behaviour
- changed standard output format to make it suitable as an input
to another shell that achieves the same trapping results
 1.33.4.3 21-Sep-2000  phil .Bl argument is "-offset indent", not "-indent" (Approved thropej.)
 1.33.4.2 28-Aug-2000  hubertf Pull up to netbsd-1-5 branch, OK'd by thorpej:

Log Message:
> Add 'RETURN VALUE' section header.

Files & Revisionis:
> cvs rdiff -r1.19 -r1.20 basesrc/bin/cat/cat.1
> cvs rdiff -r1.12 -r1.13 basesrc/bin/chmod/chmod.1
> cvs rdiff -r1.14 -r1.15 basesrc/bin/cp/cp.1
> cvs rdiff -r1.8 -r1.9 basesrc/bin/dd/dd.1
> cvs rdiff -r1.9 -r1.10 basesrc/bin/echo/echo.1
> cvs rdiff -r1.11 -r1.12 basesrc/bin/expr/expr.1
> cvs rdiff -r1.25 -r1.26 basesrc/bin/ls/ls.1
> cvs rdiff -r1.10 -r1.11 basesrc/bin/mkdir/mkdir.1
> cvs rdiff -r1.23 -r1.24 basesrc/bin/mt/mt.1
> cvs rdiff -r1.12 -r1.13 basesrc/bin/mv/mv.1
> cvs rdiff -r1.16 -r1.17 basesrc/bin/pwd/pwd.1
> cvs rdiff -r1.9 -r1.10 basesrc/bin/rm/rm.1
> cvs rdiff -r1.11 -r1.12 basesrc/bin/rmdir/rmdir.1
> cvs rdiff -r1.35 -r1.36 basesrc/bin/sh/sh.1
> cvs rdiff -r1.11 -r1.12 basesrc/bin/sleep/sleep.1
> cvs rdiff -r1.20 -r1.21 basesrc/bin/stty/stty.1
 1.33.4.1 18-Jul-2000  jhawk Pullup revs 1.34, 1.35, approved by jhawk.
rev 1.34:
Note the meaning of 'trap 0' (execute on exit from shell)
rev 1.35:
Various mandoc updates to the Builtins
section; mostly .Ic, a few other nits.
 1.85.2.2 27-Jan-2010  bouyer Pull up following revision(s) (requested by dholland in ticket #1380):
bin/sh/cd.c: revision 1.40
bin/sh/sh.1: revision 1.95
bin/sh/sh.1: revision 1.97
Make the cd builtin accept and ignore -P, which is a kshism that has been
allowed to leak into POSIX and selects the behavior cd already implements.
Closes PR bin/42557 and also relevant to PR pkg/42168.
I suppose this should probably be pulled up to both -4 and -5...
Bump date for cd -P support.
 1.85.2.1 16-Apr-2007  bouyer Pull up following revision(s) (requested by apb in ticket #570):
bin/sh/expand.c: revision 1.78
bin/sh/arith.y: revision 1.18
bin/sh/expand.h: revision 1.17
regress/bin/sh/expand.sh: revision 1.4
bin/sh/sh.1: revision 1.86
bin/sh/arith_lex.l: revision 1.14
Make /bin/sh use intmax_t (instead of int) for arithmetic in $((...)).
 1.87.18.3 30-Jan-2010  snj Pull up following revision(s) (requested by dholland in ticket #1274):
bin/sh/sh.1: revision 1.97 via patch
Bump date for cd -P support.
 1.87.18.2 30-Jan-2010  snj Pull up following revision(s) (requested by dholland in ticket #1274):
bin/sh/cd.c: revision 1.40
bin/sh/sh.1: revision 1.95
Make the cd builtin accept and ignore -P, which is a kshism that has been
allowed to leak into POSIX and selects the behavior cd already implements.
Closes PR bin/42557 and also relevant to PR pkg/42168.
I suppose this should probably be pulled up to both -4 and -5...
 1.87.18.1 01-Apr-2009  snj branches: 1.87.18.1.4;
Pull up following revision(s) (requested by mrg in ticket #622):
bin/csh/csh.1: revision 1.46
bin/csh/func.c: revision 1.37
bin/ps/print.c: revision 1.111
bin/ps/ps.c: revision 1.74
bin/sh/miscbltin.c: revision 1.38
bin/sh/sh.1: revision 1.92 via patch
external/bsd/top/dist/machine/m_netbsd.c: revision 1.7
lib/libkvm/kvm_proc.c: revision 1.82
sys/arch/mips/mips/cpu_exec.c: revision 1.55
sys/compat/darwin/darwin_exec.c: revision 1.57
sys/compat/ibcs2/ibcs2_exec.c: revision 1.73
sys/compat/irix/irix_resource.c: revision 1.15
sys/compat/linux/arch/amd64/linux_exec_machdep.c: revision 1.16
sys/compat/linux/arch/i386/linux_exec_machdep.c: revision 1.12
sys/compat/linux/common/linux_limit.h: revision 1.5
sys/compat/osf1/osf1_resource.c: revision 1.14
sys/compat/svr4/svr4_resource.c: revision 1.18
sys/compat/svr4_32/svr4_32_resource.c: revision 1.17
sys/kern/exec_subr.c: revision 1.62
sys/kern/init_sysctl.c: revision 1.160
sys/kern/kern_exec.c: revision 1.288
sys/kern/kern_resource.c: revision 1.151
sys/sys/param.h: patch
sys/sys/resource.h: revision 1.31
sys/sys/sysctl.h: revision 1.184
sys/uvm/uvm_extern.h: revision 1.153
sys/uvm/uvm_glue.c: revision 1.136
sys/uvm/uvm_mmap.c: revision 1.128
usr.bin/systat/ps.c: revision 1.32
- - add new RLIMIT_AS (aka RLIMIT_VMEM) resource that limits the total
address space available to processes. this limit exists in most other
modern unix variants, and like most of them, our defaults are unlimited.
remove the old mmap / rlimit.datasize hack.
- - adds the VMCMD_STACK flag to all the stack-creation vmcmd callers.
it is currently unused, but was added a few years ago.
- - add a pair of new process size values to kinfo_proc2{}. one is the
total size of the process memory map, and the other is the total size
adjusted for unused stack space (since most processes have a lot of
this...)
- - patch sh, and csh to notice RLIMIT_AS. (in some cases, the alias
RLIMIT_VMEM was already present and used if availble.)
- - patch ps, top and systat to notice the new k_vm_vsize member of
kinfo_proc2{}.
- - update irix, svr4, svr4_32, linux and osf1 emulations to support
this information. (freebsd could be done, but that it's best left
as part of the full-update of compat/freebsd.)
this addresses PR 7897. it also gives correct memory usage values,
which have never been entirely correct (since mmap), and have been
very incorrect since jemalloc() was enabled.
tested on i386 and sparc64, build tested on several other platforms.
thanks to many folks for feedback and testing but most espcially
chuq and yamt for critical suggestions that lead to this patch not
having a special ugliness i wasn't happy with anyway :-)
 1.87.18.1.4.1 21-Apr-2010  matt sync to netbsd-5
 1.88.2.1 13-May-2009  jym Sync with HEAD.

Third (and last) commit. See http://mail-index.netbsd.org/source-changes/2009/05/13/msg221222.html
 1.99.4.1 23-Jun-2011  cherry Catchup with rmind-uvmplock merge.
 1.106.2.2 22-May-2014  yamt sync with head.

for a reference, the tree before this commit was tagged
as yamt-pagecache-tag8.

this commit was splitted into small chunks to avoid
a limitation of cvs. ("Protocol error: too many arguments")
 1.106.2.1 30-Oct-2012  yamt sync with head
 1.108.2.3 19-Aug-2014  tls Rebase to HEAD as of a few days ago.
 1.108.2.2 23-Jun-2013  tls resync from head
 1.108.2.1 20-Nov-2012  tls Resync to 2012-11-19 00:00:00 UTC
 1.112.2.1 10-Aug-2014  tls Rebase.
 1.123.4.1 21-Apr-2017  bouyer Sync with HEAD
 1.123.2.2 26-Apr-2017  pgoyette Sync with HEAD
 1.123.2.1 20-Mar-2017  pgoyette Sync with HEAD
 1.131.2.3 19-May-2017  pgoyette Resolve conflicts from previous merge (all resulting from $NetBSD
keywork expansion)
 1.131.2.2 11-May-2017  pgoyette Sync with HEAD
 1.131.2.1 02-May-2017  pgoyette Sync with HEAD - tag prg-localcount2-base1
 1.146.2.6 07-Dec-2018  martin Pull up following revision(s) (requested by kre in ticket #1127):

bin/sh/var.h: revision 1.38 (via patch)
bin/sh/var.c: revision 1.72
bin/sh/sh.1: revision 1.211 (via patch)

Alter a design botch when magic (self modifying) variables
were added to sh ... in other shells, setting such a variable
(for most of them) causes it to lose its special properties,
and act the same as any other variable. I had assumed that
was just implementor laziness... I was wrong.

From now on the NetBSD shell will act like the others, and if vars
like HOSTNAME (and SECONDS, etc) are used as variables in a script
or whatever, they will act just like normal variables (and unless
this happens when they have been made local, or as a variable-assignment
as a prefix to a command, the special properties they would have had
otherwise are lost for the remainder of the life of the (sub-)shell
in which the variables were set).

Importing a value from the environment counts as setting the
value for this purpose (so if HOSTNAME is set in the environment,
the value there will be the value $HOSTNAME expands to).
The two exceptions to this are LINENO and RANDOM. RANDOM
needs to be able to be set to (re-)set its seed. LINENO needs to
be able to be set (at least in the "local" command) to achieve
the desired functionality. It is unlikely that any (sane) script
is going to want to use those two as normal vars however.

While here, fix a minor bug in popping local vars (fn return) that need
to notify the shell of changes in value (like PATH).
Change sh(1) to reflect this alteration. Also add doc of the
(forgotten) magic var EUSER (which has been there since the others
were added), and add a few more vars (which are documented
in other places in sh(1) - like ENV) into the defined or used
variable list (as well as wherever else they appear).

XXX pullup -8
 1.146.2.5 25-Oct-2017  snj Pull up following revision(s) (requested by kre in ticket #323):
bin/sh/sh.1: revision 1.168
Fix typo: s/one or mode/one or more/
 1.146.2.4 25-Oct-2017  snj Pull up following revision(s) (requested by kre in ticket #310):
bin/sh/expand.c: revision 1.121
bin/sh/sh.1: revision 1.167 via patch
Three fixes and a change to ~ expansions
1. A serious bug introduced 3 1/2 months ago (approx) (rev 1.116) which
broke all but the simple cases of ~ expansions is fixed (amazingly,
given the magnitude of this problem, no-one noticed!)
2. An ancient bug (probably from when ~ expansion was first addedin 1994, and
certainly is in NetBSD-6 vintage shells) where ${UnSeT:-~} (and similar)
does not expand the ~ is fixed (note that ${UnSeT:-~/} does expand,
this should give a clue to the cause of the problem.
3. A fix/change to make the effects of ~ expansions on ${UnSeT:=whatever}
identical to those in UnSeT=whatever In particular, with HOME=/foo
${UnSeT:=~:~} now assigns, and expands to, /foo:/foo rather than ~:~
just as VAR=~:~ assigns /foo:/foo to VAR. Note this is even after the
previous fix (ie: appending a '/' would not change the results here.)
It is hard to call this one a bug fix for certain (though I believe it is)
as many other shells also produce different results for the ${V:=...}
expansions than they do for V=... (though not all the same as we did).
POSIX is not clear about this, expanding ~ after : in VAR=whatever
assignments is clear, whether ${U:=whatever} assignments should be
treated the same way is not stated, one way or the other.
4. Change to make ':' terminate the user name in a ~ expansion in all cases,
not only in assignments. This makes sense, as ':' is one character that
cannot occur in user names, no matter how otherwise weird they become.
bash (incl in posix mode) ksh93 and bosh all act this way, whereas most
other shells (and POSIX) do not. Because this is clearly an extension
to POSIX, do this one only when not in posix mode (not set -o posix).
 1.146.2.3 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.146.2.2 09-Jun-2017  snj Pull up following revision(s) (requested by kre in ticket #15):
bin/sh/sh.1: revision 1.148
Fix a typo (or rather a remnant of an earlier intent).
 1.146.2.1 05-Jun-2017  snj Pull up following revision(s) (requested by kre in ticket #5):
bin/sh/cd.c: revision 1.48
bin/sh/eval.c: revision 1.141
bin/sh/exec.c: revision 1.48
bin/sh/exec.h: revision 1.25
bin/sh/mail.c: revisions 1.17, 1.18
bin/sh/sh.1: revision 1.147
Make cd (really) do cd -P, and not just claim that is what it is doing
while doing a half-hearted, broken, partial, version of cd -L instead.
The latter (as the manual says) is not supported, what's more, it is an
abomination, and should never be supported (anywhere.)
Fix the doc so that the pretense that we notice when a path given crosses
a symlink (and turns on printing of the destination directory) is claimed
no more (that used to be true until late Dec 2016, but was changed). Now
the print happens if -o cdprint is set, or if an entry from CDPATH that is
not "" or "." is used (or if the "cd dest repl" cd cmd variant is used.)
Fix CDPATH processing: avoid the magic '%' processing that is used for
PATH and MAILPATH from corrupting CDPATH. The % magic (both variants)
remains undocumented.
Also, don't double the '/' if an entry in PATH or CDPATH ends in '/'
(as in CDPATH=":/usr/src/"). A "cd usr.bin" used to do
chdir("/usr/src//usr.bin"). No more. This is almost invisible,
and relatively harmless, either way....
Also fix a bug where if a plausible destination directory in CDPATH
was located, but the chdir() failed (eg: permission denied) and then
a later "." or "" CDPATH entry succeeded, "print" mode was turned on.
That is:
cd /tmp; mkdir bin
mkdir -p P/bin; chmod 0 P/bin
CDPATH=/tmp/P:
cd bin
would cd to /tmp/bin (correctly) but print it (incorrectly).
Also when in "cd dest replace" mode, if the result of the replacement
generates '-' as the path named, as in:
cd $PWD -
then simply change to '-' (or attempt to, with CDPATH search), rather
than having this being equivalent to "cd -")
Because of these changes, the pwd command (and $PWD) essentially
always acts as pwd -P, even when called as pwd -L (which is still
the default.) That is, even more than it did before.
Also fixed a (kind of minor) mem management error (CDPATH related)
"whosoever shall padvance must stunalloc before repeating" (and the
same for MAILPATH).
--
If we are going to keep the MAILPATH % hack, then at least do something
rational. Since it isn't documented, what "rational" is is up for
discussion, but what it did before was not it (it was nonsense...).
 1.175.2.7 26-Jan-2019  pgoyette Sync with HEAD
 1.175.2.6 26-Dec-2018  pgoyette Sync with HEAD, resolve a few conflicts
 1.175.2.5 26-Nov-2018  pgoyette Sync with HEAD, resolve a couple of conflicts
 1.175.2.4 06-Sep-2018  pgoyette Sync with HEAD

Resolve a couple of conflicts (result of the uimin/uimax changes)
 1.175.2.3 21-May-2018  pgoyette Sync with HEAD
 1.175.2.2 22-Mar-2018  pgoyette Synch with HEAD, resolve conflicts
 1.175.2.1 15-Mar-2018  pgoyette Synch with HEAD
 1.206.2.4 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.206.2.3 21-Apr-2020  martin Sync with HEAD
 1.206.2.2 08-Apr-2020  martin Merge changes from current as of 20200406
 1.206.2.1 10-Jun-2019  christos Sync with HEAD
 1.223.2.2 06-Nov-2021  martin Pull up following revision(s) (requested by kre in ticket #1372):

bin/sh/sh.1: revision 1.236 (patch)
bin/sh/cd.c: revision 1.51

PR bin/45390 - fix for folly four

In the pwd builtin, verify that curdir names '.' before
simply printing it. Never alter PWD or OLDPWD in the
pwd command.

Also while here, implement the (new: coming in POSIX, but has existed
for a while in several other shells) -e option to cd (with -e, cd -P
will exit(1) if the chdir() succeeds, but PWD cannot be discovered).
cd now prints the directory name used (if different from that given,
or cdprint is on) if interactive or (the new bit)in posix mode.

Some additional/changed comments added, and a DEBUG mode trace call
that was accidentally put inside an #if 0 block moved to where it
can do some good.

XXX pullup -9

PR bin/45390

Be explicit about what happens to PWD after a successful cd command.
Also be very clear that "cd" and "cd -P" are the same thing, and
the only cd variant implemented.
Also, when it is appropriate to print the new directory after a cd
command, note that it happens if interactive (as it always has here)
and also if the posix option is set (for POSIX compat, where "interactive"
is irrelevant). Mention that "cd -" is a case where the new directory
is printed (along with paths relative to a non-empty CDPATH entry,
and where the "cd old new" (string replacement in curdir) is used.

While here document the new -e option to cd.

XXX pullup -9
 1.223.2.1 06-Nov-2021  martin Pull up following revision(s) (requested by kre in ticket #1371):

bin/sh/main.c: revision 1.87
bin/sh/main.c: revision 1.88
bin/sh/memalloc.h: revision 1.20
bin/sh/sh.1: revision 1.235
bin/sh/memalloc.c: revision 1.34
bin/sh/memalloc.c: revision 1.35
bin/sh/memalloc.h: revision 1.19
bin/sh/shell.h: revision 1.31
bin/sh/options.c: revision 1.56

PR bin/56464

After almost 30 years, finally do the right thing and read $HOME/.profile
rather than .profile in the initial directory (it was that way in version
1.1 ...) All other ash descendants seem to have fixed this long ago.
While here, copy a feature from FreeBSD which allows "set +p" (if a
shell run by a setuid process with the -p flag is privileged) to reset
the privileges. Once done (the set +p) it cannot be undone (a later
set -p sets the 'p' flag, but that's all it does) - that just becomes a
one bit storage location.

We do this, as (also copying from FreeBSD, and because it is the right
thing to do) we don't run .profile in a privileged shell - FreeBSD run
/etc/suid_profile in that case (not a good name, it also applies to setgid
shells) but I see no real need for that, we run /etc/profile in any case,
anything that would go in /etc/suid_profile can just go in /etc/profile
instead (with suitable guards so the commands only run in priv'd shells).

One or two minor DEBUG mode changes (notably having priv'd shells identify
themselves in the DEBUG trace) and sh.1 changes with doc of the "set +p"
change, the effect that has on $PSc and a few other wording tweaks.

XXX pullup -9 (not -8, this isn't worth it for the short lifetime
that has left - if it took 28+ years for anyone to notice this, it
cannot be having all that much effect).

Use a type-correct end marker for strstrcat() rather than NULL, as
for a function with unknown number & types of args, the compiler isn't
able to automatically convert to the correct type. Issue pointed out
in off list e-mail by Rolland Illig ... Thanks.

The first arg (pointer to where to put length of result) is of a known
type, so doesn't have the same issue - we can keep using NULL for that
one when the length isn't needed.
Also, make sure to return a correctly null terminated null string in
the (absurd) case that there are no non-null args to strstrcat() (though
there are much better ways to generate "" on the stack). Since there is
currently just one call in the code, and it has real string args, this
isn't an issue for now, but who knows, some day.

NFCI - if there is any real change, then it is a change that is required.

XXX pullup -9 (together with the previous changes)
 1.252.2.1 20-Dec-2022  martin Pull up following revision(s) (requested by uwe in ticket #11):

bin/sh/sh.1: revision 1.253

sh(1): Fix markup. -compact must be last.
 1.260.2.1 02-Aug-2025  perseant Sync with HEAD
 1.34 27-Feb-2025  andvar Fix various typos in comments.
 1.33 09-Oct-2024  kre PR bin/58687 -- implement suspend as a builtin in sh

Requested by uwe@ in PR bin/58687 without objections from
anyone except me, here is an implementation of a suspend
builtin command for /bin/sh

The sh.1 man page is updated, naturally, to describe it.

This new builtin does not exist in SMALL shells -- as used
on (some) boot media, etc.

If this turns out not to be useful, it can easily be removed.
 1.32 09-Feb-2024  andvar branches: 1.32.2;
fix spelling mistakes, mainly in comments and log messages.
 1.31 26-Oct-2021  kre PR bin/56464

After almost 30 years, finally do the right thing and read $HOME/.profile
rather than .profile in the initial directory (it was that way in version
1.1 ...) All other ash descendants seem to have fixed this long ago.

While here, copy a feature from FreeBSD which allows "set +p" (if a
shell run by a setuid process with the -p flag is privileged) to reset
the privileges. Once done (the set +p) it cannot be undone (a later
set -p sets the 'p' flag, but that's all it does) - that just becomes a
one bit storage location.

We do this, as (also copying from FreeBSD, and because it is the right
thing to do) we don't run .profile in a privileged shell - FreeBSD run
/etc/suid_profile in that case (not a good name, it also applies to setgid
shells) but I see no real need for that, we run /etc/profile in any case,
anything that would go in /etc/suid_profile can just go in /etc/profile
instead (with suitable guards so the commands only run in priv'd shells).

One or two minor DEBUG mode changes (notably having priv'd shells identify
themselves in the DEBUG trace) and sh.1 changes with doc of the "set +p"
change, the effect that has on $PSc and a few other wording tweaks.

XXX pullup -9 (not -8, this isn't worth it for the short lifetime
that has left - if it took 28+ years for anyone to notice this, it
cannot be having all that much effect).
 1.30 10-Sep-2021  rillig bin: remove unnecessary lint comment CONSTCOND

Since 2021-01-31, lint no longer warns about 'do ... while (0)'.

No functional change.
 1.29 22-Jan-2019  kre branches: 1.29.2;

NFCI - DEBUG mode only change.

Add tracing of lexical analyser operations. This is deliberately
kept out of the normal "all on" set as it makes a *lot* of noise
when enabled (especially in verbose mode) - but when needed, it
helps (evidence for which is coming soon).

As usual, no doc, you need the sources (and of course, a specially
built sh to even be able to enable it.)
 1.28 21-Jan-2019  kre DEBUG mode shell cleanups (NFC for any normal shell).

Add an error DEBUG trace in exraise() (when the shell has detected
some error or signal, and is aborting what it is doing)

Fix an arith error in DEBUG bit assignments (harmless as we haven't
reached the limit of flags yet), and add some missing (recently added)
debug flags so they are turned on when the user (ie: me) asks for
"everything".
 1.27 18-Oct-2018  kre Delete the old style (no longer used) DEBUG mode TRACE compat macro
definitions (just to avoid any temptation to ever use them again).

Update a comment which would make no sense without following the
preceding comment which is being deleted with the macros it describes.

While here, remove another comment that referred to events that have
long past as if they were still to come. Also a grammatical comment
correction - paragraphs start with capital letters...

NFC (even with DEBUG defined).
 1.26 22-Jul-2018  kre DEBUG mode only change (ie: no effect to any normal shell).

Add tracing of pattern matching (aid in debugging various issues.)
 1.25 26-Jul-2017  kre branches: 1.25.2; 1.25.4;

NFC: DEBUG mode change - add a couple more TRACE macros to allow for
conditional (apart from the normal debug conditions) tracing.
 1.24 17-Jun-2017  kre NFC: DEBUG related comment change - catch up with reality.
 1.23 29-May-2017  kre branches: 1.23.2;

More DEBUG mode changes. As usual, read the source if you care.
 1.22 27-May-2017  kre More standard (and saner) implementation of the ! reserved word.
Unless the shell is compiled with the (compilation time) option
BOGUS_NOT_COMMAND (as in CFLAGS+=-DBOGUS_NOT_COMMAND) which it
will not normally be, the ! command (reserved word) will only
be permitted at the start of a pipeline (which includes the
degenerate pipeline with no '|'s in it of course - ie: a simple cmd)
and not in the middle of a pipeline sequence (no "cmd | ! cmd" nonsense.)
If the latter is really required, then "cmd | { ! cmd; }" works as
a standard equivalent.

In POSIX mode, permit only one ! ("! pipeline" is ok. "! ! pipeline" is not).
Again, if needed (and POSIX conformance is wanted) "! { ! pipeline; }"
works as an alternative - and is safer, some shells treat "! ! cmd" as
being identical to "cmd" (this one did until recently.)
 1.21 13-May-2017  kre The beginnings of the great shell DEBUG (tracing) upgrade of 2017...

First, be aware that the DEBUG spoken of here has nothing whatever to
do with MKDEBUG=true type builds of NetBSD. The only way to get a
DEBUG shell is to build it yourself manually.

That said, for non-DEBUG shells, this change makes only one slight
(trivial really) difference, which should affect nothing.

Previously some code was defined like ...

function(args)
{
#ifdef DEBUG
/* function code goes here */
#endif
}

and called like ...

#ifdef DEBUG
function(params);
#endif

resulting in several empty functions that are never called being
defined in non-DEBUG shells. Those are now gone. If you can detect
the difference any way other than using "nm" or similar, I'd be very
surprised...

For DEBUG shells, this introduces a whole new TRACE() setup to use
to assist in debugging the shell.

I have had this locally (uncommitted) for over a year... it helps.

By itself this change is almost useless, nothing really changes, but
it provides the framework to allow other TRACE() calls to be updated
over time. This is why I had not committed this earlier, my previous
version required a flag day, with all the shell's internal tracing
being updated a once - which I had done, but that shell version has
bit-rotted so badly now it is almost useless...

Future updates will add the mechanism to allow the new stuff to actually
be used in a productive way, and following that, over time, gradual
conversion of all the shell tracing to the updated form (as required,
or when I am bored...)

The one useful change that we do get now is that the fd that the shell
uses for tracing (which was usually 3, but not any more) is now protected
from user/script interference, like all the other shell inernal fds.

There is no doc (nor will there be) on any of this, if you are not reading
the source code it is useless to you, if you are, you know how it works.
 1.20 21-Mar-2017  joerg branches: 1.20.2;
Add includes guards since we can include the header twice and typedef
redefinitions are a C11 feature.
 1.19 03-May-2016  kre branches: 1.19.2; 1.19.4;

Fix things so that STATIC can me made static (-DSTATIC=static)
and have the shell still compile, link, and run...

ok christos@
 1.18 28-Apr-2013  dholland Add const.
 1.17 07-Aug-2003  agc branches: 1.17.54; 1.17.60;
Move UCB-licensed code from 4-clause to 3-clause licence.

Patches provided by Joel Baker in PR 22249, verified by myself.
 1.16 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.15 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.14 25-May-2002  wiz __STDC__ is always defined on NetBSD, so remove #ifdef __STDC__ (and
unnecessary #else cases).
 1.13 22-May-2000  elric branches: 1.13.6;
Back out previous vfork changes.
 1.12 13-May-2000  elric In order to use __NetBSD_Version__, I needed to include sys/param.h.
 1.11 13-May-2000  elric Now we use vfork(2) instead of fork(2) when we can.
 1.10 16-Oct-1996  christos PR/2808: Don't define DEBUG and #ifdef out functions not needed when DEBUG
is not defined (from FreeBSD).
 1.9 01-Mar-1996  jtc branches: 1.9.4;
Changed so that cd builtin doesn't do wierd stuff when cd'ing through
symlinks. From Chris Demetriou <cgd@NetBSD.ORG>. Fixes PR #1776.

Changed so that INTOFF/INTON are paired in getpwd(). From Matthias
Pfaller <leo@marco.de>. Fixes PR #2130.
 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.9.4.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.13.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.17.60.1 23-Jun-2013  tls resync from head
 1.17.54.1 22-May-2014  yamt sync with head.

for a reference, the tree before this commit was tagged
as yamt-pagecache-tag8.

this commit was splitted into small chunks to avoid
a limitation of cvs. ("Protocol error: too many arguments")
 1.19.4.1 21-Apr-2017  bouyer Sync with HEAD
 1.19.2.1 26-Apr-2017  pgoyette Sync with HEAD
 1.20.2.1 19-May-2017  pgoyette Resolve conflicts from previous merge (all resulting from $NetBSD
keywork expansion)
 1.23.2.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.25.4.3 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.25.4.2 21-Apr-2020  martin Sync with HEAD
 1.25.4.1 10-Jun-2019  christos Sync with HEAD
 1.25.2.3 26-Jan-2019  pgoyette Sync with HEAD
 1.25.2.2 20-Oct-2018  pgoyette Sync with head
 1.25.2.1 28-Jul-2018  pgoyette Sync with HEAD
 1.29.2.1 06-Nov-2021  martin Pull up following revision(s) (requested by kre in ticket #1371):

bin/sh/main.c: revision 1.87
bin/sh/main.c: revision 1.88
bin/sh/memalloc.h: revision 1.20
bin/sh/sh.1: revision 1.235
bin/sh/memalloc.c: revision 1.34
bin/sh/memalloc.c: revision 1.35
bin/sh/memalloc.h: revision 1.19
bin/sh/shell.h: revision 1.31
bin/sh/options.c: revision 1.56

PR bin/56464

After almost 30 years, finally do the right thing and read $HOME/.profile
rather than .profile in the initial directory (it was that way in version
1.1 ...) All other ash descendants seem to have fixed this long ago.
While here, copy a feature from FreeBSD which allows "set +p" (if a
shell run by a setuid process with the -p flag is privileged) to reset
the privileges. Once done (the set +p) it cannot be undone (a later
set -p sets the 'p' flag, but that's all it does) - that just becomes a
one bit storage location.

We do this, as (also copying from FreeBSD, and because it is the right
thing to do) we don't run .profile in a privileged shell - FreeBSD run
/etc/suid_profile in that case (not a good name, it also applies to setgid
shells) but I see no real need for that, we run /etc/profile in any case,
anything that would go in /etc/suid_profile can just go in /etc/profile
instead (with suitable guards so the commands only run in priv'd shells).

One or two minor DEBUG mode changes (notably having priv'd shells identify
themselves in the DEBUG trace) and sh.1 changes with doc of the "set +p"
change, the effect that has on $PSc and a few other wording tweaks.

XXX pullup -9 (not -8, this isn't worth it for the short lifetime
that has left - if it took 28+ years for anyone to notice this, it
cannot be having all that much effect).

Use a type-correct end marker for strstrcat() rather than NULL, as
for a function with unknown number & types of args, the compiler isn't
able to automatically convert to the correct type. Issue pointed out
in off list e-mail by Rolland Illig ... Thanks.

The first arg (pointer to where to put length of result) is of a known
type, so doesn't have the same issue - we can keep using NULL for that
one when the length isn't needed.
Also, make sure to return a correctly null terminated null string in
the (absurd) case that there are no non-null args to strstrcat() (though
there are much better ways to generate "" on the stack). Since there is
currently just one call in the code, and it has real string args, this
isn't an issue for now, but who knows, some day.

NFCI - if there is any real change, then it is a change that is required.

XXX pullup -9 (together with the previous changes)
 1.32.2.1 02-Aug-2025  perseant Sync with HEAD
 1.59 11-Nov-2024  kre This commit is intended to be what was intended to happen in the
commit of Sun Nov 10 01:22:24 UTC 2024, see:

http://mail-index.netbsd.org/source-changes/2024/11/10/msg154310.html

The commit message for that applies to this one (wholly). I believe that
the problem with that version which caused it to be reverted has been found
and fixed in this version (a necessary change was made as part of one of
the fixes, but the side-effect implications of that were missed -- bad bad me.)

In addition, I found some more issues with setting close-on-exec on other
command lines

With:
func 3>whatever

fd 3 (anything > 2) got close on exec set. That makes no difference
to the function itself (nothing gets exec'd therefore nothing gets closed)
but does to any exec that might happen running a command within the function.

I believe that if this is done (just as if "func" was a regular command,
and not a function) such open fds should be passed through to anything
they exec - unless the function (or other command) takes care to close the
fd passed to it, or explicitly turn on close-on exec.

I expect this usage to be quite rare, and not make much practical difference.

The same applies do builtin commands, but is even less relevant there, eg:

printf 3>whatever

would have set close-on-exec on fd 3 for printf. This is generally
completely immaterial, as printf - and most other built-in commands -
neither uses any fd other than (some of) 0 1 & 2, nor do they exec anything.

That is, except for the "exec" built-in which was the focus of the original
fix (mentioned above) and which should remain fixed here, and for the "."
command.

Because of that last one (".") close-on-exec should not be set on built-in
commands (any of them) for redirections on the command line. This will
almost never make a difference - any such redirections last only as long
as the built-in command lasts (same with functions) and so will generally
never care about the state of close-on-exec, and I have never seen a use
of the "." command with any redirections other than stderr (which is unaffected
here, fd's <= 2 never get close-on-exec set). That's probably why no-one
ever noticed.

There are still "fd issues" when running a (non #!) shell script, that
are hard to fix, which we should probably handle the way most other shells
have, by simply abandoning the optimisation of not exec'ing a whole new
shell (#! scripts do that exec) and just doing it that way. Issues solved!
One day.
 1.58 10-Nov-2024  kre Revert the recent change until I can work out how things are broken.
 1.57 10-Nov-2024  kre exec builtin command redirection fixes

Several changes, all related to the exec special built in command,
or to close on exec, one way or another. (Except a few white space
and comment additions, KNF, etc)

1. The bug found by Edgar Fuß reported in:
http://mail-index.netbsd.org/tech-userlevel/2024/11/05/msg014588.html
has been fixed, now "exec N>whatever" will set close-on-exec for fd N
(as do ksh versions, and allowed by POSIX, though other shells do not)
which has happened now for many years. But "exec cmd N>whatever"
(which looks like the same command when redirections are processed)
which was setting close-on-exec on N, now no longer does, so fd N
can be passed to cmd as an open fd.

For anyone who cares, the big block of change just after "case CMDBUILTIN:"
in evalcommand() in eval.c is the fix for this (one line replaced by
about 90 ... though most of that is comments or #if 0'd example code
for later). It is a bit ugly, and will get worse if our exec command
ever gets any options, as others have, but it does work.

2. when the exec builtin utility is used to alter the shell's redirections
it is now "all or nothing". Previously the redirections were executed
left to right. If one failed, no more were attempted, but the earlier
ones remained. This makes no practical difference to a non-interactive
shell, as a redirection error causes that shell to exit, but it makes
a difference to interactive shells. Now if a redirection fails, any
earlier ones which had been performed are undone. Note however that
side-effects of redirections (like creating, or truncating, files in
the filesystem, cannot be reversed - just the shell's file descriptors
returned to how they were before the error).

Similarly usage errors on exec now exist .. our exec takes no options
(but does handle "--" as POSIX says it must - has done for ages).
Until now, that was the only magic piece of exec, running
exec -a name somecommand
(which several other shells support) would attempt to exec the "-a"
command, and most likely fail, causing immediate exit from the shell.
Now that is a usage error - a non-interactive shell still exits, as
exec is a special builtin, and any error from a special builtin causes
a non-interactive shell to exit. But now, an interactive shell will
no longer exit (and any redirections that were on the command will be
undone, the same as for a redirection error).

3. When a "close on exec" file descriptor is temporarily saved, so the
same fd can be redirected for another command (only built-in commands
and functions matter, redirects for file system commands happen after
a fork() and at that stage if anything goes wrong, the child simply
exits - but for non-forking commands, doing something like printf >file
required the previous stdout to be saved elsewhere, "file" opened to
be the new stdout, then when printf is finished, the old stdout moved
back. Anyway, if the fd being moved had close on exec set, then
when it was moved back, the close on exec was lost. That is now fixed.

4. The fdflags command no longer allows setting close on exec on stdin,
stdout, or stderr - POSIX requires that those 3 fd's always be open
(to something) when any normal command is invoked. With close-on-exec
set on one of these, that is impossible, so simply refuse it (when
"exec N>file" sets close on exec, it only does it for N>2).

Minor changes (should be invisible)

a. The shell now keeps track of the highest fd number it sees doing
normal operations (there are a few internal pipe() calls that aren't
monitored and a couple of others, but in general the shell will now
know the highest fd it ever saw allocated to it). This is mostly
for debugging.

b. calls to fcntl() passing an int as the "arg" are now all properly
cast to the void * that the fcntl kernel is expecting to receive.
I suspect that makes no actual difference to anything, but ...
 1.56 12-Jul-2024  kre Meaningless gcc inspired change.

This is in code only compiled in DEBUG builds (so not part of any
normal NetBSD build).

NFC
 1.55 07-Apr-2023  kre branches: 1.55.2;

The great shell trailing whitespace cleanup of 2023...
Inspired by private e-mail comments from mouse@

NFCI.
 1.54 10-Sep-2021  rillig bin: remove unnecessary lint comment CONSTCOND

Since 2021-01-31, lint no longer warns about 'do ... while (0)'.

No functional change.
 1.53 14-Feb-2019  kre DEBUG mode only change. When pretty-printing a word from a parse
tree, don't display a CTLESC which is there only to protect a CTL*
char (a data char that happens to have the same value). No actual
CTL* chars are printed as data, so no escaping is needed to protect
data which just happens to look the same. Dropping this avoids the
possibility of confusion/ambiguity in what the word actually contains.

NFC for any normal shell build (very little of this file gets compiled there)
 1.52 22-Jan-2019  kre NFCI - DEBUG mode only change.

Add tracing of lexical analyser operations. This is deliberately
kept out of the normal "all on" set as it makes a *lot* of noise
when enabled (especially in verbose mode) - but when needed, it
helps (evidence for which is coming soon).

As usual, no doc, you need the sources (and of course, a specially
built sh to even be able to enable it.)
 1.51 21-Jan-2019  kre DEBUG mode shell cleanups (NFC for any normal shell).

Add an error DEBUG trace in exraise() (when the shell has detected
some error or signal, and is aborting what it is doing)

Fix an arith error in DEBUG bit assignments (harmless as we haven't
reached the limit of flags yet), and add some missing (recently added)
debug flags so they are turned on when the user (ie: me) asks for
"everything".
 1.50 18-Oct-2018  kre Remove a DEBUG mode transition mechanism (for the transition from
the ancient DEBUG TRACE() method, to the newer CTRACE() et. al.)
that turns out never really needed committing - the mechanism, and
the code that obsoleted it, were committed together (May 2017).
[It was useful to me while getting to that state...]

NFC. Not even with DEBUG shells.
 1.49 19-Aug-2018  kre NFC: DEBUG mode only change. When tracing, show >&- as ">&-"
rather than ">&-1" (the same op as >&n where internally n < 0
means "close")
 1.48 22-Jul-2018  kre DEBUG mode only change (ie: no effect to any normal shell).

Add tracing of pattern matching (aid in debugging various issues.)
 1.47 30-Jun-2017  kre branches: 1.47.4; 1.47.6;

NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
 1.46 17-Jun-2017  kre NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
 1.45 17-Jun-2017  kre NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
 1.44 08-Jun-2017  kre Correct spelling in comments of DEBUG only code...
 1.43 07-Jun-2017  kre A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)

This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)

The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.

This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).

I would not call the results of this perfect yet, but it is close.
 1.42 29-May-2017  kre branches: 1.42.2;

More DEBUG mode changes. As usual, read the source if you care.
 1.41 18-May-2017  kre DEBUG mode only change - mostly to output when option to show shell
internal sub-process nesting is enabled, and very deep nesting levels exist.

NFC for anyone else.
 1.40 15-May-2017  kre DEBUG mode shell update (changes nothing for shells which are not
compiled for DEBUG.)

Add debug builtin command, and corresponding -D command line option.
As usual, for DEBUG related stuff, read the source for info, that's
all there is about this.

This completes the infrastructure changes for the updated DEBUG TRACE
mechanism, so now converting the rest of the shell's internal tracing
can happen as desired - piecemeal.
 1.39 13-May-2017  kre The beginnings of the great shell DEBUG (tracing) upgrade of 2017...

First, be aware that the DEBUG spoken of here has nothing whatever to
do with MKDEBUG=true type builds of NetBSD. The only way to get a
DEBUG shell is to build it yourself manually.

That said, for non-DEBUG shells, this change makes only one slight
(trivial really) difference, which should affect nothing.

Previously some code was defined like ...

function(args)
{
#ifdef DEBUG
/* function code goes here */
#endif
}

and called like ...

#ifdef DEBUG
function(params);
#endif

resulting in several empty functions that are never called being
defined in non-DEBUG shells. Those are now gone. If you can detect
the difference any way other than using "nm" or similar, I'd be very
surprised...

For DEBUG shells, this introduces a whole new TRACE() setup to use
to assist in debugging the shell.

I have had this locally (uncommitted) for over a year... it helps.

By itself this change is almost useless, nothing really changes, but
it provides the framework to allow other TRACE() calls to be updated
over time. This is why I had not committed this earlier, my previous
version required a flag day, with all the shell's internal tracing
being updated a once - which I had done, but that shell version has
bit-rotted so badly now it is almost useless...

Future updates will add the mechanism to allow the new stuff to actually
be used in a productive way, and following that, over time, gradual
conversion of all the shell tracing to the updated form (as required,
or when I am bored...)

The one useful change that we do get now is that the fd that the shell
uses for tracing (which was usually 3, but not any more) is now protected
from user/script interference, like all the other shell inernal fds.

There is no doc (nor will there be) on any of this, if you are not reading
the source code it is useless to you, if you are, you know how it works.
 1.38 09-May-2017  kre If we are going to permit
! ! pipeline
(And for now the other places where ! is permitted)
we should at least generate the logically correct exit
status:
! ! (exit 5); echo $?
should print 1, not 5. ksh and bosh do it this way - and it makes sense.
bash and the FreeBSD sh echo "5" (as did we until now.)
dash, zsh, yash all enforce the standard syntax, and prohibit this.
 1.37 03-May-2017  kre This change affects shells compiled in DEBUG mode only, for normal
shells (anything made by build.sh) there is no change at all.

In DEBUG shells, when tree dumping, remember to include NNOT (same
omission as was just corrected in jobs.c :1.81) - of course, here there
are lots of other node types not handled as well.

ALso, avoid a core dump bug when doing a tree dump of a pieline
where the commands are not all simple commands (which can only
happen with a command string like " cmd | ! cmd | ... ". The "!"
in the middle is utter nonsense, and should be forbidden, but
for now, at least avoid a core dump.
 1.36 16-Mar-2017  kre branches: 1.36.2;

Undo local changes not intended to be committed (and certainly not
with that commit message) in the previous update. This stuff works,
and will probably appear sometime, but not right now.
 1.35 16-Mar-2017  kre Have "make clean" remove sh.html1 and adapt it to clean trace files
the way they have been generated the past 20 years or so...
 1.34 23-Oct-2016  abhinav branches: 1.34.2;
Remove unused variables.
Fixes the sh(1) build when DEBUG is enabled.
 1.33 11-May-2016  kre branches: 1.33.2;

It was twenty(-two) years ago today
J.T. Conklin told us not this way
Berkeley 4.4 lite's changed which file
And it's traced differently all this while
 1.32 29-Feb-2016  christos Even more debugging improvements (from kre)
 1.31 28-Feb-2016  christos Bug fixes to handling of unterminated here documents
(they should be, and now are, a syntax error), and
miscellaneous other minor cleanups. (from kre)
 1.30 27-Feb-2016  christos More nodenames fixes.
 1.29 27-Feb-2016  christos Improve debugging, from kre (I hooked it to the build).
 1.28 23-Aug-2011  christos - add pid to the trace file so that we don't keep overwriting ourselves
- use va_copy to print the trace arguments so that we don't deplete it for the real printf
 1.27 14-Nov-2010  christos don't core-dump if we cannot open the trace file.
 1.26 14-Nov-2003  dsl This seems to need stdlib.h to get a prototype for abort().
 1.25 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.24 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.23 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.22 25-May-2002  wiz __STDC__ is always defined on NetBSD, so remove #ifdef __STDC__ (and
unnecessary #else cases).
 1.21 15-May-2002  christos implement noclobber. From Ben Harris, with minor tweaks from me. Two
unimplemented comments to go. Go Ben!
 1.20 12-Feb-2002  ross back this directory up a day, systems won't even boot (rc.subr splodes)

suggested back-to-the-drawing-board test: $ echo "${PWD:-notlikely}"
 1.19 11-Feb-2002  christos Fix off by one in the display of var trees.
 1.18 08-Oct-1999  pk Sprinkle some `const's in DEBUG bracketed code.
 1.17 04-Feb-1999  christos branches: 1.17.4;
PR/4966: Joel Reicher: Implement <> redirections which are documented in
the man page.
 1.16 01-Dec-1997  christos Remove local declaration of getenv();
 1.15 04-Jul-1997  christos branches: 1.15.2;
Fix compiler warnings.
 1.14 11-Apr-1997  christos Use #ifdef __STDC__ instead of #if __STDC__
 1.13 11-Jan-1997  tls kill 'register'
 1.12 16-Oct-1996  christos PR/2808: Don't define DEBUG and #ifdef out functions not needed when DEBUG
is not defined (from FreeBSD).
 1.11 11-May-1995  christos branches: 1.11.6;
Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.10 21-Mar-1995  cgd convert to new RCS id conventions.
 1.9 23-Jan-1995  christos I added the documented in the manual but not implemented variable expansions:

${#WORD}
${WORD%PAT}
${WORD%%PAT}
${WORD#PAT}
${WORD##PAT}
 1.8 05-Dec-1994  cgd clean up further. more patches from Jim Jegers
 1.7 04-Dec-1994  cgd from James Jegers <jimj@miller.cs.uwm.edu>: quiet -Wall, and squelch
some of the worst style errors.
 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.11.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.15.2.1 08-May-1998  mycroft Sync with trunk, per request of christos.
 1.17.4.1 27-Dec-1999  wrstuden Pull up to last week's -current.
 1.33.2.2 20-Mar-2017  pgoyette Sync with HEAD
 1.33.2.1 04-Nov-2016  pgoyette Sync with HEAD
 1.34.2.1 21-Apr-2017  bouyer Sync with HEAD
 1.36.2.2 19-May-2017  pgoyette Resolve conflicts from previous merge (all resulting from $NetBSD
keywork expansion)
 1.36.2.1 11-May-2017  pgoyette Sync with HEAD
 1.42.2.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.47.6.3 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.47.6.2 21-Apr-2020  martin Sync with HEAD
 1.47.6.1 10-Jun-2019  christos Sync with HEAD
 1.47.4.4 26-Jan-2019  pgoyette Sync with HEAD
 1.47.4.3 20-Oct-2018  pgoyette Sync with head
 1.47.4.2 06-Sep-2018  pgoyette Sync with HEAD

Resolve a couple of conflicts (result of the uimin/uimax changes)
 1.47.4.1 28-Jul-2018  pgoyette Sync with HEAD
 1.55.2.1 02-Aug-2025  perseant Sync with HEAD
 1.11 30-Jun-2017  kre branches: 1.11.6;

NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
 1.10 13-May-2017  kre branches: 1.10.2;

The beginnings of the great shell DEBUG (tracing) upgrade of 2017...

First, be aware that the DEBUG spoken of here has nothing whatever to
do with MKDEBUG=true type builds of NetBSD. The only way to get a
DEBUG shell is to build it yourself manually.

That said, for non-DEBUG shells, this change makes only one slight
(trivial really) difference, which should affect nothing.

Previously some code was defined like ...

function(args)
{
#ifdef DEBUG
/* function code goes here */
#endif
}

and called like ...

#ifdef DEBUG
function(params);
#endif

resulting in several empty functions that are never called being
defined in non-DEBUG shells. Those are now gone. If you can detect
the difference any way other than using "nm" or similar, I'd be very
surprised...

For DEBUG shells, this introduces a whole new TRACE() setup to use
to assist in debugging the shell.

I have had this locally (uncommitted) for over a year... it helps.

By itself this change is almost useless, nothing really changes, but
it provides the framework to allow other TRACE() calls to be updated
over time. This is why I had not committed this earlier, my previous
version required a flag day, with all the shell's internal tracing
being updated a once - which I had done, but that shell version has
bit-rotted so badly now it is almost useless...

Future updates will add the mechanism to allow the new stuff to actually
be used in a productive way, and following that, over time, gradual
conversion of all the shell tracing to the updated form (as required,
or when I am bored...)

The one useful change that we do get now is that the fd that the shell
uses for tracing (which was usually 3, but not any more) is now protected
from user/script interference, like all the other shell inernal fds.

There is no doc (nor will there be) on any of this, if you are not reading
the source code it is useless to you, if you are, you know how it works.
 1.9 16-Mar-2017  kre branches: 1.9.2;

Undo local changes not intended to be committed (and certainly not
with that commit message) in the previous update. This stuff works,
and will probably appear sometime, but not right now.
 1.8 16-Mar-2017  kre Have "make clean" remove sh.html1 and adapt it to clean trace files
the way they have been generated the past 20 years or so...
 1.7 07-Aug-2003  agc branches: 1.7.80; 1.7.84;
Move UCB-licensed code from 4-clause to 3-clause licence.

Patches provided by Joel Baker in PR 22249, verified by myself.
 1.6 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.5 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.4 08-Oct-1999  pk Sprinkle some `const's in DEBUG bracketed code.
 1.3 11-Apr-1997  christos branches: 1.3.6;
add forward declaration of union node;
 1.2 16-Oct-1996  christos PR/2808: Don't define DEBUG and #ifdef out functions not needed when DEBUG
is not defined (from FreeBSD).
 1.1 11-May-1995  christos branches: 1.1.6;
Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.1.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.3.6.1 27-Dec-1999  wrstuden Pull up to last week's -current.
 1.7.84.1 21-Apr-2017  bouyer Sync with HEAD
 1.7.80.1 20-Mar-2017  pgoyette Sync with HEAD
 1.9.2.1 19-May-2017  pgoyette Resolve conflicts from previous merge (all resulting from $NetBSD
keywork expansion)
 1.10.2.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.11.6.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.11.6.1 21-Apr-2020  martin Sync with HEAD
 1.8 04-Feb-2019  kre Add a couple of comments. NFC.
 1.7 03-Dec-2018  kre Revamp aliases - as dumb an idea as they are, if we're going
to have them, they should work as documented, not cause core
dumps, reference after free, incorrect replacements, failing
to implement alias after alias, ...

The big comment that ended:
This is a good idea ------- ***NOT***
and the hack it was describing are gone.

Note that most of this was from original CVS version 1.1
code (ie: came from the original import, even before 4.4-Lite
was merged. That is, May 1994. And no-one in 24.5 years
noticed (or at least complained about) all the bugs (or at
least, most of them)).

With these changes, aliases ought to work (if you can call it
that) as they are expected to by POSIX. Now if only we could
get POSIX to delete them (or make them optional)...

Changes partly inspired by similar changes made by FreeBSD,
(as was the previous change to alias.c, forgot ack in commit
log for that one, apologies) but done a little differently,
and perhaps with a slightly better outcome.
 1.6 20-Jul-2018  kre First pass at fixing some of the more arcane pattern matching
possibilities that we do not currently handle all that well.

This mostly means (for now) making sure that quoted pattern
magic characters (as well as quoted sh syntax magic chars)
are properly marked, so they remain known as being quoted,
and do not turn into pattern magic. Also, make sure that an
unquoted \ in a pattern always quotes whatever comes next
(which, unlike in regular expressions, includes inside []
matches),
 1.5 21-Aug-2017  kre branches: 1.5.2; 1.5.4;
Add support for $'...' quoting (based upon C "..." strings, with \ expansions.)

Implementation largely obtained from FreeBSD, with adaptations to meet the
needs and style of this sh, some updates to agree with the current POSIX spec,
and a few other minor changes.

The POSIX spec for this ( http://austingroupbugs.net/view.php?id=249 )
[see note 2809 for the current proposed text] is yet to be approved,
so might change. It currently leaves several aspects as unspecified,
this implementation handles those as:

Where more than 2 hex digits follow \x this implementation processes the
first two as hex, the following characters are processed as if the \x
sequence was not present. The value obtained from a \nnn octal sequence
is truncated to the low 8 bits (if a bigger value is written, eg: \456.)
Invalid escape sequences are errors. Invalid \u (or \U) code points are
errors if known to be invalid, otherwise can generate a '?' character.
Where any escape sequence generates nul ('\0') that char, and the rest of
the $'...' string is discarded, but anything remaining in the word is
processed, ie: aaa$'bbb\0ccc'ddd produces the same as aaa'bbb'ddd.

Differences from FreeBSD:
FreeBSD allows only exactly 4 or 8 hex digits for \u and \U (as does C,
but the current sh proposal differs.) reeBSD also continues consuming
as many hex digits as exist after \x (permitted by the spec, but insane),
and reject \u0000 as invalid). Some of this is possibly because that
their implementation is based upon an earlier proposal, perhaps note 590 -
though that has been updated several times.

Differences from the current POSIX proposal:
We currently always generate UTF-8 for the \u & \U escapes. We should
generate the equivalent character from the current locale's character set
(and UTF8 only if that is what the current locale uses.)
If anyone would like to correct that, go ahead.

We (and FreeBSD) generate (X & 0x1F) for \cX escapes where we should generate
the appropriate control character (SOH for \cA for example) with whatever
value that has in the current character set. Apart from EBCDIC, which
we do not support, I've never seen a case where they differ, so ...
 1.4 07-Jun-2017  kre A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)

This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)

The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.

This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).

I would not call the results of this perfect yet, but it is close.
 1.3 28-Mar-2012  christos branches: 1.3.26;
include <limits.h> for CHAR_MIN/CHAR_MAX
 1.2 12-Dec-2007  lukem branches: 1.2.26;
use __RCSID()
 1.1 17-Jan-2004  dsl branches: 1.1.22;
Put a syntax.c under CVS instead of building if with the mksyntax program.
Kill mksyntax.c - no longer possible to get the 'wrong sort of chars'.
/bin/sh now has no helper binaries.
syntax.c uses C99 initialisers, run time initialisation could be used
for systems where the compiler doesn't support them.
I've used some #defines to help make this possible - but writing the code
starts making it rather messy.
 1.1.22.1 09-Jan-2008  matt sync with HEAD
 1.2.26.1 17-Apr-2012  yamt sync with head
 1.3.26.2 10-Sep-2018  martin Pull up following revision(s) via patch (requested by kre in ticket #1015):

bin/sh/expand.c: revision 1.124
bin/sh/expand.c: revision 1.127
bin/sh/parser.c: revision 1.148
bin/sh/parser.c: revision 1.149
bin/sh/syntax.c: revision 1.6
bin/sh/syntax.h: revision 1.9 (partial)

First pass at fixing some of the more arcane pattern matching
possibilities that we do not currently handle all that well.

This mostly means (for now) making sure that quoted pattern
magic characters (as well as quoted sh syntax magic chars)
are properly marked, so they remain known as being quoted,
and do not turn into pattern magic. Also, make sure that an
unquoted \ in a pattern always quotes whatever comes next
(which, unlike in regular expressions, includes inside []
matches),

-

Part 2 of pattern matching (glob etc) fixes.
Attempt to correctly deal with \ (both when it is a literal,
in appropriate cases, and when it appears as CTLESC when it was
detected as a quoting character during parsing).

In a pattern, in sh, no quoted character can ever be anything other
than a literal character. This is quite different than regular
expressions, and even different than other uses of glob matching,
where shell quoting is not an issue.

In something like
ls ?\*.c
the ? is a meta-character, the * is a literal (it was quoted). This
is nothing new, sh has handled that properly for ever.

But the same happens with
VAR='?\*.c'
and
ls $VAR
which has not always been handled correctly. Of course, in
ls "$VAR"
nothing in VAR is a meta-character (the entire expansion is quoted)
so even the '\' must match literally (or more accurately, no matching
happens - VAR simply contains an "unusual" filename). But if it had
been
ls *"$VAR"
then we would be looking for filenames that end with the literal 5
characters that make up $VAR.

The same kinds of things are requires of matching patterns in case
statements, and sub-strings with the % and # operators in variable
expansions.

While here, the final remnant of the ancient !! pattern matching
hack has been removed (the code that actually implemented it was
long gone, but one small piece remained, not doing any real harm,
but potentially wasting time - if someone gave a pattern which would
once have invoked that hack.)
 1.3.26.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.5.4.3 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.5.4.2 21-Apr-2020  martin Sync with HEAD
 1.5.4.1 10-Jun-2019  christos Sync with HEAD
 1.5.2.2 26-Dec-2018  pgoyette Sync with HEAD, resolve a few conflicts
 1.5.2.1 28-Jul-2018  pgoyette Sync with HEAD
 1.14 03-Jul-2025  kre We have our own CEOF, do not want the one from <sys/ttydefaults.h>

Fix the builds...
 1.13 15-Jun-2024  kre branches: 1.13.2;

This file uses CHAR_MIN so needs <limits.h> to be complete.

While here, fix a typo in the alternate (as in #if 0'd out) version
of the ISCTL() macro.

NFCI.
 1.12 27-Feb-2019  kre Finish the fixes from Feb 4 for handling of random data that
matches the internal CTL* chars.

The earlier fixes handled CTL* char values in var expansions,
but not in various other places they can occur (positional
parameters, $@ $* -- even potentially $0 and ~ expansions,
as well as byte strings generated from a \u in a $'' string).

These should all be correctly handled now. There is a new
ISCTL() macro to make the test, rather than using the old
BASESYNTAX[c]==CCTL form (which us still a viable alternative)
as the new way allows compiler optimisations, and less mem
references, so it should be smaller and faster.

Also, be sure in all cases to remove any CTLESC (or other)
CTL* chars from all strings before they are made available
for any external use (there was one case missed - which didn't
matter when we weren't bothering to escape the CTL* chars at
all.)

XXX pullup-8 (will need to be via a patch) along with the Feb 4 fixes.
 1.11 03-Dec-2018  kre Revamp aliases - as dumb an idea as they are, if we're going
to have them, they should work as documented, not cause core
dumps, reference after free, incorrect replacements, failing
to implement alias after alias, ...

The big comment that ended:
This is a good idea ------- ***NOT***
and the hack it was describing are gone.

Note that most of this was from original CVS version 1.1
code (ie: came from the original import, even before 4.4-Lite
was merged. That is, May 1994. And no-one in 24.5 years
noticed (or at least complained about) all the bugs (or at
least, most of them)).

With these changes, aliases ought to work (if you can call it
that) as they are expected to by POSIX. Now if only we could
get POSIX to delete them (or make them optional)...

Changes partly inspired by similar changes made by FreeBSD,
(as was the previous change to alias.c, forgot ack in commit
log for that one, apologies) but done a little differently,
and perhaps with a slightly better outcome.
 1.10 18-Nov-2018  kre Rationalise (slightly) the way that expansions are processed
to hide meta-characters in the result when the expansion was
in (double) quotes, and so should not be further processed.

Most of this has been OK for a long while, but \ needs hiding
as well, which complicates things, as \ cannot simply be hidden
in the syntax tables as one of the group of random special characters.

This was fixed earlier for simple variable expansions, but
every variety has its own code path ($var uses different code
than $n which is different than $(...), which is different
again from ~ expansions, and also from what $'...' produces).

This could be fixed by moving them all to a common code path,
but that's harder than it seems. The form in which the data
is made available differs, so one common routine would need
a whole bunch of different "get the next char or indicate end"
methods - probably via passing in an accessor function.
That's all a lot of churn, and would probably slow the shell.

Instead, just make macros for doing the standard tests, and
use those instead of open coding (differently) each time.
This way some of the code paths don't end up forgetting to
handle '\' (which is different than all the others).

This removes one optimisation ... when no escaping is needed
(like just $var (unquoted) where magic chars (think '*') in
the value are intended to remain magic), the code avoided doing
two tests for each char ("do we need escapes" and "is this char
one that needs escaping") by choosing two different syntax
tables (choice made outside the loop) - one of which never
returns the magic "needs escaping" result, and the other does
when appropriate, and then just avoiding the "do we need escapes"
test for each character processed. Then when '\' was fixed,
there needed to be another test for it, as it cannot (for other
reasons) be the same as all the others for which "this char
need escaping" is true. So that added a 2nd test for each char...
Not all the code paths were updated. Hence the bugs...

nb: this is all rarely seen in the wild, so it is no big
surprised that no-one ever noticed.

Now the "use two different syntax tables" is gone (the two
returned the same for '\' which is why '\' needed special
processing) - and in order to avoid two tests for each
char (plus the \ test) we duplicate the loops, one of which
tests each char to see if it needs an escape, the 2nd just
copies them. This should be faster in the "no escapes"
code path (though that is not the point) and perhaps also
in the "escapes needed" path (no indirect reference to
the syntax table - though that would probably be in a
register) but makes the code slightly bigger. For /bin/sh
the text segment (on amd64) has grown by 48 bytes. But
it still uses the same number of 512 byte pages (and hence
also any bigger page size). The resulting file size
(/bin/sh) is identical before and after. So is /rescue/sh
(or /rescue/anything-else).
 1.9 21-Aug-2017  kre branches: 1.9.2; 1.9.4;
Add support for $'...' quoting (based upon C "..." strings, with \ expansions.)

Implementation largely obtained from FreeBSD, with adaptations to meet the
needs and style of this sh, some updates to agree with the current POSIX spec,
and a few other minor changes.

The POSIX spec for this ( http://austingroupbugs.net/view.php?id=249 )
[see note 2809 for the current proposed text] is yet to be approved,
so might change. It currently leaves several aspects as unspecified,
this implementation handles those as:

Where more than 2 hex digits follow \x this implementation processes the
first two as hex, the following characters are processed as if the \x
sequence was not present. The value obtained from a \nnn octal sequence
is truncated to the low 8 bits (if a bigger value is written, eg: \456.)
Invalid escape sequences are errors. Invalid \u (or \U) code points are
errors if known to be invalid, otherwise can generate a '?' character.
Where any escape sequence generates nul ('\0') that char, and the rest of
the $'...' string is discarded, but anything remaining in the word is
processed, ie: aaa$'bbb\0ccc'ddd produces the same as aaa'bbb'ddd.

Differences from FreeBSD:
FreeBSD allows only exactly 4 or 8 hex digits for \u and \U (as does C,
but the current sh proposal differs.) reeBSD also continues consuming
as many hex digits as exist after \x (permitted by the spec, but insane),
and reject \u0000 as invalid). Some of this is possibly because that
their implementation is based upon an earlier proposal, perhaps note 590 -
though that has been updated several times.

Differences from the current POSIX proposal:
We currently always generate UTF-8 for the \u & \U escapes. We should
generate the equivalent character from the current locale's character set
(and UTF8 only if that is what the current locale uses.)
If anyone would like to correct that, go ahead.

We (and FreeBSD) generate (X & 0x1F) for \cX escapes where we should generate
the appropriate control character (SOH for \cA for example) with whatever
value that has in the current character set. Apart from EBCDIC, which
we do not support, I've never seen a case where they differ, so ...
 1.8 07-Jun-2017  kre A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)

This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)

The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.

This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).

I would not call the results of this perfect yet, but it is close.
 1.7 15-May-2017  kre branches: 1.7.2;

DEBUG mode shell update (changes nothing for shells which are not
compiled for DEBUG.)

Add debug builtin command, and corresponding -D command line option.
As usual, for DEBUG related stuff, read the source for info, that's
all there is about this.

This completes the infrastructure changes for the updated DEBUG TRACE
mechanism, so now converting the rest of the shell's internal tracing
can happen as desired - piecemeal.
 1.6 16-Mar-2016  christos branches: 1.6.6;
parenthesize for safety.
 1.5 16-Mar-2016  christos Remove wrong unsigned cast, index can be negative. Cast char to int so that
gcc does not warn. Probably better to do the offset at runtime, but that
would cost more.
 1.4 16-Mar-2016  christos factor out common code in macro.
 1.3 16-Mar-2016  christos Revert (kind of) the change in 1.12 of the ancient mksyntax.sh script
(undoing the effect of that commit on syntax.h when it was
being dynamically generated) from 1996. This means that the shell
parser is now locale independent, so scripts that work anywhere will
work consistently everywhere. Inspired by a similar change in
FreeBSD's sh (from 2010) - the original change in the other direction
came from FreeBSD as well.... Note that this does not in any way
add any kind of support for locales to sh (which is a whole different
problem.) (from kre)
 1.2 17-Jan-2004  dsl Put a syntax.c under CVS instead of building if with the mksyntax program.
Kill mksyntax.c - no longer possible to get the 'wrong sort of chars'.
/bin/sh now has no helper binaries.
syntax.c uses C99 initialisers, run time initialisation could be used
for systems where the compiler doesn't support them.
I've used some #defines to help make this possible - but writing the code
starts making it rather messy.
 1.1 17-Jan-2004  dsl Put syntax.h under CVS instead of having it generated by mksyntax.
Use CHAR_MIN (from limits.h) to determine whether target char are signed
or unsigned - the syntax tables will not be indexed properly.
Rip out all the stuff from mksyntax.c that wrote syntax.h.
syntax.c can stiff be generated incorrectly...
 1.6.6.1 19-May-2017  pgoyette Resolve conflicts from previous merge (all resulting from $NetBSD
keywork expansion)
 1.7.2.2 10-Sep-2018  martin Pull up following revision(s) via patch (requested by kre in ticket #1015):

bin/sh/expand.c: revision 1.124
bin/sh/expand.c: revision 1.127
bin/sh/parser.c: revision 1.148
bin/sh/parser.c: revision 1.149
bin/sh/syntax.c: revision 1.6
bin/sh/syntax.h: revision 1.9 (partial)

First pass at fixing some of the more arcane pattern matching
possibilities that we do not currently handle all that well.

This mostly means (for now) making sure that quoted pattern
magic characters (as well as quoted sh syntax magic chars)
are properly marked, so they remain known as being quoted,
and do not turn into pattern magic. Also, make sure that an
unquoted \ in a pattern always quotes whatever comes next
(which, unlike in regular expressions, includes inside []
matches),

-

Part 2 of pattern matching (glob etc) fixes.
Attempt to correctly deal with \ (both when it is a literal,
in appropriate cases, and when it appears as CTLESC when it was
detected as a quoting character during parsing).

In a pattern, in sh, no quoted character can ever be anything other
than a literal character. This is quite different than regular
expressions, and even different than other uses of glob matching,
where shell quoting is not an issue.

In something like
ls ?\*.c
the ? is a meta-character, the * is a literal (it was quoted). This
is nothing new, sh has handled that properly for ever.

But the same happens with
VAR='?\*.c'
and
ls $VAR
which has not always been handled correctly. Of course, in
ls "$VAR"
nothing in VAR is a meta-character (the entire expansion is quoted)
so even the '\' must match literally (or more accurately, no matching
happens - VAR simply contains an "unusual" filename). But if it had
been
ls *"$VAR"
then we would be looking for filenames that end with the literal 5
characters that make up $VAR.

The same kinds of things are requires of matching patterns in case
statements, and sub-strings with the % and # operators in variable
expansions.

While here, the final remnant of the ancient !! pattern matching
hack has been removed (the code that actually implemented it was
long gone, but one small piece remained, not doing any real harm,
but potentially wasting time - if someone gave a pattern which would
once have invoked that hack.)
 1.7.2.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.9.4.3 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.9.4.2 21-Apr-2020  martin Sync with HEAD
 1.9.4.1 10-Jun-2019  christos Sync with HEAD
 1.9.2.2 26-Dec-2018  pgoyette Sync with HEAD, resolve a few conflicts
 1.9.2.1 26-Nov-2018  pgoyette Sync with HEAD, resolve a couple of conflicts
 1.13.2.1 02-Aug-2025  perseant Sync with HEAD
 1.58 09-Oct-2024  kre PR bin/58687 -- implement suspend as a builtin in sh

Requested by uwe@ in PR bin/58687 without objections from
anyone except me, here is an implementation of a suspend
builtin command for /bin/sh

The sh.1 man page is updated, naturally, to describe it.

This new builtin does not exist in SMALL shells -- as used
on (some) boot media, etc.

If this turns out not to be useful, it can easily be removed.
 1.57 13-Jul-2024  kre Implement the HISTFILE and HISTAPPEND variables.

See the (newly updated) sh(1) for details.
Also add the -z option to fc (clear history).

None of this exists in SMALL shells.
 1.56 10-Nov-2021  kre branches: 1.56.4;

DEBUG mode changes only. NFC (NC) for any normally compiled shell.

Mostly adding DEBUG mode tracing (when appropriate verbose tracing
is enabled generally) whenever a shell (including sushell) process
exits, so shells that the tracing should indicate why ehslls that
vanish did that.

Note for future investigators: if the relevant tracing is enabled,
and a (sub-)shell still simply seems to have vanished without trace,
the likely cause is that it was killed by a signal - and of those,
the most common that occurs is SIGPIPE.
 1.55 20-Aug-2020  kre Be less conservative about when we do clear_traps() when we have
traps_invalid (that is, when we actually nuke the parent shell's
caught traps in a subshell). This allows more reasonable use of
"trap -p" (and similar) in subshells than existed before (and in
particular, that command can be in a function now - there can also
be several related commands like
traps=$(trap -p INT; trap -p QUIT; trap -p HUP)
A side effect of all of this is that
(eval "$(trap -p)"; ...)
now allows copying caught traps into a subshell environment, if desired.

Also att the ksh93 variant (the one not picked by POSIX as it isn't
generally as useful) of "trap -p" (but call it "trap -P" which extracts
just the trap action for named signals (giving more than one is usually
undesirable). This allows
eval "$(trap -P INT)"
to run the action for SIGINT traps, without needing to attempt to parse
the "trap -p" output.
 1.54 20-Aug-2020  kre Whitespace. NFCI.
 1.53 09-Dec-2019  kre PR bin/54743

If a builtin command or function is the final command intended to be
executed, and is interrupted by a caught signal, the trap handler for
that signal was not executed - the shell simply exited (an exit trap
handler would still have been run - if there was one the handler
for the signal may have been invoked during the execution of the
exit trap handler, which, if it happened, is incorrect sequencing).

Now, if we're exiting, and there are pending signals, run their handlers
just before running the EXIT trap handler, if any.

There are almost certainly plenty more issues with traps that need
solving. Later,

XXX pullup -9

(-8 is too different in this area, and this problem suitably obscure,
that we won't bother) (the -7 sh is simply obsolete).
 1.52 25-Apr-2019  kre branches: 1.52.2;
Better interactive SIGINT handling (when a trap is set), and other
cleanups to the trap code. No longer silently ignore attempts to
do anything other than set SIGKILL or SIGSTOP to the default ('-")
state. Don't include those in trap or trap -p output (the former
because they cannot be other than in default state, so simply aren't
included, the latter because it is pointless) but do list them
when requested with trap -p SIG.

Interactive mode SIGINT traps are now run ASAP, rather than after
a command has been entered (so the sequence ^C \n is no longer needed
to generate one). Further, when trapped, in interactive mode,
while waiting for a user command, a SIGINT acts (aside from the
trap being run) just like when not trapped, aborts the command being
entered (rather than leaving it, which it did when libedit was in use)
prints a new prompt, and starts again (which is what should happen.)

Traps other than SIGINT (which has always been handled special in
interactive mode) are unaffected by this change, as are SIGINT traps
in non-interactive shells. Or that is the intent anyway.

Fix an in_dotrap ref count bug (was never being decremented... that
was inserted in a place never executed) (relatively harmless) and
add/improve some trap/signal related DEBUG mode tracing.
 1.51 18-Jan-2019  kre Finish (hopefully) the second half of 1.47 ... make sure
that when traps are marked as invalid, we never use them
for anything except output from the trap command.

Fixes issues where sub-shells of shells which use traps
(eg: to trap SIGPIPE) can end up looping forever if the
signal occurs in a sub-shell (where the trap is supposed
to be reset to its default). Reported, and mostly
analyzed by Martijn Dekker.
 1.50 12-Dec-2018  kre Reverse a decision made when the printsignals() routines from
kill and sh were merged so that the shell (for trap -l) and
kill (for kill -l) can use the same routine, and site that function
in the shell, rather than in kill (use the code that is in kill as
the basis for that routine). This allows access to sh internals,
and in particular to the posix option, so the builtin kill can
operate in posix mode where the standard requires just a single
character (space of newline) between successive signal names (and
we prefer nicely aligned columns instead)..

In a SMALL shell, use the ancient sh printsignals routine instead,
it is smaller (and very much dumber).

/bin/kill still uses the routine that is in its source, and is
not posix compliant. A task for some other day...
 1.49 05-Dec-2018  kre evert previous, linux build problem confirmed fixed by
update to mkinit.sh (to 1.10).

Or more correctly, revert & fix - turns out that there was an off by one
(failure to adjust for other changes -- in a value printed by debug mode
trace output).

NFC.
 1.48 05-Dec-2018  kre NFC (except that it should, I am guessing, fix compilation on
some versions of liux) - DEBUG mode change: Delete a (relatively new)
trace point (temporarily anyway) which mkinit (a script run using the
host's /bin/sh) apparently cannot handle correctly on (some release of)
linux (it is fine with the NetBSD shell).

I don't know which linux version has a shell with this problem
(or whether it is a mkinit issue that only works by fluke on NetBSD)

Problem reported by gson@
 1.47 03-Dec-2018  kre Cleanup traps a bit - attempt to handle weird uses in traps, such
as traps that issue break/continue/return to cause the loop/function
executing when the trap occurred to break/continue/return, and
generating the correct exit code from the shell including when a
signal is caught, but the trap handler for it exits.

All that from FreeBSD.

Also make
T=$(trap)
work as it is supposed to (also trap -p).

For now this is handled by the same technique as $(jobs) - rather
than clearing the traps in subshells, just mark them invalid, and
then whenever they're invalid, clear them before executing anything
other than the special blessed "trap" command. Eventually we will
handle these using non-subshell command substitution instead (not
creating a subshell environ when the commands in a command-sub alter
nothing in the environment).
 1.46 28-Oct-2018  kre Switch from using two printsignals() functions, one in trap.c
and one in (the included from bin/kill) kill.c and use just
the one in kill.c (which is amended slightly so it can work
the way that trap.c needs it to work). This one is chosen as
it was a much nicer implementation, and because while kill is
always built into the shell, kill also exists without the shell.

Leave the old implementation #if 0'd in trap.c (but updated to
match the calling convention of the one in kill.c) - for now.

Delete references of sys_signame[] from sh/trap.c and along with
that several uses of NSIG (unfortunately, there are still more)
and replace them with the newer libc functional interfaces.
 1.45 19-Aug-2018  kre PR bin/48875 (is related, and ameliorated, but not exactly "fixed")

Import a whole set of tree evaluation enhancements from FreeBSD.

With these, before forking, the shell predicts (often) when all it will
have to do after forking (in the parent) is wait for the child and then
exit with the status from the child, and in such a case simply does not
fork, but rather allows the child to take over the parent's role.

This turns out to handle the particular test case from PR bin/48875 in
such a way that it works as hoped, rather than as it did (the delay there
was caused by an extra copy of the shell hanging around waiting for the
background child to complete ... and keeping the command substitution
stdout open, so the "real" parent had to wait in case more output appeared).

As part of doing this, redirection processing for compound commands gets
moved out of evalsubshell() and into a new evalredir(), which allows us
to properly handle errors occurring while performing those redirects,
and not mishandle (as in simply forget) fd's which had been moved out
of the way temporarily.

evaltree() has its degree of recursion reduced by making it loop to
handle the subsequent operation: that is instead of (for any binop
like ';' '&&' (etc)) where it used to
evaltree(node->left);
evaltree(node->right);
return;
it now does (kind of)
next = node;
while ((node = next) != NULL) {
next = NULL;

if (node is a binary op) {
evaltree(node->left);
if appropriate /* if && test for success, etc */
next = node->right;
continue;
}
/* similar for loops, etc */
}
which can be a good saving, as while the left side (now) tends to be
(usually) a simple (or simpleish) command, the right side can be many
commands (in a command sequence like a; b; c; d; ... the node at the
top of the tree will now have "a" as its left node, and the tree for
b; c; d; ... as its right node - until now everything was evaluated
recursively so it made no difference, and the tree was constructed
the other way).

if/while/... statements are done similarly, recurse to evaluate the
condition, then if the (or one of the) body parts is to be evaluated,
set next to that, and loop (previously it recursed).

There is more to do in this area (particularly in the way that case
statements are processed - we can avoid recursion there as well) but
that can wait for another day.

While doing all of this we keep much better track of when the shell is
just going to exit once the current tree is evaluated (with a new
predicate at_eof() to tell us that we have, for sure, reached the end
of the input stream, that is, this shell will, for certain, not be reading
more command input) and use that info to avoid unneeded forks. For that
we also need another new predicate (have_traps()) to determine of there
are any caught traps which might occur - if there are, we need to remain
to (potentially) handle them, so these optimisations will not occur (to
make the issue in PR 48875 appear again, run the same code, but with a
trap set to execute some code when a signal (or EXIT) occurs - note that
the trap must be set in the appropriate level of sub-shell to have this
effect, any caught traps are cleared in a subshell whenever one is created).

There is still work to be done to handle traps properly, whatever
weirdness they do (some of which is related to some of this.)

These changes do not need man page updates, but 48875 does - an update
to sh.1 will be forthcoming once it is decided what it should say...

Once again, all the heavy lifting for this set of changes comes directly
(with thanks) from the FreeBSD shell.

XXX pullup-8 (but not very soon)
 1.44 22-Jul-2018  kre PR bin/36532 (perhaps)

This is more or less the same patch as provided in the PR
(just 11 years later, so changed a bit) by woods@...

Since there is no known way to actually cause the reported crash,
we may never know if this change actually fixes anything. But
even if it doesn't it certainly cannot hurt.

There is a potential race which could possibly explain the issue
(see commentary in the PR) which is not easy to avoid - if that is
the actual cause, this should provide a defence, if not really a fix.
 1.43 22-Jul-2018  kre Revert previous, change has nothing to do with DEBUG mode.
COming again (correctly) in a few seconds.
 1.42 22-Jul-2018  kre DEBUG mode only change (ie: no effect to any normal shell).

Add tracing of pattern matching (aid in debugging various issues.)
 1.41 05-Jul-2017  kre branches: 1.41.4; 1.41.6;

DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
 1.40 07-May-2017  kre branches: 1.40.2;

Enhance the trap command to make it possible to do what POSIX wants
(even if no shell in existence, that I am aware of, does that).

That is, POSIX says ... [of the trap command with no args]

The shell shall format the output, including the proper use of
quoting, so that it is suitable for re-input to the shell as commands
that achieve the same trapping results. For example:

save_traps=$(trap)

...

eval "$save_traps"

It is obvious what the intent is there. But no shell makes it work.

An example using bash (as the NetBSD shell, still does not do the save_traps=
stuff correctly - but that is a problem for a different time and place...)

Given this script

printf 'At start: '; trap
printf '\n'

traps=$(trap)
trap 'echo hello' INT
printf 'inside : '; trap
printf '\n'
eval "${traps}"

printf 'At end : '; trap
printf '\n'

One would expect that (assuming no traps are set at the start, and
there aren't) that the first trap will print nothing, then the inside
trap will show the trap that was set, and then when we get to the
end everything will be back to nothing again.

But:

At start:
inside : trap -- 'echo hello' SIGINT

At end : trap -- 'echo hello' SIGINT

And of course. when you think about it, it is obvious why this happens.
The first "trap" command prints nothing ... nothing has changed when we
get to the "traps=$(trap)" command ... that trap command also prints
nothing. So this does traps=''. When we do eval "${traps}" we are
doing eval "", and it is hardly surprising that this accomplishes nothing!

Now we cannot rationally change the "trap" command without args to
behave in a way that would make it useful for the posix purpose (and
here, what they're aiming for is good, it should be possible to
accomplish that objective) so is there some other way?

I think I have seen some shell (but I do not remember which one) that
actually has "trap -" that resets all traps to the default, so with that,
if we changed the 'eval "${traps}"' line to 'trap -; eval "${traps}"'
then things would actually work - kind of - that version has race conditions,
so is not really safe to use (it will work, most of the time...)

But, both ksh93 and bash have a -p arg to "trap" that allows information
about the current trap status of named signals to be reported. Unfortunately
they don't do quite the same thing, but that's not important right now,
either would be usable, and they are, but it is a lot of effort, not
nearly as simple as the posix example.

First, while "trap -p" (with no signals specified) works, it works just
the same (in both bash and ksh93, aside from output format) as "trap".
That is, that is useless. But we can to

trap_int=$(trap -p int)
trap_hup=$(trap -p hup)
...

and then reset them all, one by one, later...

(bash syntax)
test -n "${trap_int}" && eval "${trap_int}" || trap - int
test -n "${trap_hup}" && eval "${trap_hup}" || trap - hup
(ksh93 syntax)
trap "${trap_int:-}" int
trap "${trap_hup:-}" hup

the test (for bash) and variable with default for ksh93, is needed
because they both still print nothing if the signal action is the default.

So, this modification attempts to fix all of that...

1) we add trap -p, but make it always output something for every signal
listed (all of the signals if none are given) even if the signal
action is the default.

2) choose the bash output format for trap -p, over the ksh93 format,
even though the simpler usage just above makes the ksh93 form seem
better. But it isn't. Consider:

ksh93$ trap -p int hup
echo hello

One of the two traps has "echo hello" as its action, the other is
still at the default, but which?

From bash...
bash$ trap -p int hup
trap -- 'echo hello' SIGINT

And now we know! Given the bash 'trap -p' format, the following function
produces ksh93 format output (for use with named signals only) instead...

ksh93_trap_p() {
for _ARG_ do
_TRAP_=$(trap -p "${_ARG_}") || return 1
eval set -- "${_TRAP_}"
printf '%s' "$3${3:+
}"
done
return 0
}

[ It needs to be entered without the indentation, that '}"' line has to be
at the margin. If the shell running that has local vars (bash does) then
_ARG_ and _TRAP_ should be made local. ]

So the bash format was chosen (except we do not include the "SIG" on the
signal names. That's irrelevant.)

If no traps are set, "trap -p" will say (on NetBSD of course)...

trap -- - EXIT HUP INT QUIT ILL TRAP ABRT EMT FPE KILL BUS SEGV SYS
trap -- - PIPE ALRM TERM URG STOP TSTP CONT CHLD TTIN TTOU IO XCPU XFSZ
trap -- - VTALRM PROF WINCH INFO USR1 USR2 PWR RT0 RT1 RT2 RT3 RT4 RT5
trap -- - RT6 RT7 RT8 RT9 RT10 RT11 RT12 RT13 RT14 RT15 RT16 RT17 RT18
trap -- - RT19 RT20 RT21 RT22 RT23 RT24 RT25 RT26 RT27 RT28 RT29 RT30

Obviously if traps are set, the relevant signal names will be removed from
that list, and additional lines added for the trapped signals.

With args, the signals names are listed, one line each, whatever
the status of the trap for that signal is:

$ trap -p HUP INT QUIT
trap -- - HUP
trap -- 'echo interrupted' INT
trap -- - QUIT

3) we add "trap -" to reset all traps to default. (It is easy, and seems
useful.)

4) While here, lots of generic cleanup. In particular, get rid of the
NSIG+1 nonsense, and anything that ever believes a signo == NSIG
is in any way rational. Before there was a bunch of confusion,
as we need all the signals for traps, plus one more for the EXIT
trap, which looks like we then need NSIG+1. But EXIT is 0, NSIG
includes signals from 0..NSIG-1 but there is no signal 0, EXIT
uses that slot, so we do not need to add and extra one, NSIG is
enough. (To see the effect of this, use a /bin/sh from before
this fix, and compare the output from

trap '' 64
and trap '' 65

both invalid signal numbers.

Then try just "trap" and watch your shell drop core...)

Eventually NSIG needs to go away completely (from user apps), it
is not POSIX, it isn't really useful (unless we make lots of
assumptions about how signals are numbered, which are not guaranteed,
so even if apps, like this sh, work on NetBSD, they're not portable,)
and it isn't necessary (or will not be, soon.)

But that is for another day...

5) As is kind of obvious above, when listing "all" traps, list all the
ones still at their defaults, and all the ignored signals, on as
few lines as possible (it could all be on one line - technically it
would work as well, but it would have made this cvs log message
really ugly...) Signals with a non-null action still get listed
one to a line (even if several do have the exact same action.)

6) Man page updates as well.

After this change, the following script:

printf 'At start: '; trap
printf '\n'

trap -p >/tmp/out.$$
trap 'echo hello' INT
printf 'inside : '; trap
printf '\n'
. /tmp/out.$$; rm /tmp/out.$$

printf 'At end : '; trap
printf '\n'

which is just the example from above,
using "trap -p" instead of just "trap" to save the traps,
and modified to a form that will work with the NetBSD shell today
produces:

At start:
inside : trap -- 'echo hello' INT

At end :

[Do I get a prize for longest commit log message of the year?]
 1.39 29-Apr-2017  kre Fix several problems with the implementation of the "trap" command
(that is, with the command itself, not with the traps that are
executed, if any).

- "trap -- -l" is not rational, permit the (non-std) -l option only
when given as the sole arg (ie: "trap -l").
- "trap --" is the same as just "trap" (and -- is ignored for below)
- "trap action" generates a usage message (there must be at least one condition)
- "trap N [condition...]" (the old form with a numeric first arg, to reset
traps to default, instead of "trap - condition...") is properly detected.
In particular while "trap 1 2 3" resets sighup sigint and siquit handlers
to default, "trap hup int quit" runs the "hup" command on sigint or sigquit
and does nothing to sighup at all.
- actions can start with "-" (as can commands in general) - it may be unusual
or even unwise, but it is not prohibited, and should work
- bad conditions (signal names/numbers) are just a usage error (resulting in
non-zero "exit status" (and a diagnostic on stderr)) they do not cause
the script to abort (as a syntax error in a special builtin would.)
(so says posix, very explicitly.)
- when outputting the trap list ("trap") properly quote null actions
(ignored conditions). This has the side effect of also generating an
explicit null string ('') in other cases where null values are output,
such as when reporting var values ("set") but that's OK, and might be
better (VAR= and VAR='' mean the same, but the latter is more obvious.)

We still do not properly handle traps=$(trap) (ie: it does not work at all,
and should) but that's a different problem that needs fixing in another place.
 1.38 26-Apr-2017  kre Deal with traps that reset the (same) trap in the trap handler
(avoid referrencing memory that might have been freed).
From FreeBSD (ages ago, just not committed until now...)
 1.37 22-Aug-2015  christos branches: 1.37.6;
report the signal that wait was interrupted by, which is not always SIGINT
anymore.
 1.36 22-Aug-2015  christos Process pending signals while waiting for a job:
$ cat << EOF > hup.sh
#!/bin/sh
trap 'echo SIGHUP; exit 1' 1
sleep 10000 &
wait
EOF
$ chmod +x ./hup.sh
$ ./hup.sh &
$ kill -HUP %1
 1.35 18-Jun-2011  christos branches: 1.35.4; 1.35.22;
PR/45069: Henning Petersen: Use prototypes from builtins.h .
 1.34 15-Feb-2008  matt branches: 1.34.24;
Fix inconsistent definitions
 1.33 15-Jul-2005  christos branches: 1.33.10;
Allow trap to work on ignored signals when the shell is interactive.
 1.32 11-Jul-2005  christos Don't hard ignore signals that were ignored by our environment, because
when we try to set a trap on them it will not work. Also while I am here:
1. don't change the action status if the signal system call failed.
2. don't try to sigignore it if signal failed.
3. clear the signal mask in case our parent blocked it for us.
 1.31 11-Jan-2005  christos PR/28940: David Laight: /bin/sh doesn't quote the output of trap.
 1.30 26-Aug-2003  jmmv Use '\0' instead of NULL in two checks (we are not checking for a pointer
value). While here, add a missing whitespace.
 1.29 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.28 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.27 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.26 18-Mar-2001  wulf branches: 1.26.2;
Extended functionality of the trap builtin, which now closely follows
POSIX recommendations.

- trap now accepts signal names and signal numbers
e.g. INT, SIGINT, 2
- added option -l that outputs a list of valid signals
- added signal EXIT to list of valid signals
- a `-' in the action part will reset specified signal to their
default behaviour
- changed standard output format to make it suitable as an input
to another shell that achieves the same trapping results
 1.25 04-Feb-2001  christos remove redundant declarations and nexted externs.
 1.24 22-May-2000  elric branches: 1.24.4;
Back out previous vfork changes.
 1.23 13-May-2000  elric Now we use vfork(2) instead of fork(2) when we can.
 1.22 27-Jan-2000  christos Fix bin/9184, bin/9194, bin/9265, bin/9266
Exitcode and negation problems (From Martin Husemann)
 1.21 27-Mar-1999  christos When we execute commands from a shell script, make sure that the signals
are being caught (reported by Alexis Rosen), similar to the -c case.

#!/bin/sh
vi "$@"

^C when the script is running...
 1.20 05-Feb-1999  christos Fix the -c problem differently. We cannot just ignore SIGINT etc, otherwise
we cannot interrupt sh -c <command>
 1.19 18-Jan-1999  christos PR/6213: Urban Boquist: /bin/sh does not handle a trapped signal correctly
The problem was that system calls got restarted after a signal,
instead of returning EINTR. Thus the read builtin, had no way to
know that a signal occured that could change the course of execution.
Since the code has sprinkled checks for EINTR all over the place,
it is supposed to work properly with non restartable syscalls.
The fix is to use siginterrupt(signo, 1), before setting a signal
handler, to make sure that system calls don't get restarted.
 1.18 28-Jul-1998  mycroft Delint.
 1.17 04-Jul-1997  christos Fix compiler warnings.
 1.16 16-Oct-1996  christos PR/2808: Remove trailing whitespace (from FreeBSD)
 1.15 07-Jun-1995  christos branches: 1.15.6;
Ignore result of sigaction when setting traps. Traps will succeed even
on SIGKILL or SIGSTOP. This is what other bourne shells do. (suggested
by mycroft)
 1.14 05-Jun-1995  christos Avoid trapping SIGKILL. Pretend that we did, so that we will not keep
failing trying to trap it later. This is what the other bourne shells do.
 1.13 11-May-1995  christos Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.12 21-Mar-1995  cgd convert to new RCS id conventions.
 1.11 23-Dec-1994  cgd be more careful with casts.
 1.10 05-Dec-1994  cgd clean up further. more patches from Jim Jegers
 1.9 11-Jun-1994  mycroft Add RCS ids.
 1.8 12-May-1994  jtc last sys_signame[] changes; shell can now be built from scratch
 1.7 12-May-1994  jtc Include appropriate header files to bring function prototypes into scope.
 1.6 11-May-1994  jtc sync with 4.4lite
 1.5 06-Aug-1993  mycroft Use sys_signame[].
 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.15.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.24.4.3 23-Feb-2002  he Pull up revisions 1.25-1.26 (requested by jonb):
Extend functionality of the trap builtin, which now more closely
follows POSIX recommendations:
o accept signal names as well as signal numbers
o add ``-l'' option which outputs list of valid signals
o add signal EXIT to list of valid signals
o an ``-'' in the action part will reset signal to default behaviour
o changed standard output of ``trap'' to make it suitable as
subsequent input
Also various cleanups of redundant declarations and nested externs.
 1.24.4.2 18-Mar-2001  wulf Reversed submission of trap.c and sh.1 to wrong branch
 1.24.4.1 17-Mar-2001  wulf Extended functionality of the trap builtin, which now closely follows
POSIX recommendations.

- trap now accepts signal names and signal numbers
e.g. INT, SIGINT, 2
- added option -l that outputs a list of valid signals
- added signal EXIT to list of valid signals
- a `-' in the action part will reset specified signal to their
default behaviour
- changed standard output format to make it suitable as an input
to another shell that achieves the same trapping results
 1.26.2.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.33.10.1 23-Mar-2008  matt sync with HEAD
 1.34.24.1 23-Jun-2011  cherry Catchup with rmind-uvmplock merge.
 1.35.22.1 04-Nov-2015  riz Pull up following revision(s) (requested by christos in ticket #964):
bin/sh/jobs.c: revision 1.74
bin/sh/jobs.c: revision 1.75
bin/sh/trap.c: revision 1.36
bin/sh/trap.c: revision 1.37
bin/sh/trap.h: revision 1.21
bin/sh/trap.h: revision 1.22
Process pending signals while waiting for a job:
$ cat << EOF > hup.sh
#!/bin/sh
trap 'echo SIGHUP; exit 1' 1
sleep 10000 &
wait
EOF
$ chmod +x ./hup.sh
$ ./hup.sh &
$ kill -HUP %1
report the signal that wait was interrupted by, which is not always SIGINT
anymore.
 1.35.4.1 15-Nov-2015  bouyer Pull up following revision(s) (requested by christos in ticket #1323):
bin/sh/jobs.c: revision 1.74
bin/sh/jobs.c: revision 1.75
bin/sh/trap.c: revision 1.36
bin/sh/trap.c: revision 1.37
bin/sh/trap.h: revision 1.21
bin/sh/trap.h: revision 1.22
Process pending signals while waiting for a job:
$ cat << EOF > hup.sh
#!/bin/sh
trap 'echo SIGHUP; exit 1' 1
sleep 10000 &
wait
EOF
$ chmod +x ./hup.sh
$ ./hup.sh &
$ kill -HUP %1
report the signal that wait was interrupted by, which is not always SIGINT
anymore.
 1.37.6.2 11-May-2017  pgoyette Sync with HEAD
 1.37.6.1 02-May-2017  pgoyette Sync with HEAD - tag prg-localcount2-base1
 1.40.2.2 25-Aug-2018  martin Pull up following revision(s) (requested by kre in ticket #987):

bin/sh/trap.c: revision 1.44

PR bin/36532 (perhaps)

This is more or less the same patch as provided in the PR
(just 11 years later, so changed a bit) by woods@...

Since there is no known way to actually cause the reported crash,
we may never know if this change actually fixes anything. But
even if it doesn't it certainly cannot hurt.

There is a potential race which could possibly explain the issue
(see commentary in the PR) which is not easy to avoid - if that is
the actual cause, this should provide a defence, if not really a fix.
 1.40.2.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.41.6.4 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.41.6.3 21-Apr-2020  martin Sync with HEAD
 1.41.6.2 08-Apr-2020  martin Merge changes from current as of 20200406
 1.41.6.1 10-Jun-2019  christos Sync with HEAD
 1.41.4.5 18-Jan-2019  pgoyette Synch with HEAD
 1.41.4.4 26-Dec-2018  pgoyette Sync with HEAD, resolve a few conflicts
 1.41.4.3 26-Nov-2018  pgoyette Sync with HEAD, resolve a couple of conflicts
 1.41.4.2 06-Sep-2018  pgoyette Sync with HEAD

Resolve a couple of conflicts (result of the uimin/uimax changes)
 1.41.4.1 28-Jul-2018  pgoyette Sync with HEAD
 1.52.2.1 11-Dec-2019  martin Pull up following revision(s) (requested by kre in ticket #542):

bin/sh/eval.c: revision 1.176
bin/sh/trap.c: revision 1.53

PR bin/54743

Having traps set should not enforce a fork for the next command,
whatever that command happens to be, only for commands which would
normally fork if they weren't the last command expected to be
executed (ie: builtins and functions shouldn't be exexuted in a
sub-shell merely because a trap is set).

As it was (for example)
trap 'whatever' SIGANY; wait $anypid
was guaranteed to fail the wait, as the subshell it was executed
in could not have any children.

XXX pullup -9

PR bin/54743

If a builtin command or function is the final command intended to be
executed, and is interrupted by a caught signal, the trap handler for
that signal was not executed - the shell simply exited (an exit trap
handler would still have been run - if there was one the handler
for the signal may have been invoked during the execution of the
exit trap handler, which, if it happened, is incorrect sequencing).

Now, if we're exiting, and there are pending signals, run their handlers
just before running the EXIT trap handler, if any.
There are almost certainly plenty more issues with traps that need
solving. Later,

XXX pullup -9
(-8 is too different in this area, and this problem suitably obscure,
that we won't bother) (the -7 sh is simply obsolete).
 1.56.4.1 02-Aug-2025  perseant Sync with HEAD
 1.26 09-Oct-2024  kre PR bin/58687 -- implement suspend as a builtin in sh

Requested by uwe@ in PR bin/58687 without objections from
anyone except me, here is an implementation of a suspend
builtin command for /bin/sh

The sh.1 man page is updated, naturally, to describe it.

This new builtin does not exist in SMALL shells -- as used
on (some) boot media, etc.

If this turns out not to be useful, it can easily be removed.
 1.25 03-Dec-2018  martin branches: 1.25.12;
Make pendingsigs forward declaration match the definition.
 1.24 03-Dec-2018  kre Cleanup traps a bit - attempt to handle weird uses in traps, such
as traps that issue break/continue/return to cause the loop/function
executing when the trap occurred to break/continue/return, and
generating the correct exit code from the shell including when a
signal is caught, but the trap handler for it exits.

All that from FreeBSD.

Also make
T=$(trap)
work as it is supposed to (also trap -p).

For now this is handled by the same technique as $(jobs) - rather
than clearing the traps in subshells, just mark them invalid, and
then whenever they're invalid, clear them before executing anything
other than the special blessed "trap" command. Eventually we will
handle these using non-subshell command substitution instead (not
creating a subshell environ when the commands in a command-sub alter
nothing in the environment).
 1.23 19-Aug-2018  kre PR bin/48875 (is related, and ameliorated, but not exactly "fixed")

Import a whole set of tree evaluation enhancements from FreeBSD.

With these, before forking, the shell predicts (often) when all it will
have to do after forking (in the parent) is wait for the child and then
exit with the status from the child, and in such a case simply does not
fork, but rather allows the child to take over the parent's role.

This turns out to handle the particular test case from PR bin/48875 in
such a way that it works as hoped, rather than as it did (the delay there
was caused by an extra copy of the shell hanging around waiting for the
background child to complete ... and keeping the command substitution
stdout open, so the "real" parent had to wait in case more output appeared).

As part of doing this, redirection processing for compound commands gets
moved out of evalsubshell() and into a new evalredir(), which allows us
to properly handle errors occurring while performing those redirects,
and not mishandle (as in simply forget) fd's which had been moved out
of the way temporarily.

evaltree() has its degree of recursion reduced by making it loop to
handle the subsequent operation: that is instead of (for any binop
like ';' '&&' (etc)) where it used to
evaltree(node->left);
evaltree(node->right);
return;
it now does (kind of)
next = node;
while ((node = next) != NULL) {
next = NULL;

if (node is a binary op) {
evaltree(node->left);
if appropriate /* if && test for success, etc */
next = node->right;
continue;
}
/* similar for loops, etc */
}
which can be a good saving, as while the left side (now) tends to be
(usually) a simple (or simpleish) command, the right side can be many
commands (in a command sequence like a; b; c; d; ... the node at the
top of the tree will now have "a" as its left node, and the tree for
b; c; d; ... as its right node - until now everything was evaluated
recursively so it made no difference, and the tree was constructed
the other way).

if/while/... statements are done similarly, recurse to evaluate the
condition, then if the (or one of the) body parts is to be evaluated,
set next to that, and loop (previously it recursed).

There is more to do in this area (particularly in the way that case
statements are processed - we can avoid recursion there as well) but
that can wait for another day.

While doing all of this we keep much better track of when the shell is
just going to exit once the current tree is evaluated (with a new
predicate at_eof() to tell us that we have, for sure, reached the end
of the input stream, that is, this shell will, for certain, not be reading
more command input) and use that info to avoid unneeded forks. For that
we also need another new predicate (have_traps()) to determine of there
are any caught traps which might occur - if there are, we need to remain
to (potentially) handle them, so these optimisations will not occur (to
make the issue in PR 48875 appear again, run the same code, but with a
trap set to execute some code when a signal (or EXIT) occurs - note that
the trap must be set in the appropriate level of sub-shell to have this
effect, any caught traps are cleared in a subshell whenever one is created).

There is still work to be done to handle traps properly, whatever
weirdness they do (some of which is related to some of this.)

These changes do not need man page updates, but 48875 does - an update
to sh.1 will be forthcoming once it is decided what it should say...

Once again, all the heavy lifting for this set of changes comes directly
(with thanks) from the FreeBSD shell.

XXX pullup-8 (but not very soon)
 1.22 22-Aug-2015  christos branches: 1.22.14; 1.22.16;
report the signal that wait was interrupted by, which is not always SIGINT
anymore.
 1.21 22-Aug-2015  christos Process pending signals while waiting for a job:
$ cat << EOF > hup.sh
#!/bin/sh
trap 'echo SIGHUP; exit 1' 1
sleep 10000 &
wait
EOF
$ chmod +x ./hup.sh
$ ./hup.sh &
$ kill -HUP %1
 1.20 15-Mar-2012  joerg branches: 1.20.12;
Add __printflike attribution to use vprintf and friends with an argument
as format string.
 1.19 18-Jun-2011  christos branches: 1.19.2; 1.19.4;
PR/45069: Henning Petersen: Use prototypes from builtins.h .
 1.18 11-Jul-2005  christos branches: 1.18.40;
make setsig() return sig_t
 1.17 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.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 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.14 22-May-2000  elric branches: 1.14.6;
Back out previous vfork changes.
 1.13 13-May-2000  elric Now we use vfork(2) instead of fork(2) when we can.
 1.12 28-Jul-1998  mycroft Be more retentive about use of NOTREACHED and noreturn.
 1.11 16-Oct-1996  christos PR/2808: Remove trailing whitespace (from FreeBSD)
 1.10 07-Jun-1995  christos branches: 1.10.6;
Ignore result of sigaction when setting traps. Traps will succeed even
on SIGKILL or SIGSTOP. This is what other bourne shells do. (suggested
by mycroft)
 1.9 11-May-1995  christos Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.8 21-Mar-1995  cgd convert to new RCS id conventions.
 1.7 23-Dec-1994  cgd be more careful with casts.
 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.10.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.14.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.18.40.1 23-Jun-2011  cherry Catchup with rmind-uvmplock merge.
 1.19.4.1 15-Nov-2015  bouyer Pull up following revision(s) (requested by christos in ticket #1323):
bin/sh/jobs.c: revision 1.74
bin/sh/jobs.c: revision 1.75
bin/sh/trap.c: revision 1.36
bin/sh/trap.c: revision 1.37
bin/sh/trap.h: revision 1.21
bin/sh/trap.h: revision 1.22
Process pending signals while waiting for a job:
$ cat << EOF > hup.sh
#!/bin/sh
trap 'echo SIGHUP; exit 1' 1
sleep 10000 &
wait
EOF
$ chmod +x ./hup.sh
$ ./hup.sh &
$ kill -HUP %1
report the signal that wait was interrupted by, which is not always SIGINT
anymore.
 1.19.2.1 17-Apr-2012  yamt sync with head
 1.20.12.1 04-Nov-2015  riz Pull up following revision(s) (requested by christos in ticket #964):
bin/sh/jobs.c: revision 1.74
bin/sh/jobs.c: revision 1.75
bin/sh/trap.c: revision 1.36
bin/sh/trap.c: revision 1.37
bin/sh/trap.h: revision 1.21
bin/sh/trap.h: revision 1.22
Process pending signals while waiting for a job:
$ cat << EOF > hup.sh
#!/bin/sh
trap 'echo SIGHUP; exit 1' 1
sleep 10000 &
wait
EOF
$ chmod +x ./hup.sh
$ ./hup.sh &
$ kill -HUP %1
report the signal that wait was interrupted by, which is not always SIGINT
anymore.
 1.22.16.3 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.22.16.2 21-Apr-2020  martin Sync with HEAD
 1.22.16.1 10-Jun-2019  christos Sync with HEAD
 1.22.14.2 26-Dec-2018  pgoyette Sync with HEAD, resolve a few conflicts
 1.22.14.1 06-Sep-2018  pgoyette Sync with HEAD

Resolve a couple of conflicts (result of the uimin/uimax changes)
 1.25.12.1 02-Aug-2025  perseant Sync with HEAD
 1.4 11-May-1995  christos Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.3 11-Apr-1995  christos Added missing resource limits and recognize "unlimited" as RLIM_INFINITY
 1.2 21-Mar-1995  cgd convert to new RCS id conventions.
 1.1 04-Nov-1994  jtc ulimit builtin (PR #388)

This public domain code, originally by Doug Gwyn, Doug Kingston, Eric
Gisin, and Michael Rendell was ripped from pdksh 5.0.8 and hacked for
use with ash.
 1.88 26-Dec-2024  kre Fix a bug from when the ToD variable was added (July 2017) where if
TZ is unset, and ToD_FORMAT contains and strftime() conversions which
need to know the zone, bad things happen.

Amazing that no-one (incl me) ever noticed this.

XXX pullup -9, pullup -10 (and -8 from 8.0_RC1 onwards ... sigh)
 1.87 21-Oct-2024  kre If searching for a variable with no name, bail out faster,
that can never succeed. NFCI.
 1.86 14-Oct-2024  kre Apologies for that commit message ... it should have been the same
as for revision 1.124 of Makefile (and as below).

(This change changes nothing).

Reject nul characters in shell input.

At the request of Thomas Klausner (wiz@) copy an idea from OpenBSD,
and have the shell simply reject any (sh) input containing a \0 (nul)
character. Previously nul characters were simply ignored (removed
from the input before it was examined in any other way).

Note this affects data read by the shell itself only, and has no
impact on other utilities, including those that are built into
the shell (so 'read' can still use -d '' to process output using
\0 as the record separator).

While I have tested that this works, there are so many places
where a nul might appear, that I cannot possibly test them all
(or even imagine all the possible places), so if this change
causes any problems, let me know (if from a script, send me the
script).

To undo this change, simply comment out (or delete) the line
CPPFLAGS+= -DREJECT_NULS
from the Makefile, and build again. Eventually if this causes
no problems, that option (conditional compilation) will probably
just go away, and this change would be permanent.

While the conditional compilation (on or off) persists, the
NETBSD_SHELL variable value will contain the word REJECT_NULLS
so you can easily verify if you are running a shell with this
included or not.

No pullups planned.
 1.85 14-Oct-2024  kre # $NetBSD: Makefile,v 1.123 2023/10/19 04:27:24 mrg Exp $
# @(#)Makefile 8.4 (Berkeley) 5/5/95

.include <bsd.own.mk>

PROG= sh
SHSRCS= alias.c arith_token.c arithmetic.c cd.c echo.c error.c eval.c exec.c \
expand.c histedit.c input.c jobs.c mail.c main.c memalloc.c \
miscbltin.c mystring.c options.c parser.c redir.c show.c trap.c \
output.c var.c test.c kill.c syntax.c
GENSRCS=builtins.c init.c nodes.c
GENHDRS=builtins.h nodes.h token.h nodenames.h optinit.h
SRCS= ${SHSRCS} ${GENSRCS}

DPSRCS+=${GENHDRS}

LDADD+= -ledit -lterminfo
DPADD+= ${LIBEDIT} ${LIBTERMINFO}

# Environment for scripts executed during build.
SCRIPT_ENV= \
AWK=${TOOL_AWK:Q} \
MKTEMP=${TOOL_MKTEMP:Q} \
SED=${TOOL_SED:Q}

CPPFLAGS+=-DSHELL -I. -I${.CURDIR} -I${NETBSDSRCDIR}/lib/libedit
CPPFLAGS+= -DUSE_LRAND48
CPPFLAGS+= -DREJECT_NULS

#XXX: For testing only.
#CPPFLAGS+=-DDEBUG=1
#COPTS+=-g
#CFLAGS+=-funsigned-char
#TARGET_CHARFLAG?= -DTARGET_CHAR="unsigned char" -funsigned-char

# Reproducible build parameters ... export into sh for NETBSD_SHELL setting
.if ${MKREPRO_TIMESTAMP:Uno} != "no"
BUILD_DATE!= ${TOOL_DATE} -u -r "${MKREPRO_TIMESTAMP}" "+%Y%m%d%H%M%S"
# These are (should be) equivalent, but the 2nd is easier to understand
#CPPFLAGS+= -DBUILD_DATE='"${BUILD_DATE:C/([^0]0?)(00)*$/\1/}Z"'
CPPFLAGS+= -DBUILD_DATE='"${BUILD_DATE:S/00$//:S/00$//:S/00$//}Z"'
.endif

.ifdef SMALLPROG
CPPFLAGS+=-DSMALL
.endif
.ifdef TINYPROG
CPPFLAGS+=-DTINY
.else
SRCS+=printf.c
.endif

.PATH: ${.CURDIR}/bltin ${NETBSDSRCDIR}/bin/test \
${NETBSDSRCDIR}/usr.bin/printf \
${NETBSDSRCDIR}/bin/kill

CLEANFILES+= ${GENSRCS} ${GENHDRS} sh.html1
CLEANFILES+= trace.*

token.h: mktokens
${_MKTARGET_CREATE}
${SCRIPT_ENV} ${HOST_SH} ${.ALLSRC}

.ORDER: builtins.h builtins.c
builtins.h builtins.c: mkbuiltins shell.h builtins.def
${_MKTARGET_CREATE}
${SCRIPT_ENV} ${HOST_SH} ${.ALLSRC} ${.OBJDIR}
[ -f builtins.h ]

init.c: mkinit.sh ${SHSRCS}
${_MKTARGET_CREATE}
${SCRIPT_ENV} ${HOST_SH} ${.ALLSRC}

.ORDER: nodes.h nodes.c
nodes.c nodes.h: mknodes.sh nodetypes nodes.c.pat
${_MKTARGET_CREATE}
${SCRIPT_ENV} ${HOST_SH} ${.ALLSRC} ${.OBJDIR}
[ -f nodes.h ]

nodenames.h: mknodenames.sh nodes.h
${_MKTARGET_CREATE}
${SCRIPT_ENV} ${HOST_SH} ${.ALLSRC} > ${.TARGET}

optinit.h: mkoptions.sh option.list
${_MKTARGET_CREATE}
${SCRIPT_ENV} ${HOST_SH} ${.ALLSRC} ${.TARGET} ${.OBJDIR}

.if ${USETOOLS} == "yes"
NBCOMPATLIB= -L${TOOLDIR}/lib -lnbcompat
.endif

SUBDIR.roff+=USD.doc

COPTS.printf.c = -Wno-format-nonliteral
COPTS.jobs.c = -Wno-format-nonliteral
COPTS.var.c = -Wno-format-nonliteral

# XXXGCC12 - only on some targets
COPTS.parser.c+= ${${ACTIVE_CC} == "gcc" && ${HAVE_GCC:U0} >= 12:? -Wno-error=clobbered :}

.include <bsd.prog.mk>
.include <bsd.subdir.mk>

${OBJS}: Makefile
 1.84 13-Jul-2024  kre Implement the HISTFILE and HISTAPPEND variables.

See the (newly updated) sh(1) for details.
Also add the -z option to fc (clear history).

None of this exists in SMALL shells.
 1.83 12-Jul-2024  kre Improve safety in var imports from the environment.

Add a new var flag VUNSAFE - set on all vars imported from the environment.

Add setvareqsafe() (which is to setvareq() as setvarsafe() is to setvar())
and use that instead of setvareq() when processing the environment, so
errors don't cause the shell to abort. Use VUNSAFE in that call.

Add flags arguments to all var callback functions which are used when setting
variables, and pass the flags given to the setvar*() functions to those
functions, so they can act differently in different situations (if desired).
Most of them just ignore the flags.

When unsetting a variable, call setvar() to clear things (and call the
callback function) both when the variable had a value which needs to be freed,
and when unsetting a variable which wasn't unset previously, so the VUNSET
flag can be seen by that callback func.

When setting HISTSIZE, use the flags passed to determine whether to ignore
bad values (if VUNSAFE) or treat them as an error. This replaces the
earlier temporary hack to always ignore bad data there (histedit.c 1.68).

Miscellaneous associated minor changes.

These changes should largely be invisible in normal use.
 1.82 18-Sep-2022  kre branches: 1.82.2; 1.82.4;

Oops, somehow managed to commit an older version where NBSH_INVOCATION
start char was '@' rather than '!' (which meant not lexically ordered).
This is how it was intended to be (and is documented).
 1.81 18-Sep-2022  kre Add the -l option (aka -o login): be a login shell. Meaningful only on
the command line (with both - and + forms) - overrides the presence (or
otherwise) of a '-' as argv[0][0].

Since this allows any shell to be a login shell (which simply means that
it runs /etc/profile and ~/.profile at shell startup - there are no other
side effects) add a new, always set at startup, variable NBSH_INVOCATION
which has a char string as its value, where each char has a meaning,
more or less related to how the shell was started. See sh(1).
This is intended to allow those startup scripts to tailor their behaviour
to the nature of this particular login shell (it is possible to detect
whether a shell is a login shell merely because of -l, or whether it would
have been anyway, before the -l option was added - and more). The
var could also be used to set different values for $ENV for different
uses of the shell.
 1.80 09-Aug-2021  kre Fix the fix to a typo in one of the comments.
 1.79 08-Aug-2021  andvar s/varable/variable s/explictly/explicitly/ s/proerly/properly/ in comments.
 1.78 14-Feb-2019  kre branches: 1.78.2;

Add the "specialvar" built-in command. Discussed (well, mentioned
anway) on tech-userlevel with no adverse response.

This allows the magic of vars like HOSTNAME SECONDS, ToD (etc) to be
restored should it be lost - perhaps by having a var of the same name
imported from the environment (which needs to remove the magic in case
a set of scripts are using the env to pass data, and the var name chosen
happens to be one of our magic ones).

No change to SMALL shells (or smaller) - none of the magic vars (except
LINENO, which is exempt from all of this) exist in those, hence such a
shell has no need for this command either.
 1.77 09-Feb-2019  kre DTRT when dynamically generated variables return "unset" instead of
a value. There are none which do that at the minute, so this is a NFCI
change, which is just making the code correct even though nothing
currently triggers any bugs.
 1.76 09-Feb-2019  kre INTON / INTOFF audit and cleanup.

No visible differences expected - there is a remote chance that
some internal lossage may no longer occur in interactive shells
that receive SIGINT (untrapped) at inopportune times, but you would
have had to have been very unlucky to have ever suffered from that.
 1.75 21-Jan-2019  kre Fix an off by one buffer length problem. Fortunately, it was off by
one in the "safe" way (it was ensuring the buffer always ended in 2 \0
characters ... one is enough.) This could affect the expansions of
LINENO RANDOM and SECONDS, though only if they have at least 8 digits
(and then, only sometimes). RANDOM thus is safe, as it never produces
a number with more than 5 digits, you'd need a script with 10000000
lines before there might be an issue with LINENO (and even autoconf
generated scripts don't generally get that bit) and a shell would need
to be running for almost 4 months for SECONDS to climb that high.

Nevertheless: XXX pullup -8.
 1.74 12-Dec-2018  kre Implement:
readonly -q VAR...
readonly -p VAR...
export -q [-x] VAR...
export -p [-x] VAR...

all available only in !SMALL shells - and while here, limit
"export -x" to full sized shells as well.

Also, do a better job of arg checking and validating of the
export and readonly commands (which is really just one built-in)
and of issuing error messages when something bogus is detected.

Since these commands are special builtin commands, any error
causes shell exit (for non-interactive shells).
 1.73 12-Dec-2018  kre Fix a botch made in 1.70 (a bit over a week ago) where
var=foo; readonly var=new
now fails.

If var was already set, an attempt to make it readonly, and assign it
a new value at the same time, failed - the readonly flag was set too soon.

Pointed out by Martijn Dekker (thanks).

Also, while here, add a couple of comments.
 1.72 04-Dec-2018  kre Alter a design botch when magic (self modifying) variables
were added to sh ... in other shells, setting such a variable
(for most of them) causes it to lose its special properties,
and act the same as any other variable. I had assumed that
was just implementor laziness... I was wrong.

From now on the NetBSD shell will act like the others, and if vars
like HOSTNAME (and SECONDS, etc) are used as variables in a script
or whatever, they will act just like normal variables (and unless
this happens when they have been made local, or as a variable-assignment
as a prefix to a command, the special properties they would have had
otherwise are lost for the remainder of the life of the (sub-)shell
in which the variables were set).

Importing a value from the environment counts as setting the
value for this purpose (so if HOSTNAME is set in the environment,
the value there will be the value $HOSTNAME expands to).

The two exceptions to this are LINENO and RANDOM. RANDOM
needs to be able to be set to (re-)set its seed. LINENO needs to
be able to be set (at least in the "local" command) to achieve
the desired functionality. It is unlikely that any (sane) script
is going to want to use those two as normal vars however.

While here, fix a minor bug in popping local vars (fn return) that need
to notify the shell of changes in value (like PATH).

Change sh(1) to reflect this alteration. Also add doc of the
(forgotten) magic var EUSER (which has been there since the others
were added), and add a few more vars (which are documented
in other places in sh(1) - like ENV) into the defined or used
variable list (as well as wherever else they appear).

XXX pullup -8
 1.71 03-Dec-2018  kre Fix "export -x" (and its consequences) to behave as originally
intended (and as documented) rather than how it has been behaving
(which was not very rational.) Since it is unlikely that anyone
is using this, the change should be mostly invisible.

While here, a couple of other minor cleanups:
. One call of geteuid() is enough in choose_ps1()
. Fix a typo in a comment
. Improve appearance (whitspace changes) in find_var()
 1.70 13-Jul-2018  kre Remove atoi()

Mostly use number() (no longer implemented using atoi()) when an
unsigned integer is required, but use strtoXXX() when a conversion
is wanted, without the possibility or error (like setting OPTIND
and RANDOM). Always init OPTIND to 1 when sh starts (overriding
anything in environ.)
 1.69 19-Nov-2017  kre branches: 1.69.2; 1.69.4;
Implement the -X option - an apparent variant of -x which sends all trace
output to the stderr which existed when the -X option was (last) enabled.
It also enables tracing by enabling -x (and when reset, +X, also resets
the 'x' flag (+x)). Note that it is still -x/+x which actually
enables/disables the trace output. Hence "apparent variant" - what -X
actually does (aside from setting -x) is just to lock the trace output,
rather than having it follow wherever stderr is later redirected.
 1.68 28-Oct-2017  kre Extract the variable name validity test from setname() into a
function of its own. It will soon be needed from another source.
 1.67 31-Aug-2017  kre Fix a bug noticed by Soren Jacobsen running the netbsd-6-0 build.sh which
causes a core dump in some exotic circumstances (when restoring local
variables when a function returns). ("build.sh makewrapper" exposed it.)

This was introduced in 1.63 - not as part of the substance of that
change (addition) but as an unrelated "must be the right thing to do"
cleanup, which wasn't...
 1.66 24-Jul-2017  kre NFC: DEBUG mode only change - add a little more tracing.
 1.65 12-Jul-2017  kre Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.64 05-Jul-2017  kre DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
 1.63 30-Jun-2017  kre Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
 1.62 28-Jun-2017  kre Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
 1.61 27-Jun-2017  kre Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
 1.60 17-Jun-2017  kre Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).

Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)

From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
 1.59 17-Jun-2017  kre s/volatile/const/ -- wonderful how opposites attract like this.
 1.58 07-Jun-2017  kre Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)

While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
 1.57 07-Jun-2017  kre A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)

This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)

The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.

This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).

I would not call the results of this perfect yet, but it is close.
 1.56 07-Jun-2017  kre An initial attempt at implementing LINENO to meet the specs.

Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.

Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)

This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.

POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)

This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.

This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).

Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
 1.55 27-May-2017  kre branches: 1.55.2;
More standard (and saner) implementation of the ! reserved word.
Unless the shell is compiled with the (compilation time) option
BOGUS_NOT_COMMAND (as in CFLAGS+=-DBOGUS_NOT_COMMAND) which it
will not normally be, the ! command (reserved word) will only
be permitted at the start of a pipeline (which includes the
degenerate pipeline with no '|'s in it of course - ie: a simple cmd)
and not in the middle of a pipeline sequence (no "cmd | ! cmd" nonsense.)
If the latter is really required, then "cmd | { ! cmd; }" works as
a standard equivalent.

In POSIX mode, permit only one ! ("! pipeline" is ok. "! ! pipeline" is not).
Again, if needed (and POSIX conformance is wanted) "! { ! pipeline; }"
works as an alternative - and is safer, some shells treat "! ! cmd" as
being identical to "cmd" (this one did until recently.)
 1.54 27-May-2017  kre It turns out that most shells do not do variable value/attribute
inheritance when a variable is declared local, but instead leave
the local var unset (if not given a value) in the function.
Only ash derived shells do inheritance it seems.

So, to compensate for that, and get one step closer to making
"local" part of POSIX, so we can really rely upon it, a compromise
has been suggested, where "local x" is implementation defined
when it comes to this issue, and we add "local -I x" to specify
inheritance, and "local -N x" to specify "not" (something...)
(not inherited, or not set, or whatever you prefer to imagine!)
The option names took a lot of hunting to find something reasonable
that no shell (we know of) had already used for some other purpose...
The I was easy, but 'u' 'U' 'X' ... all in use somewhere.

This implements that (well, semi-) agreement.

While here, add "local -x" (which many other shells already have)
which causes the local variable to be made exported. Not a lot
of gain in that (since "export x" can always be done immediately
after "local x") but it is very cheap to add and allows more other
scripts to work with out shell.

Note that while 'local x="${x}"' always works to specify inheritance
(while making the shell work harder), "local x; unset x" does not
always work to specify the alternative, as some shells have
"re-interpreted" unset of a local variable to mean something that
would best be described as "unlocal" instead - ie: after the unset
you might be back with the variable from the outer scope, rather
than with an unset local variable.

Also add "unset -x" to allow unsetting a variable without removing
any exported status it has.

There are gazillions of other options that are not supported here!
 1.53 14-May-2017  kre Make ${NETBSD_SHELL} value include (a human recognisable form of)
MKREPRO_TIMESTAMP (as an additional word in the value, with a "BUILD:" prefix)
if it is set during the build. (Trailing 00 pairs in the time are removed).

While here, throw in some extra words that list the compilation
options used which alter sh behaviour (mostly by removing stuff.)
Usually that will only be noticed in a SMALL shell compiled for
install media, or similar - none of the others (not that there
are many) are ever changed from the default in a normal build
(default settings are just omitted.) This also allows scripts
to tell if they are running in a DEBUG shell, which can sometimes
make debugging easier.
 1.52 10-May-2017  kre I noticed!

POSIX requires that the output of the "set" command (with no args -- it
gives a list of variables, and their values) be sorted according to
the collating sequence defined by the current locale.

Now I'm not aware of any locale where the collating sequence order of
ascii letters, digits, and '_' are any different than they are in the
C locale (and those are the only characters that can occur in variable
names - unless there is perhaps a locale that defines "dictionary" order
as the sort order) but never mind, that isn't the bug...

What "collating sequence order" does mean however, if not "collating
sequence order, except when we happen to have two variable names, where
one name is a prefix of the other (say X and XY) and the first character
of the 'Y' part of the longer name happens to be a digit..."

"set" is not a frequently used command (particularly in scripts where
it matters - that is, the no args form, nothing here alters anything
about any use of set with args) and is already a bit slow (sluggish...)
because of the sort requirement, so let's make it fractionally even
slower, but correct.
 1.51 03-May-2017  kre Make "export VAR" work correctly ... if VAR was unset before this
command it should remain unset afterwards.

Previouly "export VAR" did much the same as:
export VAR="${VAR}"
(but without the side effects if VAR had previously been VAR='~' or similar)

Also stop unset exported variables from actually making it into the
environment. Previously this was impossible - variables get exported
in just one of 3 ways, by being imported from the environ (which means
the var is set) when -a is set, and a var is given a value (so the var
is set), or using "export" which previously always set a null string
if the var was otheriwse unset.

The same happens for "readonly" (readonly and export use the same mechanism)
- except, once marked readonly, it is no longer possible to set the var, so
(assuming VAR is not already readonly)
unset VAR; readonly VAR
is (now) a way to guarantee that "VAR" can never be set.

This conforms with POISX (though it is not particularly clear on this
point) and with bash and ksh93 (and also with the FreeBSD shell, though
they export unset variables that are marked for export as if set to '')

It s not clear whether
unset VAR; readonly VAR; unset VAR; echo $?
should print 0, or non-0, so for now just leave this as it is (prints 1).
 1.50 29-Apr-2017  kre Fix several problems with the implementation of the "trap" command
(that is, with the command itself, not with the traps that are
executed, if any).

- "trap -- -l" is not rational, permit the (non-std) -l option only
when given as the sole arg (ie: "trap -l").
- "trap --" is the same as just "trap" (and -- is ignored for below)
- "trap action" generates a usage message (there must be at least one condition)
- "trap N [condition...]" (the old form with a numeric first arg, to reset
traps to default, instead of "trap - condition...") is properly detected.
In particular while "trap 1 2 3" resets sighup sigint and siquit handlers
to default, "trap hup int quit" runs the "hup" command on sigint or sigquit
and does nothing to sighup at all.
- actions can start with "-" (as can commands in general) - it may be unusual
or even unwise, but it is not prohibited, and should work
- bad conditions (signal names/numbers) are just a usage error (resulting in
non-zero "exit status" (and a diagnostic on stderr)) they do not cause
the script to abort (as a syntax error in a special builtin would.)
(so says posix, very explicitly.)
- when outputting the trap list ("trap") properly quote null actions
(ignored conditions). This has the side effect of also generating an
explicit null string ('') in other cases where null values are output,
such as when reporting var values ("set") but that's OK, and might be
better (VAR= and VAR='' mean the same, but the latter is more obvious.)

We still do not properly handle traps=$(trap) (ie: it does not work at all,
and should) but that's a different problem that needs fixing in another place.
 1.49 31-Mar-2016  christos branches: 1.49.6;
Implement the NETBSD_SHELL readonly unexportable unimportable
variable (with its current value set at 20160401) as discussed on
current-users and tech-userlevel. This also includes the necessary
support to implement it properly (particularly the unexportable
part) and adds options to the export command to support unexportable
variables. Also implement the "posix" option (no single letter
equivalent) which gets its default value from whether or not
POSIXLY_CORRECT is set in the environment when the shell starts
(but can be changed just like any other option using -o and +o on
the command line, or the set builtin command.) While there, fix
all uses of options so it is possible to have options that have a
short (one char) name, and no long name, just as it has been possible
to have options with a long name and no short name, though there
are currently none (with no long name). For now, the only use of
the posix option is to control whether ${ENV} is read at startup
by a non-interactive shell, so changing it with set is not usful
- that might change in the future. (from kre@)
 1.48 27-Mar-2016  christos General KNF and source code cleanups, avoid scattering the
magic string " \t\n" all over the place, slightly improved
syntax error messages, restructured some of the code for
clarity, don't allow IFS to be imported through the environment,
and remove the (never) conditionally compiled ATTY option.
Apart from one or two syntax error messages, and ignoring IFS
if present in the environment, this is intended to have no
user visible changes. (from kre@)
 1.47 08-Mar-2016  christos Move the PPID installation to the init() section.
 1.46 08-Mar-2016  christos - don't export $PPID (from kre)
- include <stdio.h>
 1.45 08-Mar-2016  christos Provide $PPID, kill vvers (unused)
 1.44 26-May-2015  christos Drop privileges when executed set{u,g}id unless -p is specified like other
shells do to avoid system() and popen() abuse.
 1.43 01-Nov-2013  christos PR/48312: Dieter Roelands: According to TOG, unset should not return an error
for functions are variables that were not previously set:
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
 1.42 13-Dec-2012  christos PR/47317: Henning Petersen: Replace index() with strchr()
 1.41 28-Mar-2012  christos branches: 1.41.2;
include <limits.h> for CHAR_MIN/CHAR_MAX
 1.40 18-Jun-2011  christos branches: 1.40.2; 1.40.4;
PR/45069: Henning Petersen: Use prototypes from builtins.h .
 1.39 16-Oct-2008  dholland branches: 1.39.16;
Use "extern" properly for referencing globals defined in other modules.
Now builds cleanly with -warn-common.
 1.38 18-Dec-2006  christos fix a volatile variable; from Anon Ymous
 1.37 24-Apr-2006  snj It's "its."
 1.36 06-Oct-2004  enami Fix a bug introduced by previous commit. It breaks export command
with multiple arguments if one of them are already set. Fix PR#27155
and probably PR#27143.
 1.35 02-Oct-2004  dsl Save the length of each variable in the name table so that we can
compare the lengths and then use memcmp() in the search code.
Speeds up one of my scripts by a facter of 2.
Increase the size of the variable hash table.
Cuts down time for script to execute from 60 seconds to 10.
Move variable search into a new function to hide the implementation
from most of the code, new version is slightly smaller than old.
 1.34 26-Aug-2003  jmmv Include strings.h, needed for index's prototype.
 1.33 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.32 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.31 25-Nov-2002  agc Make this compile on some of the more esoteric architectures (e.g. those
which are not i386)
 1.30 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.29 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.28 15-May-2002  bjh21 Implement sh -a (allexport). Code (all two lines of it) from FreeBSD
(FreeBSD var.c 1.13, sh.1 1.27).
 1.27 04-Feb-2001  christos branches: 1.27.2;
remove redundant declarations and nexted externs.
 1.26 20-Dec-2000  cgd __CONCAT does token pasting, not string concatnation. if something like:
__CONCAT("PATH=",_PATH_STDPATH);
actually works to concantate strings, it's because the preprocessor expands
it into "PATH=""whatever _PATH_STDPATH is" as separate strings, and then
ANSI string concatenation is performed on that. It's more straightforward
to just use ANSI string concatenation directly, and newer GCCs complain
(rightly) about mis-use of token pasting.
 1.25 22-May-2000  elric Back out previous vfork changes.
 1.24 17-May-2000  elric When vforking ensure that the environment passed to exec is built before
vforking as a set of local variables which can be popped by the parent.

Addresses bin/10124.
 1.23 09-Jul-1999  christos compile with WARNS = 2
 1.22 28-Jan-1999  kleink Add support for the export and readonly -p option.
 1.21 07-Apr-1998  fair fix default PATH to be <paths.h> _PATH_DEFPATH
 1.20 07-Apr-1998  fair Change a few things to reference /usr/include/paths.h instead of local
references. Fixing the default PATH is a bit more effort.
 1.19 04-Jul-1997  christos branches: 1.19.2;
Fix compiler warnings.
 1.18 11-Apr-1997  christos Track $TERM and call the appropriate editline(3) routine to update the
terminal type.
 1.17 14-Mar-1997  christos NO_HISTORY->SMALL
 1.16 11-Jan-1997  tls kill 'register'
 1.15 16-Oct-1996  christos PR/2808: - Don't use p++ in macros.
- Hash using unsigned numbers.
(from FreeBSD)
 1.14 25-Jun-1996  christos - Add function callback capability when variables are set.
- Add setvarsafe that returns an error instead of longjmp() to the
error code.
 1.13 11-May-1995  christos branches: 1.13.6;
Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.12 21-Mar-1995  cgd convert to new RCS id conventions.
 1.11 20-Jan-1995  mycroft Remove `.' from default PATH.
 1.10 05-Dec-1994  cgd clean up further. more patches from Jim Jegers
 1.9 23-Sep-1994  mycroft Eliminate uses of some obsolete functions.
 1.8 11-Jun-1994  mycroft Add RCS ids.
 1.7 14-May-1994  cgd add back in support for building w/o obj dir. also, add NO_HISTORY
define, which (if you invoke mkbuiltins properly) gets you a sh w/o
history of command line editing (for floppy sh).
 1.6 12-May-1994  jtc Include appropriate header files to bring function prototypes into scope.
 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.13.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.19.2.1 08-May-1998  mycroft Sync with trunk, per request of christos.
 1.27.2.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.39.16.1 23-Jun-2011  cherry Catchup with rmind-uvmplock merge.
 1.40.4.1 16-Nov-2016  snj Pull up following revision(s) (requested by dholland in ticket #1412):
bin/sh/exec.c: revision 1.45
bin/sh/var.c: revision 1.43
PR/48312: Dieter Roelants: According to TOG, unset should not return an error
for functions are variables that were not previously set:
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
 1.40.2.3 22-May-2014  yamt sync with head.

for a reference, the tree before this commit was tagged
as yamt-pagecache-tag8.

this commit was splitted into small chunks to avoid
a limitation of cvs. ("Protocol error: too many arguments")
 1.40.2.2 23-Jan-2013  yamt sync with head
 1.40.2.1 17-Apr-2012  yamt sync with head
 1.41.2.2 19-Aug-2014  tls Rebase to HEAD as of a few days ago.
 1.41.2.1 25-Feb-2013  tls resync with head
 1.49.6.3 19-May-2017  pgoyette Resolve conflicts from previous merge (all resulting from $NetBSD
keywork expansion)
 1.49.6.2 11-May-2017  pgoyette Sync with HEAD
 1.49.6.1 02-May-2017  pgoyette Sync with HEAD - tag prg-localcount2-base1
 1.55.2.4 07-Dec-2018  martin Pull up following revision(s) (requested by kre in ticket #1127):

bin/sh/var.h: revision 1.38 (via patch)
bin/sh/var.c: revision 1.72
bin/sh/sh.1: revision 1.211 (via patch)

Alter a design botch when magic (self modifying) variables
were added to sh ... in other shells, setting such a variable
(for most of them) causes it to lose its special properties,
and act the same as any other variable. I had assumed that
was just implementor laziness... I was wrong.

From now on the NetBSD shell will act like the others, and if vars
like HOSTNAME (and SECONDS, etc) are used as variables in a script
or whatever, they will act just like normal variables (and unless
this happens when they have been made local, or as a variable-assignment
as a prefix to a command, the special properties they would have had
otherwise are lost for the remainder of the life of the (sub-)shell
in which the variables were set).

Importing a value from the environment counts as setting the
value for this purpose (so if HOSTNAME is set in the environment,
the value there will be the value $HOSTNAME expands to).
The two exceptions to this are LINENO and RANDOM. RANDOM
needs to be able to be set to (re-)set its seed. LINENO needs to
be able to be set (at least in the "local" command) to achieve
the desired functionality. It is unlikely that any (sane) script
is going to want to use those two as normal vars however.

While here, fix a minor bug in popping local vars (fn return) that need
to notify the shell of changes in value (like PATH).
Change sh(1) to reflect this alteration. Also add doc of the
(forgotten) magic var EUSER (which has been there since the others
were added), and add a few more vars (which are documented
in other places in sh(1) - like ENV) into the defined or used
variable list (as well as wherever else they appear).

XXX pullup -8
 1.55.2.3 25-Aug-2018  martin Pull up following revision(s) (requested by kre in ticket #988):

bin/sh/parser.c: revision 1.147
bin/sh/var.c: revision 1.70
bin/sh/mystring.c: revision 1.18
bin/sh/options.c: revision 1.53
bin/sh/histedit.c: revision 1.53

Remove atoi()

Mostly use number() (no longer implemented using atoi()) when an
unsigned integer is required, but use strtoXXX() when a conversion
is wanted, without the possibility or error (like setting OPTIND
and RANDOM). Always init OPTIND to 1 when sh starts (overriding
anything in environ.)
 1.55.2.2 31-Aug-2017  martin Pull up following revision(s) (requested by kre in ticket #250):
bin/sh/var.c: revision 1.67
Fix a bug noticed by Soren Jacobsen running the netbsd-6-0 build.sh which
causes a core dump in some exotic circumstances (when restoring local
variables when a function returns). ("build.sh makewrapper" exposed it.)
This was introduced in 1.63 - not as part of the substance of that
change (addition) but as an unrelated "must be the right thing to do"
cleanup, which wasn't...
 1.55.2.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.69.4.3 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.69.4.2 21-Apr-2020  martin Sync with HEAD
 1.69.4.1 10-Jun-2019  christos Sync with HEAD
 1.69.2.3 26-Jan-2019  pgoyette Sync with HEAD
 1.69.2.2 26-Dec-2018  pgoyette Sync with HEAD, resolve a few conflicts
 1.69.2.1 28-Jul-2018  pgoyette Sync with HEAD
 1.78.2.1 02-Jan-2025  martin Pull up following revision(s) (requested by kre in ticket #1932):

bin/sh/var.c: revision 1.88

Fix a bug from when the ToD variable was added (July 2017) where if
TZ is unset, and ToD_FORMAT contains and strftime() conversions which
need to know the zone, bad things happen.

Amazing that no-one (incl me) ever noticed this.
 1.82.4.1 02-Aug-2025  perseant Sync with HEAD
 1.82.2.1 31-Dec-2024  snj Pull up following revision(s) (requested by kre in ticket #1034):
bin/sh/var.c: 1.88
Fix a bug from when the ToD variable was added (July 2017) where if
TZ is unset, and ToD_FORMAT contains and strftime() conversions which
need to know the zone, bad things happen.
Amazing that no-one (incl me) ever noticed this.
 1.41 13-Jul-2024  kre Implement the HISTFILE and HISTAPPEND variables.

See the (newly updated) sh(1) for details.
Also add the -z option to fc (clear history).

None of this exists in SMALL shells.
 1.40 12-Jul-2024  kre Improve safety in var imports from the environment.

Add a new var flag VUNSAFE - set on all vars imported from the environment.

Add setvareqsafe() (which is to setvareq() as setvarsafe() is to setvar())
and use that instead of setvareq() when processing the environment, so
errors don't cause the shell to abort. Use VUNSAFE in that call.

Add flags arguments to all var callback functions which are used when setting
variables, and pass the flags given to the setvar*() functions to those
functions, so they can act differently in different situations (if desired).
Most of them just ignore the flags.

When unsetting a variable, call setvar() to clear things (and call the
callback function) both when the variable had a value which needs to be freed,
and when unsetting a variable which wasn't unset previously, so the VUNSET
flag can be seen by that callback func.

When setting HISTSIZE, use the flags passed to determine whether to ignore
bad values (if VUNSAFE) or treat them as an error. This replaces the
earlier temporary hack to always ignore bad data there (histedit.c 1.68).

Miscellaneous associated minor changes.

These changes should largely be invisible in normal use.
 1.39 18-Sep-2022  kre branches: 1.39.4;
Add the -l option (aka -o login): be a login shell. Meaningful only on
the command line (with both - and + forms) - overrides the presence (or
otherwise) of a '-' as argv[0][0].

Since this allows any shell to be a login shell (which simply means that
it runs /etc/profile and ~/.profile at shell startup - there are no other
side effects) add a new, always set at startup, variable NBSH_INVOCATION
which has a char string as its value, where each char has a meaning,
more or less related to how the shell was started. See sh(1).
This is intended to allow those startup scripts to tailor their behaviour
to the nature of this particular login shell (it is possible to detect
whether a shell is a login shell merely because of -l, or whether it would
have been anyway, before the -l option was added - and more). The
var could also be used to set different values for $ENV for different
uses of the shell.
 1.38 04-Dec-2018  kre Alter a design botch when magic (self modifying) variables
were added to sh ... in other shells, setting such a variable
(for most of them) causes it to lose its special properties,
and act the same as any other variable. I had assumed that
was just implementor laziness... I was wrong.

From now on the NetBSD shell will act like the others, and if vars
like HOSTNAME (and SECONDS, etc) are used as variables in a script
or whatever, they will act just like normal variables (and unless
this happens when they have been made local, or as a variable-assignment
as a prefix to a command, the special properties they would have had
otherwise are lost for the remainder of the life of the (sub-)shell
in which the variables were set).

Importing a value from the environment counts as setting the
value for this purpose (so if HOSTNAME is set in the environment,
the value there will be the value $HOSTNAME expands to).

The two exceptions to this are LINENO and RANDOM. RANDOM
needs to be able to be set to (re-)set its seed. LINENO needs to
be able to be set (at least in the "local" command) to achieve
the desired functionality. It is unlikely that any (sane) script
is going to want to use those two as normal vars however.

While here, fix a minor bug in popping local vars (fn return) that need
to notify the shell of changes in value (like PATH).

Change sh(1) to reflect this alteration. Also add doc of the
(forgotten) magic var EUSER (which has been there since the others
were added), and add a few more vars (which are documented
in other places in sh(1) - like ENV) into the defined or used
variable list (as well as wherever else they appear).

XXX pullup -8
 1.37 03-Dec-2018  kre Fix "export -x" (and its consequences) to behave as originally
intended (and as documented) rather than how it has been behaving
(which was not very rational.) Since it is unlikely that anyone
is using this, the change should be mostly invisible.

While here, a couple of other minor cleanups:
. One call of geteuid() is enough in choose_ps1()
. Fix a typo in a comment
. Improve appearance (whitspace changes) in find_var()
 1.36 28-Oct-2017  kre branches: 1.36.2; 1.36.4;
Extract the variable name validity test from setname() into a
function of its own. It will soon be needed from another source.
 1.35 30-Jun-2017  kre Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
 1.34 28-Jun-2017  kre Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
 1.33 27-Jun-2017  kre Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
 1.32 26-Jun-2017  kre Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)

Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.

Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.

While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")

TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)

All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
 1.31 17-Jun-2017  kre Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).

Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)

From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
 1.30 07-Jun-2017  kre A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)

This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)

The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.

This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).

I would not call the results of this perfect yet, but it is close.
 1.29 07-Jun-2017  kre An initial attempt at implementing LINENO to meet the specs.

Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.

Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)

This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.

POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)

This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.

This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).

Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
 1.28 31-Mar-2016  christos branches: 1.28.8;
Implement the NETBSD_SHELL readonly unexportable unimportable
variable (with its current value set at 20160401) as discussed on
current-users and tech-userlevel. This also includes the necessary
support to implement it properly (particularly the unexportable
part) and adds options to the export command to support unexportable
variables. Also implement the "posix" option (no single letter
equivalent) which gets its default value from whether or not
POSIXLY_CORRECT is set in the environment when the shell starts
(but can be changed just like any other option using -o and +o on
the command line, or the set builtin command.) While there, fix
all uses of options so it is possible to have options that have a
short (one char) name, and no long name, just as it has been possible
to have options with a long name and no short name, though there
are currently none (with no long name). For now, the only use of
the posix option is to control whether ${ENV} is read at startup
by a non-interactive shell, so changing it with set is not usful
- that might change in the future. (from kre@)
 1.27 27-Mar-2016  christos General KNF and source code cleanups, avoid scattering the
magic string " \t\n" all over the place, slightly improved
syntax error messages, restructured some of the code for
clarity, don't allow IFS to be imported through the environment,
and remove the (never) conditionally compiled ATTY option.
Apart from one or two syntax error messages, and ignoring IFS
if present in the environment, this is intended to have no
user visible changes. (from kre@)
 1.26 26-May-2015  christos Drop privileges when executed set{u,g}id unless -p is specified like other
shells do to avoid system() and popen() abuse.
 1.25 18-Jun-2011  christos PR/45069: Henning Petersen: Use prototypes from builtins.h .
 1.24 16-Oct-2008  dholland branches: 1.24.16;
Use "extern" properly for referencing globals defined in other modules.
Now builds cleanly with -warn-common.
 1.23 02-Oct-2004  dsl Save the length of each variable in the name table so that we can
compare the lengths and then use memcmp() in the search code.
Speeds up one of my scripts by a facter of 2.
Increase the size of the variable hash table.
Cuts down time for script to execute from 60 seconds to 10.
Move variable search into a new function to hide the implementation
from most of the code, new version is slightly smaller than old.
 1.22 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.21 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.20 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.19 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.18 22-May-2000  elric branches: 1.18.6;
Back out previous vfork changes.
 1.17 17-May-2000  elric When vforking ensure that the environment passed to exec is built before
vforking as a set of local variables which can be popped by the parent.

Addresses bin/10124.
 1.16 09-Jul-1999  christos compile with WARNS = 2
 1.15 25-Jan-1999  mycroft Patches from Tor Egge (via Havard Eidnes) to fix various bugs in field
splitting and combining.
(Note: Some of this are not strictly bugs, but differences between traditional
Bourne shell and POSIX.)
 1.14 11-Apr-1997  christos Track $TERM and call the appropriate editline(3) routine to update the
terminal type.
 1.13 14-Mar-1997  christos NO_HISTORY->SMALL
 1.12 02-Nov-1996  christos Fix problems that gcc -Wall found (from Todd Miller, OpenBSD)
 1.11 16-Oct-1996  christos PR/2808: Remove trailing whitespace (from FreeBSD)
 1.10 25-Jun-1996  christos - Add function callback capability when variables are set.
- Add setvarsafe that returns an error instead of longjmp() to the
error code.
 1.9 11-May-1995  christos branches: 1.9.6;
Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.8 21-Mar-1995  cgd convert to new RCS id conventions.
 1.7 05-Dec-1994  cgd clean up further. more patches from Jim Jegers
 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.9.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.18.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.24.16.1 23-Jun-2011  cherry Catchup with rmind-uvmplock merge.
 1.28.8.2 07-Dec-2018  martin Pull up following revision(s) (requested by kre in ticket #1127):

bin/sh/var.h: revision 1.38 (via patch)
bin/sh/var.c: revision 1.72
bin/sh/sh.1: revision 1.211 (via patch)

Alter a design botch when magic (self modifying) variables
were added to sh ... in other shells, setting such a variable
(for most of them) causes it to lose its special properties,
and act the same as any other variable. I had assumed that
was just implementor laziness... I was wrong.

From now on the NetBSD shell will act like the others, and if vars
like HOSTNAME (and SECONDS, etc) are used as variables in a script
or whatever, they will act just like normal variables (and unless
this happens when they have been made local, or as a variable-assignment
as a prefix to a command, the special properties they would have had
otherwise are lost for the remainder of the life of the (sub-)shell
in which the variables were set).

Importing a value from the environment counts as setting the
value for this purpose (so if HOSTNAME is set in the environment,
the value there will be the value $HOSTNAME expands to).
The two exceptions to this are LINENO and RANDOM. RANDOM
needs to be able to be set to (re-)set its seed. LINENO needs to
be able to be set (at least in the "local" command) to achieve
the desired functionality. It is unlikely that any (sane) script
is going to want to use those two as normal vars however.

While here, fix a minor bug in popping local vars (fn return) that need
to notify the shell of changes in value (like PATH).
Change sh(1) to reflect this alteration. Also add doc of the
(forgotten) magic var EUSER (which has been there since the others
were added), and add a few more vars (which are documented
in other places in sh(1) - like ENV) into the defined or used
variable list (as well as wherever else they appear).

XXX pullup -8
 1.28.8.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.36.4.3 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.36.4.2 21-Apr-2020  martin Sync with HEAD
 1.36.4.1 10-Jun-2019  christos Sync with HEAD
 1.36.2.1 26-Dec-2018  pgoyette Sync with HEAD, resolve a few conflicts
 1.39.4.1 02-Aug-2025  perseant Sync with HEAD
 1.4 22-Jan-2022  kre After 3 and a bit years, it is time...
 1.3 12-Dec-2018  kre The time has come, the Walrus said... (but no shoes,
ships, or sealing wax required). No oysters either.

I have not taken the Magical Mystery Tour, but I
say it anyway...
 1.2 31-Mar-2016  christos branches: 1.2.14; 1.2.16;
replace with standard copyright :-)
 1.1 31-Mar-2016  christos Implement the NETBSD_SHELL readonly unexportable unimportable
variable (with its current value set at 20160401) as discussed on
current-users and tech-userlevel. This also includes the necessary
support to implement it properly (particularly the unexportable
part) and adds options to the export command to support unexportable
variables. Also implement the "posix" option (no single letter
equivalent) which gets its default value from whether or not
POSIXLY_CORRECT is set in the environment when the shell starts
(but can be changed just like any other option using -o and +o on
the command line, or the set builtin command.) While there, fix
all uses of options so it is possible to have options that have a
short (one char) name, and no long name, just as it has been possible
to have options with a long name and no short name, though there
are currently none (with no long name). For now, the only use of
the posix option is to control whether ${ENV} is read at startup
by a non-interactive shell, so changing it with set is not usful
- that might change in the future. (from kre@)
 1.2.16.3 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.2.16.2 21-Apr-2020  martin Sync with HEAD
 1.2.16.1 10-Jun-2019  christos Sync with HEAD
 1.2.14.1 26-Dec-2018  pgoyette Sync with HEAD, resolve a few conflicts
 1.4 05-Jul-2014  dholland branches: 1.4.24;
Reorg docs, part 2:
Rename the following reference documents to match their programs:
shell -> sh
viref -> vi

and rename the following to match their topic better:
ipctut -> sockets
ipc -> sockets-advanced

Also, the old "timed" and "timedop" docs are now ref5/timed and
ref8/timed respectively, as the first of these documented the
protocol.
 1.3 05-Jul-2014  dholland Reorg docs, part 1:
Move all the reference manuals to subdirs of /usr/share/doc/reference.
We have subdirs ref1-ref9, corresponding to man page sections 1-9.

Everything that's the reference manual for a program (sections 1, 6,
8), C interface (sections 2, 3), driver or file system (section 4),
format or configuration (section 5), or kernel internal interface
(section 9) belongs in here.

Section 7 is a little less clear: some things that might go in section
7 if they were a man page aren't really reference manuals. So I'm only
putting things in reference section 7 that are (to me) clearly
reference material, rather than e.g. tutorials, guides, FAQs, etc.
This obviously leaves some room for debate, especially without first
editing the docs with this distinction in mind, but if people hate
what I've done things can always be moved again.

Note also that while roff macro man pages traditionally go in section
7, I have put all the roff documentation (macros, tools, etc.) in one
place in reference/ref1/roff. This will make it easier to find and
also easier to edit it into some kind of coherent form.
 1.2 05-Jul-2014  dholland Rework /usr/share/doc.

Update the <bsd.doc.mk> infrastructure, and update the docs to match
the new infrastructure.

- Build and install text, ps, pdf, and/or html, not roff sources.

- Don't wire the chapter numbers into the build system, or use them in
the installed pathnames. This didn't matter much when the docs were a
museum, but now that we're theoretically going to start maintaining
them again, we're going to add and remove documents periodically and
having the chapter numbers baked in creates a lot of thrashing for no
purpose.

- Specify the document name explicitly, rather than implicitly in a
path. Use this name (instead of other random strings) as the name
of the installed files.

- Specify the document section, which is the subdirectory of
/usr/share/doc to install into.

- Allow multiple subdocuments. (That is, multiple documents in one
output directory.)

- Enumerate the .png files groff emits along with html so they can be
installed.

- Remove assorted hand-rolled rules for running roff and roff widgetry
and add enough variable settings to make these unnecessary. This
includes support for
- explicit use of soelim
- refer
- tbl
- pic
- eqn

- Forcibly apply at least minimal amounts of sanity to certain
autogenerated roff files.

- Don't exclude USD.doc, SMM.doc, and PSD.doc directories from the
build, as they now actually do stuff.

Note: currently we can't generate pdf. This turns out to be a
nontrivial problem with no immediate solution forthcoming. So for now,
as a workaround, install compressed .ps as the printable form.
 1.1 22-Aug-2010  perry branches: 1.1.12; 1.1.24;
Revive S.R. Bourne's original tutorial on using the Bourne Shell.
This initial commit consists of the files as they existed in 4.4BSD,
with the copyrights altered to reflect the subsequent BSD relicensing.
 1.1.24.1 10-Aug-2014  tls Rebase.
 1.1.12.1 19-Aug-2014  tls Rebase to HEAD as of a few days ago.
 1.4.24.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.4.24.1 21-Apr-2020  martin Sync with HEAD
 1.2 14-Sep-2018  rillig Fix "every" typo in quote from The Mythical Man-Month
 1.1 22-Aug-2010  perry branches: 1.1.46; 1.1.48;
Revive S.R. Bourne's original tutorial on using the Bourne Shell.
This initial commit consists of the files as they existed in 4.4BSD,
with the copyrights altered to reflect the subsequent BSD relicensing.
 1.1.48.3 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.1.48.2 21-Apr-2020  martin Sync with HEAD
 1.1.48.1 10-Jun-2019  christos Sync with HEAD
 1.1.46.1 30-Sep-2018  pgoyette Ssync with HEAD
 1.1 05-Jul-2014  dholland branches: 1.1.2; 1.1.6; 1.1.28;
Rework /usr/share/doc.

Update the <bsd.doc.mk> infrastructure, and update the docs to match
the new infrastructure.

- Build and install text, ps, pdf, and/or html, not roff sources.

- Don't wire the chapter numbers into the build system, or use them in
the installed pathnames. This didn't matter much when the docs were a
museum, but now that we're theoretically going to start maintaining
them again, we're going to add and remove documents periodically and
having the chapter numbers baked in creates a lot of thrashing for no
purpose.

- Specify the document name explicitly, rather than implicitly in a
path. Use this name (instead of other random strings) as the name
of the installed files.

- Specify the document section, which is the subdirectory of
/usr/share/doc to install into.

- Allow multiple subdocuments. (That is, multiple documents in one
output directory.)

- Enumerate the .png files groff emits along with html so they can be
installed.

- Remove assorted hand-rolled rules for running roff and roff widgetry
and add enough variable settings to make these unnecessary. This
includes support for
- explicit use of soelim
- refer
- tbl
- pic
- eqn

- Forcibly apply at least minimal amounts of sanity to certain
autogenerated roff files.

- Don't exclude USD.doc, SMM.doc, and PSD.doc directories from the
build, as they now actually do stuff.

Note: currently we can't generate pdf. This turns out to be a
nontrivial problem with no immediate solution forthcoming. So for now,
as a workaround, install compressed .ps as the printable form.
 1.1.28.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.1.28.1 21-Apr-2020  martin Sync with HEAD
 1.1.6.2 19-Aug-2014  tls Rebase to HEAD as of a few days ago.
 1.1.6.1 05-Jul-2014  tls file referargs was added on branch tls-maxphys on 2014-08-19 23:45:11 +0000
 1.1.2.2 10-Aug-2014  tls Rebase.
 1.1.2.1 05-Jul-2014  tls file referargs was added on branch tls-earlyentropy on 2014-08-10 06:41:18 +0000
 1.2 22-Aug-2010  perry branches: 1.2.48;
RCSIds
 1.1 22-Aug-2010  perry Revive S.R. Bourne's original tutorial on using the Bourne Shell.
This initial commit consists of the files as they existed in 4.4BSD,
with the copyrights altered to reflect the subsequent BSD relicensing.
 1.2.48.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.2.48.1 21-Apr-2020  martin Sync with HEAD
 1.3 22-Aug-2010  perry branches: 1.3.48;
RCSIds
 1.2 22-Aug-2010  perry Extremely extensive updates.

This document should now serve as a reasonable tutorial for the
modern POSIX shell. Comments and additional fixes for mistakes I may
have made are solicited.
 1.1 22-Aug-2010  perry Revive S.R. Bourne's original tutorial on using the Bourne Shell.
This initial commit consists of the files as they existed in 4.4BSD,
with the copyrights altered to reflect the subsequent BSD relicensing.
 1.3.48.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.3.48.1 21-Apr-2020  martin Sync with HEAD
 1.3 22-Aug-2010  perry branches: 1.3.48;
RCSIds
 1.2 22-Aug-2010  perry Extremely extensive updates.

This document should now serve as a reasonable tutorial for the
modern POSIX shell. Comments and additional fixes for mistakes I may
have made are solicited.
 1.1 22-Aug-2010  perry Revive S.R. Bourne's original tutorial on using the Bourne Shell.
This initial commit consists of the files as they existed in 4.4BSD,
with the copyrights altered to reflect the subsequent BSD relicensing.
 1.3.48.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.3.48.1 21-Apr-2020  martin Sync with HEAD
 1.3 22-Aug-2010  perry branches: 1.3.48;
RCSIds
 1.2 22-Aug-2010  perry Extremely extensive updates.

This document should now serve as a reasonable tutorial for the
modern POSIX shell. Comments and additional fixes for mistakes I may
have made are solicited.
 1.1 22-Aug-2010  perry Revive S.R. Bourne's original tutorial on using the Bourne Shell.
This initial commit consists of the files as they existed in 4.4BSD,
with the copyrights altered to reflect the subsequent BSD relicensing.
 1.3.48.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.3.48.1 21-Apr-2020  martin Sync with HEAD
 1.3 22-Aug-2010  perry branches: 1.3.48;
RCSIds
 1.2 22-Aug-2010  perry Extremely extensive updates.

This document should now serve as a reasonable tutorial for the
modern POSIX shell. Comments and additional fixes for mistakes I may
have made are solicited.
 1.1 22-Aug-2010  perry Revive S.R. Bourne's original tutorial on using the Bourne Shell.
This initial commit consists of the files as they existed in 4.4BSD,
with the copyrights altered to reflect the subsequent BSD relicensing.
 1.3.48.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.3.48.1 21-Apr-2020  martin Sync with HEAD
 1.16 18-May-2021  kre Fix a bug in the built-in echo in /bin/sh reported in private mail by
Oguz <oguzismailuysal@gmail.com>

If echo detects an I/O error, it does exit(1) (that's fine) but then
the next echo also does exit(1) even without any errors of its own,
and every following echo writing to stdout does the same thing.

eg:

echo foo >&- ; echo $?; echo $?; ( echo $( echo $?; echo $?) ; echo $? )
1
1
1 1
1

The first echo writes nothing (stdout is closed) but does exit(1).
The second echo writes "1" (correct, the exit status of the previous
echo) and should exit(0) - but doesn't. This pattern continues...

While here, conform to the POSIX requirement on echo (and many other
standard utilities, but definitely not all) that when the utility
does exit(>0) a message must be written to stderr (and vice versa
in many cases). Our echo (as shown above) did the exit(1) part
when it detected the I/O error, but no message is sent to stderr.
Fix that while we're here.

Similar changes are required for /bin/echo (coming soon), and
/usr/bin/printf (which is also the sh builtin printf) - except
currently that one kind of conforms, as it ignores errors writing
to stdout (as do large numbers of other utilities). For many
programs that's kind of acceptable, but where the sole purpose of
the program is to write to stdout, it really isn't. Also to be
fixed soon.
 1.15 26-Jun-2017  kre branches: 1.15.6; 1.15.12;
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)

Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.

Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.

While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")

TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)

All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
 1.14 16-Mar-2016  christos branches: 1.14.8;
Avoid warning by using gcc'ism
 1.13 12-Oct-2008  dholland output.c output.h: expose OUTPUT_ERR (flag for an exposed flags variable)
bltin.h: support ferror()
echo.c: use ferror() to fail on output write errors

Another piece of PR bin/39574.
 1.12 29-Mar-2008  apb * define SHELL_BUILTIN, which other headers may use to hide some of their
symbols if appropriate. For example, error.h will use it to hide
declarations that should not be seen by external builtins such as printf.
* The shell's outfmt() function returns void, but the standard fprintf()
function returns int. Similarly for several other functions that are
redefined via macros in bltin.h. Add a _RETURN_INT macro to do the
necessary conversion.
* Delete some declarations that appear in error.h.
* Add comments on some #else/#endif lines.
 1.11 07-Aug-2003  agc branches: 1.11.16;
Move UCB-licensed code from 4-clause to 3-clause licence.

Patches provided by Joel Baker in PR 22249, verified by myself.
 1.10 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.9 04-Jul-1997  christos Fix compiler warnings.
 1.8 16-Oct-1996  christos PR/2808: Add a definition for warnx() (from FreeBSD; currently unused)
 1.7 21-Mar-1995  cgd branches: 1.7.6;
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.7.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.11.16.1 18-Nov-2008  bouyer Pull up following revision(s) (requested by dholland in ticket #1232):
bin/echo/echo.c: revision 1.18
bin/sh/bltin/bltin.h: revision 1.13
bin/sh/bltin/echo.c: revision 1.14
bin/sh/output.c: revision 1.30
bin/sh/output.h: revision 1.19
Check ferror(stdout) and exit(1) if there's been a problem.
Fixes PR bin/39574 from Ed Ravin, but with a simpler patch.
output.c output.h: expose OUTPUT_ERR (flag for an exposed flags variable)
bltin.h: support ferror()
echo.c: use ferror() to fail on output write errors
Another piece of PR bin/39574.
 1.14.8.1 23-Jul-2017  snj Pull up following revision(s) (requested by kre in ticket #103):
bin/kill/kill.c: 1.28
bin/sh/Makefile: 1.111-1.113
bin/sh/arith_token.c: 1.5
bin/sh/arith_tokens.h: 1.2
bin/sh/arithmetic.c: 1.3
bin/sh/arithmetic.h: 1.2
bin/sh/bltin/bltin.h: 1.15
bin/sh/cd.c: 1.49-1.50
bin/sh/error.c: 1.40
bin/sh/eval.c: 1.142-1.151
bin/sh/exec.c: 1.49-1.51
bin/sh/exec.h: 1.26
bin/sh/expand.c: 1.113-1.119
bin/sh/expand.h: 1.23
bin/sh/histedit.c: 1.49-1.52
bin/sh/input.c: 1.57-1.60
bin/sh/input.h: 1.19-1.20
bin/sh/jobs.c: 1.86-1.87
bin/sh/main.c: 1.71-1.72
bin/sh/memalloc.c: 1.30
bin/sh/memalloc.h: 1.17
bin/sh/mknodenames.sh: 1.4
bin/sh/mkoptions.sh: 1.3-1.4
bin/sh/myhistedit.h: 1.12-1.13
bin/sh/nodetypes: 1.16-1.18
bin/sh/option.list: 1.3-1.5
bin/sh/parser.c: 1.133-1.141
bin/sh/parser.h: 1.22-1.23
bin/sh/redir.c: 1.58
bin/sh/redir.h: 1.24
bin/sh/sh.1: 1.149-1.159
bin/sh/shell.h: 1.24
bin/sh/show.c: 1.43-1.47
bin/sh/show.h: 1.11
bin/sh/syntax.c: 1.4
bin/sh/syntax.h: 1.8
bin/sh/trap.c: 1.41
bin/sh/var.c: 1.56-1.65
bin/sh/var.h: 1.29-1.35
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version
does about as well as most other shell implementations when expanding
$((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the
latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce
the same value when used on the same line (a defect that other shells do not
share - aside from the FreeBSD sh as it is today, where only the LINENO hack
exists and so (like for us before this commit) $((LINENO)) is always either
0, or at least whatever value was last set, perhaps by
LINENO=${LINENO}
which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string
LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the
same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation
does that fairly literally - except that we only bother before the commands
which actually expand words (for, case and simple commands). Unfortunately
this forgot that expansions also occur in redirects, and the other compound
commands can also have redirects, so if a redirect on one of the other compound
commands wants to use the value of $((LINENO)) as a part of a generated file
name, then it will get an incorrect value. This is the "one problem" above.
(Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just
for reference purposes (it will be superseded within minutes by a better one)
I won't bother. However should anyone else decide that this is a better choice
(it is probably a smaller implementation, in terms of code & data space then
the replacement, but also I would expect, slower, and definitely less accurate)
this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions
(all functions) count from 1 from the start of the function, and elsewhere,
start from 1 from where the shell started reading the input file/stream in
question. In an "eval" expression the line number starts at the line of the
"eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before)
hence this slightly longer than usual commit message.
A better LINENO implementation. This version deletes (well, #if 0's out)
the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)).
(Code to invert the LINENO hack when required, like when de-compiling the
execution tree to provide the "jobs" command strings, is still included,
that can be deleted when the LINENO hack is completely removed - look for
refs to VSLINENO throughout the code. The var funclinno in parser.c can
also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate
as the LINENO hack made ${LINENO} which is very good. That's why the
LINENO hack is not yet completely removed, so it can be easily re-enabled.
If you can tell the difference when it is in use, or not in use, then
something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the
man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function
associated with a variable, which gets called whenever the value of the
variable is required (that's what implements LINENO). There is just
one function pointer however, so any particular variable gets at most
one of the set function (as used for PATH, etc) or the reference function.
The VFUNCREF bit in the var flags indicates which func the variable in
question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
Unbreak (at least) i386 build .... I have no idea why this built for me on
amd64 (problem was missing prototype for snprintf witout <stdio.h>)
While here, add some (DEBUG mode only) tracing that proved useful in
solving another problem.
Set the line number before expanding args, not after. As the line_number
would have usually been set earlier, this change is mostly an effective
no-op, but it is better this way (just in case) - not observed to have
caused any problems.
Undo some over agressive fixes for a (pre-commit) bug that did not
need these changes to be fixed - and these cause problems in another
absurd use case. Either of these issues is unlikely to be seen by
anyone who isn't an idiot masochist...
PR bin/52280
removescapes_nl in expari() even when not quoted,
CRTNONL's appear regardless of quoting (unlike CTLESC).
New sentence, new line. Whitespace.
Improve the (new) LINENO section, markup changes (with thanks to wiz@ for
assistace) and some better wording in a few placed.
I am an idiot... revert the previous unintended commit.
Remove some left over baggage from the LINENO v1 implementation that
didn't get removed with v2, and should have. This would have had
(I think, without having tested it) one very minor effect on the way
LINENO worked in the v2 implementation, but my guess is it would have
taken a long time before anyone noticed...
Correct spelling in comments of DEBUG only code...
(Perhaps) temporary fix to pkgtools (cwrappers) build (configure).
Expanding `` containing \ \n sequences looks to have been giving
problems. I don't think this is the correct fix, but it will do
no worse harm than (perhaps) incorrectly calculating LINENO in this
kind of (rare) circumstance. I'll look and see if there should be
a better fix later.
s/volatile/const/ -- wonderful how opposites attract like this.
NFC (normal use) - DEBUG only change, when showing empty arg list don't
omit terminating \n.
Free stack memory in a couple of obscure cases where it wasn't
being done (one in probably dead code that is never compiled, the other
in a very rare error case.) Since it is stack memory it wasn't lost
in any case, just held longer than needed.
Many internal memory management type fixes.
PR bin/52302 (core dump with interactive shell, here doc and error
on same line) is fixed. (An old bug.)
echo "$( echo x; for a in $( seq 1000 ); do printf '%s\n'; done; echo y )"
consistently prints 1002 lines (x, 1000 empty ones, then y) as it should
(And you don't want to know what it did before, or why.) (Another old one.)
(Recently added) Problems with ~ expansion fixed (mem management related).
Proper fix for the cwrappers configure problem (which includes the quick
fix that was done earlier, but extends upon that to be correct). (This was
another newly added problem.)
And the really devious (and rare) old bug - if STACKSTRNUL() needs to
allocate a new buffer in which to store the \0, calculate the size of
the string space remaining correctly, unlike when SPUTC() grows the
buffer, there is no actual data being stored in the STACKSTRNUL()
case - the string space remaining was calculated as one byte too few.
That would be harmless, unless the next buffer also filled, in which
case it was assumed that it was really full, not one byte less, meaning
one junk char (a nul, or anything) was being copied into the next (even
bigger buffer) corrupting the data.
Consistent use of stalloc() to allocate a new block of (stack) memory,
and grabstackstr() to claim a block of (stack) memory that had already
been occupied but not claimed as in use. Since grabstackstr is implemented
as just a call to stalloc() this is a no-op change in practice, but makes
it much easier to comprehend what is really happening. Previous code
sometimes used stalloc() when the use case was really for grabstackstr().
Change grabstackstr() to actually use the arg passed to it, instead of
(not much better than) guessing how much space to claim,
More care when using unstalloc()/ungrabstackstr() to return space, and in
particular when the stack must be returned to its previous state, rather than
just returning no-longer needed space, neither of those work. They also don't
work properly if there have been (really, even might have been) any stack mem
allocations since the last stalloc()/grabstackstr(). (If we know there
cannot have been then the alloc/release sequence is kind of pointless.)
To work correctly in general we must use setstackmark()/popstackmark() so
do that when needed. Have those also save/restore the top of stack string
space remaining.
[Aside: for those reading this, the "stack" mentioned is not
in any way related to the thing used for maintaining the C
function call state, ie: the "stack segment" of the program,
but the shell's internal memory management strategy.]
More comments to better explain what is happening in some cases.
Also cleaned up some hopelessly broken DEBUG mode data that were
recently added (no effect on anyone but the poor semi-human attempting
to make sense of it...).
User visible changes:
Proper counting of line numbers when a here document is delimited
by a multi-line end-delimiter, as in
cat << 'REALLY
END'
here doc line 1
here doc line 2
REALLY
END
(which is an obscure case, but nothing says should not work.) The \n
in the end-delimiter of the here doc (the last one) was not incrementing
the line number, which from that point on in the script would be 1 too
low (or more, for end-delimiters with more than one \n in them.)
With tilde expansion:
unset HOME; echo ~
changed to return getpwuid(getuid())->pw_home instead of failing (returning ~)
POSIX says this is unspecified, which makes it difficult for a script to
compensate for being run without HOME set (as in env -i sh script), so
while not able to be used portably, this seems like a useful extension
(and is implemented the same way by some other shells).
Further, with
HOME=; printf %s ~
we now write nothing (which is required by POSIX - which requires ~ to
expand to the value of $HOME if it is set) previously if $HOME (in this
case) or a user's directory in the passwd file (for ~user) were a null
STRING, We failed the ~ expansion and left behind '~' or '~user'.
Changed the long name for the -L option from lineno_fn_relative
to local_lineno as the latter seemed to be marginally more popular,
and perhaps more importantly, is the same length as the peviously
existing quietprofile option, which means the man page indentation
for the list of options can return to (about) what it was before...
(That is, less indented, which means more data/line, which means less
lines of man page - a good thing!)
Cosmetic changes to variable flags - make their values more suited
to my delicate sensibilities... (NFC).
Arrange not to barf (ever) if some turkey makes _ readonly. Do this
by adding a VNOERROR flag that causes errors in var setting to be
ignored (intended use is only for internal shell var setting, like of "_").
(nb: invalid var name errors ignore this flag, but those should never
occur on a var set by the shell itself.)
From FreeBSD: don't simply discard memory if a variable is not set for
any reason (including because it is readonly) if the var's value had
been malloc'd. Free it instead...
NFC - DEBUG changes, update this to new TRACE method.
KNF - white space and comment formatting.
NFC - DEBUG mode only change - convert this to the new TRACE() format.
NFC - DEBUG mode only change - complete a change made earlier (marking
the line number when included in the trace line tag to show whether it
comes from the parser, or the elsewhere as they tend to be quite different).
Initially only one case was changed, while I pondered whether I liked it
or not. Now it is all done... Also when there is a line tag at all,
always include the root/sub-shell indicator character, not only when the
pid is included.
NFC: DEBUG related comment change - catch up with reality.
NFC: DEBUG mode only change. Fix botched cleanup of one TRACE().
"b" more forgiving when sorting options to allow reasonable (and intended)
flexibility in option.list format. Changes nothing for current option.list.
Now that excessive use of STACKSTRNUL has served its purpose (well, accidental
purpose) in exposing the bug in its implementation, go back to not using
it when not needed for DEBUG TRACE purposes. This change should have no
practical effect on either a DEBUG shell (where the STACKSTRNUL() calls
remain) or a non DEBUG shell where they are not needed.
Correct the initial line number used for processing -c arg strings.
(It was inheriting the value from end of profile file processing) - I didn't
notice before as I usually test with empty or no profile files to avoid
complications. Trivial change which should have very limited impact.
Fix from FreeBSD (applied there in July 2008...)
Don't dump core with input like sh -c 'x=; echo >&$x' - that is where
the word after a >& or <& redirect expands to nothing at all.
Another fix from FreeBSD (this one from April 2009).
When processing a string (as in eval, trap, or sh -c) don't allow
trailing \n's to destroy the exit status of the last command executed.
That is:
sh -c 'false
'
echo $?
should produce 1, not 0.
It is amazing what nonsense appears to work sometimes... (all my nonsense too!)
Two bugs here, one benign because of the way the script is used.
The other hidden by NetBSD's sort being stable, and the data not really
requiring sorting at all...
So as it happens these fixes change nothing, but they are needed anyway.
(The contents of the generated file are only used in DEBUG shells, so
this is really even less important than it seems.)
Another ancient (highly improbable) bug bites the dust. This one
caused by incorrect macro usage (ie: using the wrong one) which has
been in the sources since version 1.1 (ie: forever).
Like the previous (STACKSTRNUL) bug, the probability of this one
actually occurring has been infinitesimal but the LINENO code increases
that to infinitesimal and a smidgen... (or a few, depending upon usage).
Still, apparently that was enough, Kamil Rytarowski discovered that the
zsh configure script (damn competition!) managed to trigger this problem.
source .editrc after we initialize so that commands persist!
Make arg parsing in kill POSIX compatible with POSIX (XBD 2.12) by
parsing the way getopt(3) would, if only it could handle the (required)
-signumber and -signame options. This adds two "features" to kill,
-ssigname and -lstatus now work (ie: one word with all of the '-', the
option letter, and its value) and "--" also now works (kill -- -pid1 pid2
will not attempt to send the pid1 signal to pid2, but rather SIGTERM
to the pid1 process group and pid2). It is still the case that (apart
from --) at most 1 option is permitted (-l, -s, -signame, or -signumber.)
Note that we now have an ambiguity, -sname might mean "-s name" or
send the signal "sname" - if one of those turns out to be valid, that
will be accepted, otherwise the error message will indicate that "sname"
is not a valid signal name, not that "name" is not. Keeping the "-s"
and signal name as separate words avoids this issue.
Also caution: should someone be weird enough to define a new signal
name (as in the part after SIG) which is almost the same name as an
existing name that starts with 'S' by adding an extra 'S' prepended
(eg: adding a SIGSSYS) then the ambiguity problem becomes much worse.
In that case "kill -ssys" will be resolved in favour of the "-s"
flag being used (the more modern syntax) and would send a SIGSYS, rather
that a SIGSSYS. So don't do that.
While here, switch to using signalname(3) (bye bye NSIG, et. al.), add
some constipation, and show a little pride in formatting the signal names
for "kill -l" (and in the usage when appropriate -- same routine.) Respect
COLUMNS (POSIX XBD 8.3) as primary specification of the width (terminal width,
not number of columns to print) for kill -l, a very small value for COLUMNS
will cause kill -l output to list signals one per line, a very large
value will cause them all to be listed on one line.) (eg: "COLUMNS=1 kill -l")
TODO: the signal printing for "trap -l" and that for "kill -l"
should be switched to use a common routine (for the sh builtin versions.)
All changes of relevance here are to bin/kill - the (minor) changes to bin/sh
are only to properly expose the builtin version of getenv(3) so the builtin
version of kill can use it (ie: make its prototype available.)
Properly support EDITRC - use it as (naming) the file when setting
up libedit, and re-do the config whenever EDITRC is set.
Get rid of workarounds for ancient groff html backend.
Simplify macro usage.
Make one example more like a real world possibility (it still isn't, but
is closer) - though the actual content is irrelevant to the point being made.
Add literal prompt support this allows one to do:
CA="$(printf '\1')"
PS1="${CA}$(tput bold)${CA}\$${CA}$(tput sgr0)${CA} "
Now libedit supports embedded mode switch sequence, improve sh
support for them (adds PSlit variable to set the magic character).
NFC: DEBUG only change - provide an externally visible (to the DEBUG sh
internals) interface to one of the internal (private to trace code) functions
Include redirections in trace output from "set -x"
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)
Implement a bunch of new shell environment variables. many mostly useful
in prompts when expanded at prompt time, but all available for general use.
Many of the new ones are not available in SMALL shells (they work as normal
if assigned, but the shell does not set or use them - and there is no magic
in a SMALL shell (usually for install media.))
Omnibus manual update for prompt expansions and new variables. Throw in
some random cleanups as a bonus.
Correct a markup typo (why did I not see this before the prev commit??)
Sort options (our default is 0..9AaBbZz).
Fix markup problems and a typo.
Make $- list flags in the same order they appear in sh(1)
Do a better job of detecting the error in pkgsrc/devel/libbson-1.6.3's
configure script, ie: $(( which is intended to be a sub-shell in a
command substitution, but is an arith subst instead, it needs to be
written $( ( to do as intended. Instead of just blindly carrying on to
find the missing )) somewhere, anywhere, give up as soon as we have seen
an unbalanced ')' that isn't immediately followed by another ')' which
in a valid arith subst it always would be.
While here, there has been a comment in the code for quite a while noting a
difference in the standard between the text descr & grammar when it comes to
the syntax of case statements. Add more comments to explain why parsing it
as we do is in fact definitely the correct way (ie: the grammar wins arguments
like this...).
DEBUG and white space changes only. Convert TRACE() calls for DEBUg mode
to the new style. NFC (when not debugging sh).
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to
the new format. Also #if 0 a function definition that is used nowhere.
While here, change the function of pushfile() slightly - it now sets
the buf pointer in the top (new) input descriptor to NULL, instead of
simply leaving it - code that needs a buffer always (before and after)
must malloc() one and assign it after the call. But code which does not
(which will be reading from a string or similar) now does not have to
explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
DEBUG changes: convert DEBUG TRACE() calls to new format.
ALso, cause exec failures to always cause the shell to exit with
status 126 or 127, whatever the cause. 127 is intended for lookup
failures (and is used that way), 126 is used for anything else that
goes wrong (as in several other shells.) We no longer use 2 (more easily
confused with an exit status of the command exec'd) for shell exec failures.
DEBUG only changes. Convert the TRACE() calls in the remaining files
that still used it to the new format. NFC.
Fix a reference after free (and consequent nonsense diagnostic for
attempts to set readonly variables) I added in 1.60 by incompletely
copying the FreeBSD fix for the lost memory issue.
 1.15.12.1 31-May-2021  cjep sync with head
 1.15.6.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.15.6.1 21-Apr-2020  martin Sync with HEAD
 1.14 03-Jul-2017  wiz branches: 1.14.6;
Remove workaround for ancient HTML generation code.
 1.13 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.12 08-Feb-2002  ross Generate <>& symbolically. I'm avoiding .../dist/... directories for now.
 1.11 20-Dec-2001  wiz Punctuation nit.
 1.10 20-Dec-2001  wiz Whitespace nits.
 1.9 22-Mar-1999  garbled More and more .Os cleanups. .Os is defined in the tmac.doc-common file,
so we shouldn't override it with versions in the manpages. Many more to
come.
 1.8 16-Oct-1996  christos PR/2808: Use .Nm macro properly. (from FreeBSD)
 1.7 21-Mar-1995  cgd branches: 1.7.6;
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.7.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.14.6.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.14.6.1 21-Apr-2020  martin Sync with HEAD
 1.15 18-May-2021  kre Fix a bug in the built-in echo in /bin/sh reported in private mail by
Oguz <oguzismailuysal@gmail.com>

If echo detects an I/O error, it does exit(1) (that's fine) but then
the next echo also does exit(1) even without any errors of its own,
and every following echo writing to stdout does the same thing.

eg:

echo foo >&- ; echo $?; echo $?; ( echo $( echo $?; echo $?) ; echo $? )
1
1
1 1
1

The first echo writes nothing (stdout is closed) but does exit(1).
The second echo writes "1" (correct, the exit status of the previous
echo) and should exit(0) - but doesn't. This pattern continues...

While here, conform to the POSIX requirement on echo (and many other
standard utilities, but definitely not all) that when the utility
does exit(>0) a message must be written to stderr (and vice versa
in many cases). Our echo (as shown above) did the exit(1) part
when it detected the I/O error, but no message is sent to stderr.
Fix that while we're here.

Similar changes are required for /bin/echo (coming soon), and
/usr/bin/printf (which is also the sh builtin printf) - except
currently that one kind of conforms, as it ignores errors writing
to stdout (as do large numbers of other utilities). For many
programs that's kind of acceptable, but where the sole purpose of
the program is to write to stdout, it really isn't. Also to be
fixed soon.
 1.14 12-Oct-2008  dholland branches: 1.14.62; 1.14.68;
output.c output.h: expose OUTPUT_ERR (flag for an exposed flags variable)
bltin.h: support ferror()
echo.c: use ferror() to fail on output write errors

Another piece of PR bin/39574.
 1.13 12-Dec-2007  lukem use __RCSID()
 1.12 06-Feb-2005  perry branches: 1.12.10; 1.12.16;
remove obsolete register declarations
 1.11 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.10 04-Jan-2003  wiz Spell output with two ts.
 1.9 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.8 02-Nov-1996  christos Fix problems that gcc -Wall found (from Todd Miller, OpenBSD)
 1.7 21-Mar-1995  cgd branches: 1.7.6;
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.7.6.1 26-Jan-1997  rat Update /bin/sh from trunk per request of Christos Zoulas. Fixes
many bugs.
 1.12.16.1 09-Jan-2008  matt sync with HEAD
 1.12.10.1 18-Nov-2008  bouyer Pull up following revision(s) (requested by dholland in ticket #1232):
bin/echo/echo.c: revision 1.18
bin/sh/bltin/bltin.h: revision 1.13
bin/sh/bltin/echo.c: revision 1.14
bin/sh/output.c: revision 1.30
bin/sh/output.h: revision 1.19
Check ferror(stdout) and exit(1) if there's been a problem.
Fixes PR bin/39574 from Ed Ravin, but with a simpler patch.
output.c output.h: expose OUTPUT_ERR (flag for an exposed flags variable)
bltin.h: support ferror()
echo.c: use ferror() to fail on output write errors
Another piece of PR bin/39574.
 1.14.68.1 31-May-2021  cjep sync with head
 1.14.62.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.14.62.1 21-Apr-2020  martin Sync with HEAD
 1.9 09-Apr-2025  kre Modernise these (unused) functions

Much of what is here is truly ancient. It isn't used as
part of the build (never installed anywhere) so are only
available from src/bin/sh/funcs which means that in practice
no-one ever sees or uses any of this.

A notable example is the provided 'suspend' function, which
has been using "set +j" to turn off job control all this time.
That was the old (original ash) name for what is now the 'm'
option ... it was changed (by Berkeley CSRG) in July 1992
(approaching 33 years ago), which means the suspend function
provided here hasn't been used in at least 33 years.
(Since "suspend" is now provided as a sh builtin, the function
here is no real use anyway).

Still, since they exist here, they may as well be made to work
properly.

Note: should anyone decide to install these somewhere, the
"pushd" "popd" and "dirs" scripts are all the same thing,
and (while they could be installed as 3 files) should really
be just one file, linked to 3 names, when installed - it
makes no practical difference which of them gets copied rather
than just being a link.
 1.8 29-Feb-2016  christos branches: 1.8.16; 1.8.28;
delete clauses 3,4
 1.7 11-May-1995  christos Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.6 21-Mar-1995  cgd convert to new RCS id conventions.
 1.5 11-Jun-1994  mycroft Add RCS ids.
 1.4 11-May-1994  jtc sync with 4.4lite
 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.8.28.1 02-Aug-2025  perseant Sync with HEAD
 1.8.16.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.8.16.1 21-Apr-2020  martin Sync with HEAD
 1.10 09-Apr-2025  kre Modernise these (unused) functions

Much of what is here is truly ancient. It isn't used as
part of the build (never installed anywhere) so are only
available from src/bin/sh/funcs which means that in practice
no-one ever sees or uses any of this.

A notable example is the provided 'suspend' function, which
has been using "set +j" to turn off job control all this time.
That was the old (original ash) name for what is now the 'm'
option ... it was changed (by Berkeley CSRG) in July 1992
(approaching 33 years ago), which means the suspend function
provided here hasn't been used in at least 33 years.
(Since "suspend" is now provided as a sh builtin, the function
here is no real use anyway).

Still, since they exist here, they may as well be made to work
properly.

Note: should anyone decide to install these somewhere, the
"pushd" "popd" and "dirs" scripts are all the same thing,
and (while they could be installed as 3 files) should really
be just one file, linked to 3 names, when installed - it
makes no practical difference which of them gets copied rather
than just being a link.
 1.9 07-Apr-2023  kre branches: 1.9.2;

The great shell trailing whitespace cleanup of 2023...
Inspired by private e-mail comments from mouse@

NFCI.
 1.8 29-Feb-2016  christos branches: 1.8.16;
delete clauses 3,4
 1.7 11-May-1995  christos Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.6 21-Mar-1995  cgd convert to new RCS id conventions.
 1.5 11-Jun-1994  mycroft Add RCS ids.
 1.4 11-May-1994  jtc sync with 4.4lite
 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.8.16.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.8.16.1 21-Apr-2020  martin Sync with HEAD
 1.9.2.1 02-Aug-2025  perseant Sync with HEAD
 1.8 29-Feb-2016  christos branches: 1.8.16;
delete clauses 3,4
 1.7 11-May-1995  christos Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.6 21-Mar-1995  cgd convert to new RCS id conventions.
 1.5 11-Jun-1994  mycroft Add RCS ids.
 1.4 11-May-1994  jtc sync with 4.4lite
 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.8.16.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.8.16.1 21-Apr-2020  martin Sync with HEAD
 1.9 09-Apr-2025  kre Modernise these (unused) functions

Much of what is here is truly ancient. It isn't used as
part of the build (never installed anywhere) so are only
available from src/bin/sh/funcs which means that in practice
no-one ever sees or uses any of this.

A notable example is the provided 'suspend' function, which
has been using "set +j" to turn off job control all this time.
That was the old (original ash) name for what is now the 'm'
option ... it was changed (by Berkeley CSRG) in July 1992
(approaching 33 years ago), which means the suspend function
provided here hasn't been used in at least 33 years.
(Since "suspend" is now provided as a sh builtin, the function
here is no real use anyway).

Still, since they exist here, they may as well be made to work
properly.

Note: should anyone decide to install these somewhere, the
"pushd" "popd" and "dirs" scripts are all the same thing,
and (while they could be installed as 3 files) should really
be just one file, linked to 3 names, when installed - it
makes no practical difference which of them gets copied rather
than just being a link.
 1.8 29-Feb-2016  christos branches: 1.8.16; 1.8.28;
delete clauses 3,4
 1.7 11-May-1995  christos Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.6 21-Mar-1995  cgd convert to new RCS id conventions.
 1.5 11-Jun-1994  mycroft Add RCS ids.
 1.4 11-May-1994  jtc sync with 4.4lite
 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.8.28.1 02-Aug-2025  perseant Sync with HEAD
 1.8.16.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.8.16.1 21-Apr-2020  martin Sync with HEAD
 1.9 09-Apr-2025  kre Modernise these (unused) functions

Much of what is here is truly ancient. It isn't used as
part of the build (never installed anywhere) so are only
available from src/bin/sh/funcs which means that in practice
no-one ever sees or uses any of this.

A notable example is the provided 'suspend' function, which
has been using "set +j" to turn off job control all this time.
That was the old (original ash) name for what is now the 'm'
option ... it was changed (by Berkeley CSRG) in July 1992
(approaching 33 years ago), which means the suspend function
provided here hasn't been used in at least 33 years.
(Since "suspend" is now provided as a sh builtin, the function
here is no real use anyway).

Still, since they exist here, they may as well be made to work
properly.

Note: should anyone decide to install these somewhere, the
"pushd" "popd" and "dirs" scripts are all the same thing,
and (while they could be installed as 3 files) should really
be just one file, linked to 3 names, when installed - it
makes no practical difference which of them gets copied rather
than just being a link.
 1.8 29-Feb-2016  christos branches: 1.8.16; 1.8.28;
delete clauses 3,4
 1.7 11-May-1995  christos Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.6 21-Mar-1995  cgd convert to new RCS id conventions.
 1.5 11-Jun-1994  mycroft Add RCS ids.
 1.4 11-May-1994  jtc sync with 4.4lite
 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.8.28.1 02-Aug-2025  perseant Sync with HEAD
 1.8.16.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.8.16.1 21-Apr-2020  martin Sync with HEAD
 1.10 09-Apr-2025  kre Modernise these (unused) functions

Much of what is here is truly ancient. It isn't used as
part of the build (never installed anywhere) so are only
available from src/bin/sh/funcs which means that in practice
no-one ever sees or uses any of this.

A notable example is the provided 'suspend' function, which
has been using "set +j" to turn off job control all this time.
That was the old (original ash) name for what is now the 'm'
option ... it was changed (by Berkeley CSRG) in July 1992
(approaching 33 years ago), which means the suspend function
provided here hasn't been used in at least 33 years.
(Since "suspend" is now provided as a sh builtin, the function
here is no real use anyway).

Still, since they exist here, they may as well be made to work
properly.

Note: should anyone decide to install these somewhere, the
"pushd" "popd" and "dirs" scripts are all the same thing,
and (while they could be installed as 3 files) should really
be just one file, linked to 3 names, when installed - it
makes no practical difference which of them gets copied rather
than just being a link.
 1.9 07-Apr-2023  kre branches: 1.9.2;

The great shell trailing whitespace cleanup of 2023...
Inspired by private e-mail comments from mouse@

NFCI.
 1.8 29-Feb-2016  christos branches: 1.8.16;
delete clauses 3,4
 1.7 11-May-1995  christos Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.6 21-Mar-1995  cgd convert to new RCS id conventions.
 1.5 11-Jun-1994  mycroft Add RCS ids.
 1.4 11-May-1994  jtc sync with 4.4lite
 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.8.16.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.8.16.1 21-Apr-2020  martin Sync with HEAD
 1.9.2.1 02-Aug-2025  perseant Sync with HEAD
 1.10 09-Apr-2025  kre Modernise these (unused) functions

Much of what is here is truly ancient. It isn't used as
part of the build (never installed anywhere) so are only
available from src/bin/sh/funcs which means that in practice
no-one ever sees or uses any of this.

A notable example is the provided 'suspend' function, which
has been using "set +j" to turn off job control all this time.
That was the old (original ash) name for what is now the 'm'
option ... it was changed (by Berkeley CSRG) in July 1992
(approaching 33 years ago), which means the suspend function
provided here hasn't been used in at least 33 years.
(Since "suspend" is now provided as a sh builtin, the function
here is no real use anyway).

Still, since they exist here, they may as well be made to work
properly.

Note: should anyone decide to install these somewhere, the
"pushd" "popd" and "dirs" scripts are all the same thing,
and (while they could be installed as 3 files) should really
be just one file, linked to 3 names, when installed - it
makes no practical difference which of them gets copied rather
than just being a link.
 1.9 07-Apr-2023  kre branches: 1.9.2;

The great shell trailing whitespace cleanup of 2023...
Inspired by private e-mail comments from mouse@

NFCI.
 1.8 29-Feb-2016  christos branches: 1.8.16;
delete clauses 3,4
 1.7 11-May-1995  christos Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.6 21-Mar-1995  cgd convert to new RCS id conventions.
 1.5 11-Jun-1994  mycroft Add RCS ids.
 1.4 11-May-1994  jtc sync with 4.4lite
 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.8.16.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.8.16.1 21-Apr-2020  martin Sync with HEAD
 1.9.2.1 02-Aug-2025  perseant Sync with HEAD
 1.9 09-Apr-2025  kre Modernise these (unused) functions

Much of what is here is truly ancient. It isn't used as
part of the build (never installed anywhere) so are only
available from src/bin/sh/funcs which means that in practice
no-one ever sees or uses any of this.

A notable example is the provided 'suspend' function, which
has been using "set +j" to turn off job control all this time.
That was the old (original ash) name for what is now the 'm'
option ... it was changed (by Berkeley CSRG) in July 1992
(approaching 33 years ago), which means the suspend function
provided here hasn't been used in at least 33 years.
(Since "suspend" is now provided as a sh builtin, the function
here is no real use anyway).

Still, since they exist here, they may as well be made to work
properly.

Note: should anyone decide to install these somewhere, the
"pushd" "popd" and "dirs" scripts are all the same thing,
and (while they could be installed as 3 files) should really
be just one file, linked to 3 names, when installed - it
makes no practical difference which of them gets copied rather
than just being a link.
 1.8 29-Feb-2016  christos branches: 1.8.16; 1.8.28;
delete clauses 3,4
 1.7 11-May-1995  christos Merge in my changes from vangogh, and fix the x=`false`; echo $? == 0
bug.
 1.6 21-Mar-1995  cgd convert to new RCS id conventions.
 1.5 11-Jun-1994  mycroft Add RCS ids.
 1.4 11-May-1994  jtc sync with 4.4lite
 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.8.28.1 02-Aug-2025  perseant Sync with HEAD
 1.8.16.2 21-Apr-2020  martin Ooops, restore accidently removed files from merge mishap
 1.8.16.1 21-Apr-2020  martin Sync with HEAD

RSS XML Feed