setenv(3) by tracking the size of the memory allocated instead of using
strlen() on the current value.
Convert all calls to POSIX from historic BSD API:
- unsetenv returns an int.
- putenv takes a char * instead of const char *.
- putenv no longer makes a copy of the input string.
- errno is set appropriately for POSIX. Exceptions involve bad environ
variable and internal initialization code. These both set errno to
EFAULT.
Several patches to base utilities to handle the POSIX changes from
Andrey Chernov's previous commit. A few I re-wrote to use setenv()
instead of putenv().
New regression module for tools/regression/environ to test these
functions. It also can be used to test the performance.
Bump __FreeBSD_version to 700050 due to API change.
PR: kern/99826
Approved by: wes
Approved by: re (kensmith)
Not because I admit they are technically wrong and not because of bug
reports (I receive nothing). But because I surprisingly meets so
strong opposition and resistance so lost any desire to continue that.
Anyone who interested in POSIX can dig out what changes and how
through cvs diffs.
1) Under POSIX unsetenv("foo=bar") is explicit error and not equal
to unsetenv("foo")
2) Prepare for upcomig POSIXed putenv() rewrite: make putenv() calls
portable and conforming to standard.
either -v or -V) if a file with a slash in the name doesn't exist (if there is
no slash we already did that).
Additionally, suppress the error message for command -v for files with a slash.
PR: 107674
Submitted by: Martin Kammerhofer
issue a syntax error immediately but save the information that it is erroneous
for later when the parameter expansion is actually done. This means eg. "false
&& ${}" will not generate an error which seems to be required by POSIX.
Include the invalid parameter expansion in the error message (sometimes
abbreviated with ... because recovering it would require a lot of code).
PR: 105078
Submitted by: emaste
process leader for each job. Now the last specified option for the output
format (-l, -p or -s) wins, previously -s trumped -l.
PR: 99926
Submitted by: Ed Schouten and novel (patches modified by me)
Utilities option. Its value is printed at the beginning of the line if tracing
(-x) is active. PS4 defaults to the string "+ " which is compatible with the
old behaviour to always print "+ ".
We still need to expand variables in PS1, PS2 and PS4.
PR: 46441 (part of)
Submitted by: schweikh
Obtained from: NetBSD
.//dir as /dir. Rather strip it only for the purpose of checking if the
directory path should be printed.
PR: 88813
Submitted by: Josh Elsasser
Patch from: NetBSD (cd.c rev 1.38)
MFC after: 2 weeks
own buffer. Interactively typing in long lines (>1023 characters)
previously overflowed the buffer. Unlike the NetBSD people I don't see the
need to subtract 8 from BUFSIZ, so I just used BUFSIZ-1.
Obtained from: NetBSD
PR: 91110
I would have chosen the EOF markers, but they are no longer available
AFAICS, so output "<<HERE" and "<<XHERE" instead.
(NOTE: These changes only affect DEBUG output.)
demanded by POSIX.
- A redirection error is only fatal (meaning the execution of a shell script is
terminated) for special built-ins. Previously it was fatal for all shell
builtins, causing problems like the one reported in PR 88845.
- Variable assignments remain in effect for special built-ins.
- Option or operand errors are only fatal for special built-ins.
This change also makes errors from 'fc' non-fatal (I could not find any reasons
for this behaviour).
Somewhat independently from the above down-grade the error handling in the
shift built-in if the operand is bigger than $# from an error() call (which is
now fatal) to a return 1. I'm not sure if this should be considered a POSIX
"operand error", however this change is needed for now as we trigger that error
while building libncurses. Comparing with other shells, zsh does the same as
our sh before this change (write a diagnostic, return 1), bash behaves as our
sh after this commit (no diagnostic, return 1) and ksh93 and NetBSD's sh treat
it as a fatal error.
is just ". file" according to POSIX, however many other shells allow
arguments to be passed after the file. For compatibility (we even use that
feature in buildworld) additional arguments are not considered to be an
error, even though this shell does not do anything with the arguments at all.
new member to struct builtincmd and set it to 1 if -s was specified. This
is done because there are cases where special builtins must be treated
differently from other builtins.
Obtained from: NetBSD (builtins.def part)
automatically it is possible wait4(2) returns -1 and sets
errno = ECHILD if there were forked children. A user can
set such signal handler e.g. via ``trap "" 20'', see a PR
for the test case. Deal with this case and mark a job as
JOBDONE.
PR: bin/90334
Submitted by: bde
MFC after: 4 weeks
This makes a difference for the trap builtin, where after "trap '' 0" we
printed "trap -- quit". This is wrong, because an empty action means to reset
the action to the default. A side effect of this commit is that empty
variables are now printed as "variable=''" instead of just "variable=".
itself and its children. Instead of calling times() (as implied by POSIX) this
implementation directly calls getrusage() to get the times because this is more
convenient.
set +o can be used to reload previous settings, for this to work disabled
options must be printed as well or otherwise options that were set in the mean
time won't be turned off.
To avoid an excessively long output line I formatted the output to print only
six options per line.
Submitted by: Jilles Tjoelker
PR: 73500
ckrealloc and ckfree (added), respectively. sh jumps out of the signal handler
using longjmp which is obviously a bad idea during malloc calls.
Note: I think there is still a small race here because volatile sig_atomic_t
only guarantees atomic reads and writes while we're doing increments and
decrements.
Protect a setmode call with INT{ON,OFF} as it calls malloc internally.
PR: 45478
Patch from: Nate Eldredge
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.
are later stripped with rmescapes() in expandarg(). If the filename has
already been unescaped, doing it again in rmescapes() can walk off the
end of the string, leading to memory corruption and eventually SIGSEGV.
Noticed by: kris
commands. Commands like "if then ... fi" and "while do ... done" are no
longer accepted. Bodies of compound commands are still allowed to be
empty, because even though POSIX does not allow them, most shells do.
pointers. This fixes two format warnings on 64 bits
archs which are fatal now that WFORMAT=0 has been removed.
It doesn't fully fix the sh(1) build on 64 bits platforms
though, there is still some quad_t issues that need to be
fixed.
Tested on: i386, sparc64
adding history and vi/emacs-style line editing to the shell itself.
Atty was a user-mode terminal emulator (like screen and window) that did
line editing and history.
forkshell() after it has been freed. This caused mysterious behaviour
when anything but the first command in a pipeline tried to access the
terminal when the `junk' malloc() option was enabled (which is the default).
itself does that if you set EL_SIGNAL. Instead, set a flag and check it
before calling el_gets(). This is safer, but slower to respond to changes.
Pointed out by: mp
shell function and alias lookup. The -p option has been implemented, the
UPE -v and -V options have not. The old `command' command has been renamed
to `builtin'.
The pgrp member of struct job was declared as a short and could not store
every possible process group ID value, the rest of them were benign because
pid_t happens to be an int.
2. Instead, open /dev/tty. This problem stopped commands in subshells from
being executed correctly if standard error was redirected.
PR: 36671
Obtained from: NetBSD (but simplified)
reality (and POSIX): current directory isn't searched unless CDPATH has
a "." element or is unset.
PR: 38442
Submitted by: oleg dashevskii <be9@be9.ru>
MFC after: 1 week
keep a linked list of the jobs, most recently used first. This is required
to support the idea of `previous job', and to allow the jobs fg and bg
default to be correct according to POSIX.
to fail when the logical current directory no longer exists. Allow changes
to absolute paths when logical cwd is invalid, fall back to physical cd
if logical cd fails.
o Old-style K&R declarations have been converted to new C89 style
o register has been removed
o prototype for main() has been removed (gcc3 makes it an error)
o int main(int argc, char *argv[]) is the preferred main definition.
o Attempt to not break style(9) conformance for declarations more than
they already are.
o Change
int
foo() {
...
to
int
foo(void)
{
...
used so often that it's worth keeping it as a builtin.
Now that all the printf invocations from within the system startup
scripts, we can safely remove it.
Urged by: sheldonh :)
No MFC is planned so far because it may break compatibility and
violate POLA.
binary size increase is 3,784 bytes (about 0.6%).
I don't drop the printf builtin while I'm here because some /etc/rc.*
scripts seem to use it before mounting /usr where printf(1) resides.
Reviewed by: arch (sheldonh)
Inspired by: NetBSD, ksh
Clued by: ume (on how the printf builtin is used)
setvar() and passed to setvareq(). When the VTEXTFIXED flag is set,
that copy is never freed, causing a memory leak.
PR: 31533
Submitted by: maxim@macomnet.ru
value CTLARI since this might break expansion of arithmetic expressions.
Don't access memory below start of stackblock.
Problem analyzed by hunt@iprg.nokia.com, slightly different patch applied.
PR: 24443
Submitted by: hunt@iprg.nokia.com
Avoid using parenthesis enclosure macros (.Pq and .Po/.Pc) with plain text.
Not only this slows down the mdoc(7) processing significantly, but it also
has an undesired (in this case) effect of disabling hyphenation within the
entire enclosed block.
errexit (-e) processing. This solves a problem where 'make clean' would
fail with an unspecified error in certain automake-generated makefiles.
Reviewed by: no objections from -hackers...
MFC after: 2 weeks
When a child is receiving SIGSTOP, eval continues with the next
command. While that is correct for the interactive case (Control-Z
and you get the prompt back), it is wrong for a shellscript, which
just continues with the next command, never again waiting for the
stopped child. Noted when childs from cronjobs were stopped, just to
make more processes (by wosch).
The fix is not to return from a job wait when the wait returned for a
stopped child while in non-interactive mode. This bahaviour seems to
be what bash2 and ksh implement. I tested for correct behaviour for
finnaly killing the child with and without forgrounding it first.
When not foregrouding before killing, the shell continues with the
script, which is what the other shells do as well.
Reviewed by: Silence on -current
Serious fix still needed, see discussion on -current
(Subject: /bin/sh dumps core with here-document of 8bit text)
Problem in this code originally spotted by
Jun Kuriyama <kuriyama@FreeBSD.org>
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().
PR: bin/19983
Submitted by: Tor.Egge@fast.no
Reviewed by: Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
case), so that it doesn't clash with the ncurses function of the same
name when linking statically with -ltermcap.
The linker only complains when -static is used, and it is not clear
whether this is a bug.
PR: bin/18104
Submitted by: Anatoly Vorobey <mellon@pobox.com>
spaces reserved by the header files it includes.
mkinit.c still produces C code with redundant declarations, although
they are more harmless since they automatically derived from the right
places.
in that revision as well as things I broke in that revision. A note-
worthy instance of the latter case was the inversion of -E and -V in the
subsection on Commandline Editing.
than two processes (got that? :-), the stdin fd of the middle
processes that has just been set up was accidetially closed. Don't do
this.
PR: bin/14527
commit and those which cause ugly nroff output have been fixed, since
the purpose of the style guideline which they contravene is to reduce
the sizes of deltas.
Reported by: bde
* Consistently misspell built-in as builtin.
* Add a builtin(1) manpage and create builtin(1) MLINKS for all shell
builtin commands for which no standalone utility exists. These MLINKS
replace those that were created for csh(1).
* Add appropriate xrefs for builtin(1) to the csh(1) and sh(1) manpages,
as well as to the manpages of standalone utilities which are supported
as shell builtin commands in at least one of the shells. In such
manpages, explain that similar functionality may be provided as a
shell builtin command.
* Improve sh(1)'s description of the cd builtin command. Csh(1) already
describes it adequately. Replace the cd(1) manpage with a builtin(1)
MLINKS link.
* Clean up some mdoc problems: use Xr instead of literal "foo(n)"; use
Ic instead of Xr for shell builtin commands.
* Undo English contractions.
Reviewed by: mpp, rgrimes
Fix grammar and spelling nits.
Use .Dq and .Qq where appropriate.
Divorce trailing punctuation from quoted elements.
Use .Dq instead of .Xr for builtins.
Remove trailing whitespace and blank lines.
PR: 13340
statement if blocks[*] when the else could be ambiguous, not defaulting
to int type and removal of some unused variables.
[*] This is explicitly allowed by style(9) when the single statement
spans more than one line.
Reviewed by: obrien, chuckr
representation of the expression is quoted. Take care of this when
doing pattern matching in conjunction with trimming.
#!/bin/sh
c=d:e; echo "${c%:e}"
PR: NetBSD PR#7231
Noticed by: Havard Eidnes <Havard.Eidnes@runit.sintef.no>
make /etc/rc interruptible in cases when programs hang with blocked
signals) isn't standard enough.
It is now switched off by default and a new switch -T enables it.
You should update /etc/rc to the version I'm about to commit in a few
minutes to keep it interruptible.
Don't output double-quotes inside variable expansion/arithmetic
expansion region in here-documents. When leaving the arithmetic
expansion syntax mode, adjust the dblquote flag according to
previous syntax, in order to avoid splitting of quoted variables.
foreground child is running. Formerly, traps were exceuted after the
next child exit.
The enables the user to put a breaking wrapper around a blocking
application:
(trap 'echo trap ; exit 1' 2; ./pestyblocker; echo -n)
The "echo -n" after the child call is needed to prevent sh from
optimizing the trap-executing shell away. I'm working on this.
multiple times when performing nested variable expansion, and
preserve some quoting information in order to avoid removing
apparently empty expansion result.