termination with set -e if a command fails in a loop body inside a function
with an explicitely tested exit status, eg
f() {
for i in 1 2 3; do
false
done
}
f || true
Briefly reviewed by: cracauer
two cases of unwanted termination with set -e:
* if-commands containing several commands separated by semicolons, eg
if false; false; then [...]
* functions with an explicitely tested exit status that contain a failing
command which is not the last one, eg
f() {
false
false
}
f || true
PR: 77067, 85267
Briefly reviewed by: cracauer
and linting procedure:
1. Remove useless sub-expression:
- if (*start || (!ifsspc && start > string && (nulonly || 1))) {
+ if (*start || (!ifsspc && start > string)) {
The sub-expression "(nulonly || 1)" always evaluates to true and
according to CVS logs seems to be just a left-over from some
debugging and introduced by accident. Removing the sub-expression
doesn't change semantics and a code inspection showed that the
variable "nulonly" is also not necessary here in any way (and the
expression would require fixing instead of removing).
2. Remove dead code:
- if (backslash && c == '\\') {
- if (read(STDIN_FILENO, &c, 1) != 1) {
- status = 1;
- break;
- }
- STPUTC(c, p);
- } else if (ap[1] != NULL && strchr(ifs, c) != NULL) {
+ if (ap[1] != NULL && strchr(ifs, c) != NULL) {
Inspection of the control and data flow showed that variable
"backslash" is always false (0) when the "if"-expression is
evaluated, hence the whole block is effectively dead code.
Additionally, the skipping of characters after a backslash is already
performed correctly a few lines above, so this code is also not
needed at all. According to the CVS logs and the ASH 0.2 sources,
this code existed in this way already since its early days.
3. Cleanup Style:
- ! trap[signo][0] == '\0' &&
+ ! (trap[signo][0] == '\0') &&
The expression wants to ensure the trap is not assigned the empty
string. But the "!" operator has higher precedence than "==", so the
comparison should be put into parenthesis to form the intended way of
expression. Nevertheless the code was effectively not really broken
as both particular NUL comparisons are semantically equal, of course.
But the parenthesized version is a lot more intuitive.
4. Remove shadowing variable declaration:
- char *q;
The declaration of symbol "q" hides another identical declaration of
"q" in the same context. As the other "q" is already reused multiple
times and also can be reused again without negative side-effects,
just remove the shadowing declaration.
5. Just small cosmetics:
- if (ifsset() != 0)
+ if (ifsset())
The ifsset() macro is already coded by returning the boolean result
of a comparison operator, so no need to compare this boolean result
again against a numerical value. This also aligns the macros usage to
the remaining existing code.
Reviewed by: stefanf@
converting the stat() call to a lstat() call, which will cover the
situation. One can exercise this bug by referring a dangling link with
something like */the-link.
Approved by: re (scottl)
Submitted by: Simon 'corecode' Schubert [corecode fs ei tum de]
Obtained from: NetBSD via DragonFlyBSD (NetBSD rev. 1.51 and DragonFly
rev. 1.6)
MFC After: 3 days
promised by the Argument List Processing section introduction.
What follows the option in the options list is its long name,
not its argument (as is the case for the -c option). Also
sort references in the SEE ALSO section.
Approved by: re (blanket)
benefit of scripts start out as: #!/bin/sh -- # -*- perl -*-
With this fix in place, we can commit a change to kern/imgact_shell.c
so FreeBSD will process the `#!' line in shell-scripts in a more
standard fashion.
PR: 16393
Mentioned on: freebsd-arch
- Move the description of the ``-c string'' option closer to the option itself.
- Add an ENVIRONMENT section (1)
- Add more .Xr cross references to the SEE ALSO section.
Obtained from: NetBSD (1)
work as expected when they have a "shebang line" of:
#!/bin/sh -- # -*- perl -*- -p
This specific line is recommended in some perl documentation, and I think
I've seen similar lines in documentation for ruby and python. Those
write-ups expect `sh' to ignore everything after the '--' if the first
thing after the '--' is a '#'. See chapter 19, "The Command-Line Interface"
in 3rd edition of "Programming Perl", for some discussion of why perl
recommends using this line in some circumstances.
The above line does work on solaris, irix and aix (as three data points),
and it used to work on FreeBSD by means of a similar patch to execve().
However, that change to execve() effected *all* shells (which caused
other problems), and that processing was recently removed.
PR: 16393 (the original request to fix the same issue)
Reviewed by: freebsd-current (looking at a slightly different patch)
MFC after: 1 week
XXX from Tor: "The shell can also go into a similar loop if the child was
killed by signal 127, since the shell would believe the child to have
only stopped (WIFSTOPPED() macro returns nonzero value). Disallowing
signals 127 and 128 will fix that problem." See kern/19402 for details.
PR: bin/66242
Submitted by: tegge
Analysis and testcase by: demon
MFC after: 3 weeks
instead of just !, this allows one to more easily locate/understand
the section of the manpage in question.
Additional wording correction by: keramida
Reviewed by: keramida
considered an error according to the Open Group Base Specification.
PR: standards/45738
Submitted by: Matthias Andree <matthias.andree@web.de>
MFC after: 3 days
Only use return value from system call if system call succeeded.
Tested with `make world` and some of my own scripts.
This should be MFCed soon. While /bin/sh is hard to test the fix is
obviously correct and can be assumed not to break something else
(famous last words...).
Joe Marcus Clarke <marcus@FreeBSD.ORG>, subshells could lose a
non-zero exit status.
This commit is Joe's proposed patch. Thanks!
I verified that the problem Joe found is fixed and I ran a full world
with this patch.
I don't plan to ever commit language patches to /bin/sh again. It is
a minefield too big to navigate without a full-time committment, which
I am not willing to do on our /bin/sh.
Under normal circumstances I would recommend using NetBSD's sh which
has a lot of language fixes (like the ones what these patches were
about) but unfortunately they had implemented broken signal behaviour
for shellscript containing interactive programs. Similar issues apply
to pdksh which is OpenBSD's sh.
From my perspective bash2 is the only really working bourne sh out
there and that one is GPLed. Oh well.
should slightly reduce the number of system calls in critical portions of
the shell, and select a more efficient path through the fdalloc code.
Reviewed by: bde
sh -e behaviour was incorrect when && and || statements where used in
"if" clauses.
This is the patch submitted by MORI Kouji <mori@tri.asanuma.co.jp>.
It fixes the issue at hand, but sh fixes like this are super-hard to
verify that they don't break anything else. I ran some of my old test
cases and a few big GNU configure scripts that detected mistakes
before, with the previous sh, patched sh and bash. No differences in
behaviour found. MFC recommended after longer than usual time.
Compiles on i386 and sledge.
when grepping for JOBS. The recent style cleanup replaced the space with
a tab and broke job control detection. Little edits, disastrous consequences.
Submitted by: Peter Edwards <pmedwards@eircom.net>
X-MFC when: in about 5 weeks with the other sh arithmetic fixes.
- Removed dead declarations
- Made objects that should have been declared as static, static.
The changes use STATIC instead of static, following the existing
convention in the rest of the code.
Approved by: schweikh (mentor)
MFC after: 2 weeks
output buffer, don't insert them at all. This prevents a buffer
*underrun* when the substitution consists completely of newlines
(e.g. `echo`) and the byte before the source buffer to which p
points is a '\n', in which case more characters would be removed
from the output buffer than were inserted.
This fixes certain port builds on sparc64.
Approved by: re (scottl)
Reviewed by: des, tjr
Due to the use of signed vs. unsigned chars on our various platforms, one gets
"warning: comparison is always true due to limited range of data type"
from GCC 3.3.
mutually exclusive. The fact that the most recent one specified on the
command line is the one that takes effect is an implementation detail and
users should not rely on this.
The initial stack_block is staticly allocated and will be aligned
according to the alignment requirements of pointers, which does not
necessarily match the alignment enforced by ALIGN. To solve this a
more involved change is required: remove the static initial stack
and deal with an initial condition of not having a stack at all. This
change is therefore more risky than the previous ones, but unavoidable
(other than not using the platform default alignment).
Discussed with: tjr
Approved and reviewed by: tjr
Tested on: alpha, i386, ia64 and sparc64
The problem with the previous attempt, as noticed by Marcel, was that
stacknxt was being aligned to a pointer boundary instead of an
ALIGNBYTES + 1 boundary, which broke sparc64.
using the alignment from sys/param.h (16) instead of the alignment
from machdep.h (8) tickled a nasty bug in the memory allocator that I
haven't been able to track down yet.