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)
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.
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.)
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.
%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).
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.
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).
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).
After all, a system might want to sleep for several
thousand years on a spaceship headed to a distant
solar system...
So, remove the pause() code, deal with limits on the
range (it is just an int) that can be passed to sleep()
by looping, and do a much better job of checking for
out of range input values.
With this change sleep(1) should work for durations
up to something more than 250 billion years. It
fails (at startup, with an error) if the requested
duration is beyond what can be handled.
Here no changes at all related to locales and arg
parsing. Still for another day.
integer" case, so we avoid adjusting the locale of sleep,
and generally be more reliable and simpler.
In addition, deal with weirdness in nanosleep() when the
interval gets long, by avoiding using it. In this version
when the sleep interval < 10000 seconds, we use nanosleep()
as before, for delays longer than that we use sleep() instead,
and ignore any fractional seconds.
We avoid overflow problems here by not bothering to sleep
at all for delays longer than 135 years (approx) and simply
pause() instead. That sleep never terminates in such a
case is unlikely to ever be observed.
This commit makes no decision on the question of whether
the arg should be interpreted in the locale of the user,
or always in the C locale. That is for another day.
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.
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.)
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".
(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
(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.
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).
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.
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.
what the current locale's radix character happens to be,
while still allowing locale specific entry of fractional
seconds (ie: if you're in locale where the radix character
is ',' you san use "sleep 2.5" or "sleep 2,5" and they
accomplish the same thing).
This avoids issues with the "sleep 0.05" in rc.subr which
generated usage messages when a locale that does not use
'.' as its radix character was in use.
Reported on netbsd-users by Dima Veselov, with the problem
diagnosed by Martin Husemann
While here, tighten the arg validity checking (3+4 is
no longer permitted as a synonym of 3) and allow 0.0
to mean the same thing as 0 rather than being an error.
Also, make the SIGINFO reports a little nicer (IMO).
The ATF tests for sleep all pass (not that that means a lot).
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.
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.
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).
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.
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.
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.
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.
(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).