Replace the RESET blocks with regular functions and a reset() function that
calls them all.
This code generation tool is unusual and does not appear to provide much
benefit. I do not think isolating the knowledge about which modules need to
be reset is worth an almost 500-line build tool and wider scope for
variables used by the reset functions.
Also, relying on reset functions is often wrong: the cleanup should be done
in exception handlers so that no stale state remains after 'command eval'
and the like.
These cleanup operations are not needed because they are already performed
after an optimized command substitution (whether there was an error or not).
Although using -i with -c does not seem very useful, it seems inappropriate
to read commands from the terminal in this case.
Side effect: if the -s -c extension is used and the -s option is turned off
using 'set +s' during the interactive part, the shell now exits after an
error or interrupt. Note that POSIX only specifies -s as option to sh, not
to set.
See also Austin Group issue #718.
This is required by POSIX, at least for pids that are not known child
processes.
Other problems with job specifications still cause wait to abort with
exit status 2.
PR: 176916
This is only part of the PR; the behaviour for unknown/invalid pids/jobs
remains unchanged (aborts the builtin with status 2).
PR: 176916
Submitted by: Vadim Goncharov
The linked list of stack marks may cause problems if the allocation stack is
used between an exception and a higher-level popstackmark(), as it may then
touch a stack mark that is local to a function which has returned.
Also, the adjustment compares to a pointer passed to realloc(), which is
undefined behaviour.
Instead of adjusting stack marks when reallocating stack blocks, ensure that
such an adjustment is never necessary by fixing a small piece of memory in
place at a stack mark. This also simplifies the code.
To avoid the problems reported in bin/175922, it remains necessary to call
setstackmark() after popstackmark() if the stack mark remains in use.
* If read -t times out, return status as if interrupted by SIGALRM
(formerly 1).
* If a trapped signal interrupts read, return status 128+sig (formerly 1).
* If [EINTR] occurs but there is no trap, retry the read (for example
because of a SIGWINCH in interactive mode).
* If a read error occurs, write an error message and return status 2.
As before, a variable assignment error returns 2 and discards the remaining
data read.
Use non-blocking I/O to write as much as the pipe will accept (often 64K,
but it can be as little as 4K), avoiding the need for the ugly PIPESIZE
constant. If PIPESIZE was set too high, a deadlock would occur.
It now passes WARNS=7 with clang on i386.
GCC 4.2.1 does not understand setjmp() properly so will always trigger
-Wuninitialized. I will not add the volatile keywords to suppress this.
In some other shells, things like $((a);(b)) are command substitutions.
Also, there are shells that have an extension ((ARITH)) that evaluates an
arithmetic expression and returns status 1 if the result is zero, 0
otherwise. This extension may lead to ambiguity with two subshells starting
in sequence.
If syntactically invalid job identifiers are to be taken as jobs that exited
with status 127, this should not apply to options, so that we can add
options later if need be.
This ensures 'return' in a trap returns the correct status to the caller.
If evalskip is not set or if it is overridden by a previous evalskip, keep
the old behaviour of restoring the exit status from before the trap.
If a stack mark is set while the current stack block is empty, the stack
block may move later on (because of realloc()) and the stack mark needs to
be updated. This updating does not happen after popstackmark() has been
called; therefore, call setstackmark() again if the stack mark is still
being used.
For some reason, this only affects a few users. I cannot reproduce it. The
situation seems quite rare as well because an empty stack block would
usually be freed (by popstackmark()) before execution reaches a
setstackmark() call.
PR: 175922
Tested by: KT Sin
Now it outputs fixed files, which use constants provided by the C standard
library to determine appropriate values for the target machine.
Before, mksyntax inspected the host machine which resulted in subtle
breakage if e.g. char is signed on the host and unsigned on the target such
as when cross-compiling on x86 for ARM.
Tested using -funsigned-char on amd64. Compiling build-tools without it and
sh itself with it causes various tests to fail without this change but not
with this change. With consistent -funsigned-char, tests pass with or
without this change.
The mksyntax program could be removed and syntax.c and syntax.h committed to
the repository.
Submitted by: Christoph Mallon
MFC after: 2 weeks
ISO/IEC 9899:1999 (E) 5.2.1p3 guarantees that the values of the characters
0123456789 are contiguous.
The generated syntax.c and syntax.h remain the same.
Submitted by: Christoph Mallon
Expand here documents at the same point other redirections are expanded but
use a non-fork subshell environment (like simple command substitutions) for
compatibility. Substitition errors result in an empty here document like
before.
As a result, a fork is avoided for short (<4K) expanded here documents.
Unexpanded here documents (with quoted end marker after <<) are not affected
by this change. They already only forked when >4K.
Side effects:
* Order of expansion is slightly different.
* Slow expansions are not executed in parallel with the redirected command.
* A non-fork subshell environment is subtly different from a forked process.
If a loop contained certain commands (such as redirected compound commands),
the temporary memory for the redirection was not freed between iterations of
the loop but only after the loop.
Put a stackmark in evaltree(), freeing memory whenever a node has been
evaluated. Some other stackmarks are then redundant; remove them.
Example:
while :; do { :; } </dev/null; done
Instead of rechecking relative paths for all hashed utilities after a cd,
track if any utility in cmdtable depends on a relative path in PATH.
If there is such a utility, cd clears the entire table.
As a result, the '*' in hash no longer happens.
Accessing sys_siglist directly requires rtld to copy it from libc to the sh
executable's BSS. Also, strsignal() will put in the signal number for
unknown signals (FreeBSD-specific) so we need not do that ourselves.
Unfortunately, there is no function for sys_signame.
If there is a write error on stdout, a message will be printed (to stderr)
and the exit status will be changed to 2 if it would have been 0 or 1.
PR: bin/158206
* The last character is not displayed.
* If the alias ends with itself (as a word), an infinite memory-eating loop
occurs.
If an alias is defined initially, a space is appended to avoid recursion but
this did not happen when an alias was later modified.
PR: bin/173418
Submitted by: Daniel F.
MFC after: 1 week
Although sufficient memory is available for a longer string in cmdname,
this is undefined behaviour anyway.
Side effect: for alignment reasons, an additional byte of memory is
allocated per hashed command.
This reduces code duplication and code size.
/usr/bin/printf is not affected.
Side effect: different error messages when certain builtins are passed
invalid options.