Commit Graph

816 Commits

Author SHA1 Message Date
jilles
6672b66ab7 sh: Track if the current locale's charset is UTF-8 or not. 2011-05-06 22:31:27 +00:00
jilles
e4f71c5640 sh: Change the CTL* bytes to ones invalid in UTF-8.
This ensures that mbrtowc(3) can be used directly once it has been verified
that there is no CTL* byte. Dealing with a CTLESC byte within a multibyte
character would be complicated.

The new values do occur in iso-8859-* encodings. This decreases efficiency
slightly but should not affect correctness.

Caveat: Updating across this change and rebuilding without cleaning may
yield a subtly broken sh binary. By default, make buildworld will clean and
avoid problems.
2011-05-06 20:45:50 +00:00
jilles
5a49f52603 sh: Add $'quoting' (C-style escape sequences).
A string between $' and ' may contain backslash escape sequences similar to
the ones in a C string constant (except that a single-quote must be escaped
and a double-quote need not be). Details are in the sh(1) man page.

This construct is useful to include unprintable characters, tabs and
newlines in strings; while this can be done with a command substitution
containing a printf command, that needs ugly workarounds if the result is to
end with a newline as command substitution removes all trailing newlines.

The construct may also be useful in future to describe unprintable
characters without needing to write those characters themselves in 'set -x',
'export -p' and the like.

The implementation attempts to comply to the proposal for the next issue of
the POSIX specification. Because this construct is not in POSIX.1-2008,
using it in scripts intended to be portable is unwise.

Matching the minimal locale support in the rest of sh, the \u and \U
sequences are currently not useful.

Exp-run done by: pav (with some other sh(1) changes)
2011-05-05 20:55:55 +00:00
jilles
ba0d29571f sh: Apply set -u to variables in arithmetic.
Note that this only applies to variables that are actually used.
Things like (0 && unsetvar) do not cause an error.

Exp-run done by: pav (with some other sh(1) changes)
2011-05-04 22:12:22 +00:00
jilles
fa0f3c42ef sh: Detect an error for ${#var<GARBAGE>}.
In particular, this makes things like ${#foo[0]} and ${#foo[@]} errors
rather than silent equivalents of ${#foo}.

PR:		bin/151720
Submitted by:	Mark Johnston
Exp-run done by: pav (with some other sh(1) changes)
2011-05-04 21:49:34 +00:00
jilles
7b50330e01 sh: Set $? to 0 for background commands.
For backgrounded pipelines and subshells, the previous value of $? was being
preserved, which is incorrect.

For backgrounded simple commands containing a command substitution, the
status of the last command substitution was returned instead of 0.

If fork() fails, this is an error.
2011-04-25 20:54:12 +00:00
jilles
836a99923b sh: Check setuid()/setgid() return values.
If the -p option is turned off, privileges from a setuid or setgid binary
are dropped. Make sure to check if this succeeds. If it fails, this is an
error which will cause the shell to abort except in interactive mode or if
'command' was used to make 'set' or an outer 'eval' or '.' non-special.

Note that taking advantage of this feature and writing setuid shell scripts
seems unwise.

MFC after:	1 week
2011-04-25 10:14:29 +00:00
jilles
54847e6220 sh: Remove duplicate code resetting uid/gid for set +p/+o privileged.
MFC after:	1 week
2011-04-25 10:08:34 +00:00
jilles
f250dc2f44 sh: Allow EV_EXIT through function calls, make {...} <redir more consistent.
If EV_EXIT causes an exit, use the exception mechanism to unwind
redirections and local variables. This way, if the final command is a
redirected command, an EXIT trap now executes without the redirections.

Because of these changes, EV_EXIT can now be inherited by the body of a
function, so do so. This means that a function no longer prevents a fork
before an exec being skipped, such as in
  f() { head -1 /etc/passwd; }; echo $(f)

Wrapping a single builtin in a function may still cause an otherwise
unnecessary fork with command substitution, however.

An exit command or -e failure still invokes the EXIT trap with the
original redirections and local variables in place.

Note: this depends on SHELLPROC being gone. A SHELLPROC depended on
keeping the redirections and local variables and only cleaning up the
state to restore them.
2011-04-23 22:28:56 +00:00
jilles
1347144ea4 sh: Do not word split "${#parameter}".
This is only a problem if IFS contains digits, which is unusual but valid.

Because of an incorrect fix for PR bin/12137, "${#parameter}" was treated
as ${#parameter}. The underlying problem was that "${#parameter}"
erroneously added CTLESC bytes before determining the length. This
was properly fixed for PR bin/56147 but the incorrect fix was not backed
out.

Reported by:	Seeker on forums.freebsd.org
MFC after:	2 weeks
2011-04-20 22:24:54 +00:00
jilles
f4c860e408 sh(1): Describe subshell environment, command substitution more correctly.
POSIX does not require the shell to fork for a subshell environment, and we
use that possibility in various ways (command substitutions with a single
command and most subshells that are the final command of a shell process).
Therefore do not tie subshells to forking in the man page.

Command substitutions with expansions are a bit strange, causing a fork for
$(...$(($x))...) because $x might expand to y=2; they will probably be
changed later but this is how they work now.
2011-03-20 23:52:45 +00:00
jilles
161663c247 sh: Fix some parameter expansion variants ${#...}.
These already worked: $# ${#} ${##} ${#-} ${#?}
These now work as well: ${#+word} ${#-word} ${##word} ${#%word}

There is an ambiguity in the standard with ${#?}: it could be the length of
$? or it could be $# giving an error in the (impossible) case that it is not
set. We continue to use the former interpretation as it seems more useful.
2011-03-13 20:02:39 +00:00
stefanf
0d4be9304a Remove unnecessary cast.
Reviewed by:	jilles
2011-03-07 07:31:15 +00:00
jilles
75dda0ff36 sh(1): Reduce excessive semicolon-separated sentences.
Reported by:	Benjamin Kaduk
2011-03-06 21:20:53 +00:00
jilles
1a2c2ccf00 sh: Fix some warnings in code for arithmetic expressions.
Submitted by:	eadler
2011-03-05 13:27:13 +00:00
brucec
6d9b42b486 Fix typos - remove duplicate "the".
PR:	bin/154928
Submitted by:	Eitan Adler <lists at eitanadler.com>
MFC after: 	3 days
2011-02-21 09:01:34 +00:00
jilles
2fb0603686 sh: Detect dividing the smallest integer by -1.
This overflows and on some architectures such as amd64 it generates SIGFPE.
Generate an error on all architectures.
2011-02-12 23:44:05 +00:00
jilles
a0549c0f22 sh(1): Update description of arithmetic. 2011-02-08 23:19:40 +00:00
jilles
1cbab8a321 sh: Import arithmetic expression code from dash.
New features:
* proper lazy evaluation of || and &&
* ?: ternary operator
* executable is considerably smaller (8K on i386) because lex and yacc are
  no longer used

Differences from dash:
* arith_t instead of intmax_t
* imaxdiv() not used
* unset or null variables default to 0
* let/exp builtin (undocumented, will probably be removed later)

Obtained from:	dash
2011-02-08 23:18:06 +00:00
jilles
ff6aee65ce sh: Fix two things about {(...)} <redir:
* In {(...) <redir1;} <redir2, do not drop redir1.
* Maintain the difference between (...) <redir and {(...)} <redir:
  In (...) <redir, the redirection is performed in the child, while in
  {(...)} <redir it should be performed in the parent (like {(...); :;}
  <redir)
2011-02-05 15:02:19 +00:00
jilles
9a75a8c404 sh: Remove clearcmdentry()'s now unused argument. 2011-02-05 14:08:51 +00:00
jilles
852a80acf7 sh: Forget all cached command locations on any PATH change.
POSIX requires this and it is simpler than the previous code that remembered
command locations when appending directories to PATH.

In particular,
  PATH=$PATH
is no longer a no-op but discards all cached command locations.
2011-02-05 14:01:46 +00:00
jilles
a81357fbe9 sh: Do not try to execute binary files as scripts.
If execve() returns an [ENOEXEC] error, check if the file is binary before
trying to execute it using sh. A file is considered binary if at least one
of the first 256 bytes is '\0'.

In particular, trying to execute ELF binaries for the wrong architecture now
fails with an "Exec format error" message instead of syntax errors and
potentially strange results.
2011-02-05 12:54:59 +00:00
jilles
95ad413d4a sh: Remove special code for shell scripts without magic number.
These are called "shell procedures" in the source.

If execve() failed with [ENOEXEC], the shell would reinitialize itself
and execute the program as a script. This requires a fair amount of code
which is not frequently used (most scripts have a #! magic number).
Therefore just execute a new instance of sh (_PATH_BSHELL) to run the
script.
2011-02-04 22:47:55 +00:00
jilles
dbecc33067 Make sys_signame upper case.
This matches the constants from <signal.h> with 'SIG' removed, which POSIX
requires kill and trap to accept and 'kill -l' to write.

'kill -l', 'trap', 'trap -l' output is now upper case.

In Turkish locales, signal names with an upper case 'I' are now accepted,
while signal names with a lower case 'i' are no longer accepted, and the
output of 'killall -l' now contains proper capital 'I' without dot instead
of a dotted capital 'I'.
2011-02-04 16:40:50 +00:00
jilles
86ccb3f9c0 sh: Return only 126 or 127 for execve() failures.
Do not return 2 for errors other than [EACCES] or [ENOENT].
2011-02-03 23:38:11 +00:00
jilles
e252925aeb sh: Remove comment mentioning herefd, which is gone. 2011-02-02 21:48:53 +00:00
jilles
8605caacbf sh: Send messages about signals to stderr.
This is required by POSIX and seems to make more sense.

See also r217557.
2011-01-30 22:57:52 +00:00
jilles
a123f0aac0 sh: Clean up some old comments:
* There is no plan for an alternative to the command "set".
* Attempting to unset a readonly variable has not raised an error for quite
  a while, so the order of unsetting a variable and a function with the same
  name does not matter.

MFC after:	1 week
2011-01-25 20:56:18 +00:00
jilles
460d7b088e sh: Fix signal messages being sent to the wrong file sometimes.
When a foreground job exits on a signal, a message is printed to stdout
about this. The buffer was not flushed after this which could result in the
message being written to the wrong file if the next command was a builtin
and had stdout redirected.

Example:
  sh -c 'kill -9 $$'; : > foo; echo FOO:; cat foo

Reported by:	gcooper
MFC after:	1 week
2011-01-18 21:18:31 +00:00
jilles
48fcfccda6 sh(1): Document changes to 'exit' from traps. 2011-01-16 14:11:50 +00:00
jilles
3967e15d57 sh: If exit is used without args from a trap action, exit on the signal.
This is useful so that it is easier to exit on a signal than to reset the
trap to default and resend the signal. It matches ksh93. POSIX says that
'exit' without args from a trap action uses the exit status from the last
command before the trap, which is different from 'exit $?' and matches this
if the previous command is assumed to have exited on the signal.

If the signal is SIGSTOP, SIGTSTP, SIGTTIN or SIGTTOU, or if the default
action for the signal is to ignore it, a normal _exit(2) is done with exit
status 128+signal_number.
2011-01-16 13:56:41 +00:00
jilles
31120cf045 sh: Fix some things about -- in trap:
* Make 'trap --' do the same as 'trap' instead of nothing.
* Make '--' stop option processing (note that '-' action is not an option).

Side effect: The error message for an unknown option is different.
2011-01-15 21:09:00 +00:00
jilles
085a83f669 sh: Make 'trap -l' look like 'kill -l'. 2011-01-14 21:30:27 +00:00
jilles
ebbca2a885 sh: Follow-up to r216743, grabstackblock() can be replaced with stalloc().
grabstackblock() was used only once (but it is a very often executed piece
of code).
2011-01-09 22:47:58 +00:00
jilles
2a782244a9 sh: Remove special %builtin PATH entry.
All builtins are now always found before a PATH search.

Most ash derivatives have an undocumented feature where the presence of an
entry "%builtin" in $PATH will cause builtins to be checked at that point of
the PATH search, rather than before looking at any directories as documented
in the man page (very old versions do document this feature).

I am removing this feature from sh, as it complicates the code, may violate
expectations (for example, /usr/bin/alias is very close to a forkbomb with
PATH=/usr/bin:%builtin, only /usr/bin/builtin not being another link saves
it) and appears to be unused (all the %builtin google code search finds is
in some sort of ash source code).

Note that aliases and functions took and take precedence above builtins.
Because aliases work on a lexical level they can only ever be overridden on
a lexical level (quoting or preceding 'builtin' or 'command'). Allowing
override of functions via PATH does not really fit in the model of sh and it
would work differently from %builtin if implemented.

Note: POSIX says special builtins are found before functions. We comply to
this because we do not allow functions with the same name as a special
builtin.

Silence from:	freebsd-hackers@ (message sent 20101225)
Discussed with:	dougb
2011-01-09 21:07:30 +00:00
jilles
3a61afec3c sh: Make exit without parameters from EXIT trap POSIX-compliant.
It should use the original exit status, just like falling off the
end of the trap handler.

Outside an EXIT trap, 'exit' is still equivalent to 'exit $?'.
2011-01-08 23:08:13 +00:00
jilles
3c4cff0f35 sh: Do not call exitshell() from evalcommand() unless evalcommand() forked
itself.

This ensures that certain traps caused by builtins are executed.
2011-01-05 23:17:29 +00:00
jilles
9391068711 sh: Check readonly status for assignments on regular builtins.
An error message is written, the builtin is not executed, nonzero exit
status is returned but the shell does not abort.

This was already checked for special builtins and external commands, with
the same consequences except that the shell aborts for special builtins.

Obtained from:	NetBSD
2011-01-01 13:26:18 +00:00
jilles
e3df947be8 sh: Check if dup2 for redirection from/to a file succeeds.
A failure (e.g. caused by ulimit -n being set very low) is a redirection
error.

Example:
  ulimit -n 9; exec 9<.
2010-12-31 18:20:17 +00:00
jilles
ca3118f4ca sh: Avoid side effects from builtins in optimized command substitution.
Change the criterion for builtins to be safe to execute in the same process
in optimized command substitution from a blacklist of only cd, . and eval to
a whitelist.

This avoids clobbering the main shell environment such as by $(exit 4) and
$(set -x).

The builtins jobid, jobs, times and trap can still show information not
available in a child process; this is deliberately permitted. (Changing
traps is not.)

For some builtins, whether they are safe depends on the arguments passed to
them. Some of these are always considered unsafe to keep things simple; this
only harms efficiency a little in the rare case they are used alone in a
command substitution.
2010-12-30 22:33:55 +00:00
jilles
584bccb74d sh: Properly restore exception handler in fc.
If SIGINT arrived at exactly the right moment (unlikely), an exception
handler in a no longer active stack frame would be called.

Because the old handler was not used in the normal path, clang thought it
was a dead value and if an exception happened it would longjmp() to garbage.
This caused builtins/fc1.0 to fail if histedit.c was compiled with clang.

MFC after:	1 week
2010-12-29 19:39:51 +00:00
jilles
74d9b02bb0 sh: Don't do optimized command substitution if expansions have side effects.
Before considering to execute a command substitution in the same process,
check if any of the expansions may have a side effect; if so, execute it in
a new process just like happens if it is not a single simple command.

Although the check happens at run time, it is a static check that does not
depend on current state. It is triggered by:
- expanding $! (which may cause the job to be remembered)
- ${var=value} default value assignment
- assignment operators in arithmetic
- parameter substitutions in arithmetic except ${#param}, $$, $# and $?
- command substitutions in arithmetic

This means that $((v+1)) does not prevent optimized command substitution,
whereas $(($v+1)) does, because $v might expand to something containing
assignment operators.

Scripts should not depend on these exact details for correctness. It is also
imaginable to have the shell fork if and when a side effect is encountered
or to create a new temporary namespace for variables.

Due to the $! change, the construct $(jobs $!) no longer works. The value of
$! should be stored in a variable outside command substitution first.
2010-12-28 21:27:08 +00:00
jilles
713ef02a1f sh: Make expansion errors in optimized command substitution non-fatal.
Command substitutions consisting of a single simple command are executed in
the main shell process but this should be invisible apart from performance
and very few exceptions such as $(trap).
2010-12-28 13:28:24 +00:00
jilles
f6812a9bf2 sh: Simplify "stack string" code slightly.
Maintain a pointer to the end of the stack string area instead of how much
space is left. This simplifies the macros in memalloc.h. The places where
the new variable must be updated are only where the memory area is created,
destroyed or resized.
2010-12-27 22:18:27 +00:00
jilles
e1ab1f8c3c sh: Fix integer overflow check, it checked an uninitialized variable. 2010-12-26 13:41:53 +00:00
jilles
de73f385a5 sh: Allow arbitrary large numbers in CHECKSTRSPACE.
Reduce "stack string" API somewhat and simplify code.
Add a check for integer overflow of the "stack string" length (probably
incomplete).
2010-12-26 13:25:47 +00:00
jilles
dbd8131dd6 sh(1): Explain why it is a bad idea to use aliases in scripts. 2010-12-21 22:48:56 +00:00
jilles
ae2aabc349 sh: Add kill builtin.
This allows specifying a %job (which is equivalent to the corresponding
process group).

Additionally, it improves reliability of kill from sh in high-load
situations and ensures "kill" finds the correct utility regardless of PATH,
as required by POSIX (unless the undocumented %builtin mechanism is used).

Side effect: fatal errors (any error other than kill(2) failure) now return
exit status 2 instead of 1. (This is consistent with other sh builtins, but
not in NetBSD.)

Code size increases about 1K on i386.

Obtained from:	NetBSD
2010-12-21 22:47:34 +00:00
jilles
eb00352e45 sh: Add a function to print warnings (with command name and newline).
This is like error() but without raising an exception.
It is particularly useful as a replacement for the warnx macro in
bltin/bltin.h.
2010-12-21 20:47:06 +00:00
jilles
ccc4611f77 sh: Make warnings in the printf builtin non-fatal, like in the program.
The #define for warnx now behaves much like the libc function (except that
it uses sh command name and output).

Also, it now uses C99 __VA_ARGS__ so there is no need for three different
macros for 0, 1 or 2 parameters.
2010-12-20 23:06:57 +00:00
jilles
84941f8297 sh: arith: Disallow decimal constants starting with 0 (containing 8 or 9).
Constants in arithmetic starting with 0 should be octal only.

This avoids the following highly puzzling result:
  $ echo $((018-017))
  3
by making it an error instead.
2010-12-18 23:03:51 +00:00
uqs
bd917baec5 Remove dead code.
c is assigned 0 and *loc is pointing to NULL, so c!=0 cannot be true,
and dereferencing loc would be a bad idea anyway.

Coverity Prevent:	CID 5113
Reviewed by:		jilles
2010-12-18 22:16:15 +00:00
jilles
da5b058d1d sh: Fix corruption of command substitutions with special chars after newline
The CTLESC byte to protect a special character was output before instead of
after a newline directly preceding the special character.

The special handling of newlines is because command substitutions discard
all trailing newlines.
2010-12-16 23:28:20 +00:00
uqs
889baffc86 Remove duplicate check, turning dead code into live code.
Coverity CID:	5114
Reviewed by:	jilles
2010-12-13 10:48:49 +00:00
jilles
9624ca1479 sh: Various simplifications to jobs.c:
* Prefer kill(-X) to killpg(X).
* Remove some dead code.
* No additional SIGINT is needed if int_pending() is already true.

No functional change is intended.
2010-12-12 22:59:34 +00:00
jilles
9daf74d4c8 sh: Remove the herefd hack.
The herefd hack wrote out partial here documents while expanding them. It
seems unnecessary complication given that other expansions just allocate
memory. It causes bugs because the stack is also used for intermediate
results such as arithmetic expressions. Such places should disable herefd
for the duration but not all of them do, and I prefer removing the need for
disabling herefd to disabling it everywhere needed.

Here documents larger than 1024 bytes will use a bit more CPU time and
memory.

Additionally this allows a later change to expand here documents in the
current shell environment. (This is faster for small here documents but also
changes behaviour.)

Obtained from:	dash
2010-12-12 00:07:27 +00:00
jilles
9f0c118349 sh: Replace some macros and repeated code in expand.c with functions.
No functional change is intended, but the binary is about 1K smaller on
i386.
2010-12-11 22:13:29 +00:00
jilles
353bb2f73a sh: Use vsnprintf() rather than crafting our own in fmtstr().
Add INTOFF/INTON as longjmp out of vsnprintf may cause memory leaks or
undefined behaviour.
2010-12-11 17:47:27 +00:00
jilles
83a1280f2b sh: Improve internal-representation-to-text code to avoid binary output.
The code to translate the internal representation to text did not know about
various additions to the internal representation since the original ash and
therefore wrote binary stuff to the terminal.

The code is used in the jobs command and similar output.

Note that the output is far from complete and mostly serves for recognition
purposes.
2010-12-06 23:49:27 +00:00
jilles
0c87a741dc sh: POSIX says there should not be a space between Done and (exitstatus).
(On the other hand, (core dumped) does need a space and so does [1] +.)
2010-12-05 22:56:46 +00:00
jilles
91e61ea9fc sh: Improve jobs output of pipelines.
If describing the status of a pipeline, write all elements of the pipeline
and show the status of the last process (which would also end up in $?).
Only write one report per job, not one for every process that exits.

To keep some earlier behaviour, if any process started by the shell in a
foreground job terminates because of a signal, write a message about the
signal (at most one message per job, however).

Also, do not write messages about signals in the wait builtin in
non-interactive shells. Only true foreground jobs now write such messages
(for example, "Terminated").
2010-12-05 22:37:01 +00:00
jilles
506e81b852 sh: Avoid marking a job as done before it is fully created.
In r208489, I added code to reap zombies when forking new processes, to
limit the amount of zombies. However, this can lead to marking a job as done
or stopped if it consists of multiple processes and the first process ends
very quickly. Fix this by only checking for zombies before forking the first
process of a job and not marking any jobs without processes as done or
stopped.
2010-12-05 21:53:29 +00:00
jilles
81a44f4bf1 sh: jobs -p: Do not ask the kernel for the pgid.
The getpgid() call will fail if the first process in the job has already
terminated, resulting in output of "-1".

The pgid of a job is always the pid of the first process in the job and
other code already relies on this.
2010-12-05 16:09:03 +00:00
jilles
c042df181c sh(1): Clean up documentation of built-in commands.
Make sure all built-in commands are in the subsection named such, except
exp, let and wordexp which are deliberately undocumented. The text said only
built-ins that really need to be a built-in were documented there but in
fact almost all of them were already documented.
2010-12-03 23:24:27 +00:00
jilles
67c1c79555 sh(1): Document that command's -p option also works with -v/-V.
This was implemented in r201343.
2010-12-01 23:26:32 +00:00
jilles
7377de8f91 sh: Code size optimizations to "stack string" memory allocation:
* Prefer one CHECKSTRSPACE with multiple USTPUTC to multiple STPUTC.
* Add STPUTS macro (based on function) and use it instead of loops that add
  nul-terminated strings to the stack string.

No functional change is intended, but code size is about 1K less on i386.
2010-11-23 22:17:39 +00:00
jilles
2ece5375f3 sh: Pass multiple bytes at a time to lex.
This speeds up the expansion/arith6.0 test considerably.
2010-11-23 20:46:06 +00:00
jilles
31d53d7f22 sh: Fix confusing behaviour if chdir succeeded but getcwd failed in cd -P.
If getcwd fails, do not treat this as an error, but print a warning and
unset PWD. This is similar to the behaviour when starting the shell in a
directory whose name cannot be determined.
2010-11-22 23:49:06 +00:00
brucec
621e6d10d8 Fix some more warnings found by clang. 2010-11-22 20:10:48 +00:00
jilles
2bd9940d99 sh: Remove the check that alpha/name/in_name chars are not CTL* bytes.
Since is_alpha/is_name/is_in_name were made ASCII-only, this can no longer
happen.

Additionally, the check was wrong because it did not include the new
CTLQUOTEEND.
2010-11-20 14:30:28 +00:00
jilles
6915411ab2 sh: Code size optimizations to buffered output.
This is mainly less use of the outc macro.

No functional change is intended, but code size is about 2K less on i386.
2010-11-20 14:14:52 +00:00
jilles
129853101d sh: Add printf builtin.
This was removed in 2001 but I think it is appropriate to add it back:
* I do not want to encourage people to write fragile and non-portable echo
  commands by making printf much slower than echo.
* Recent versions of Autoconf use it a lot.
* Almost no software still wants to support systems that do not have
  printf(1) at all.
* In many other shells printf is already a builtin.

Side effect: printf is now always the builtin version (which behaves
identically to /usr/bin/printf) and cannot be overridden via PATH (except
via the undocumented %builtin mechanism).

Code size increases about 5K on i386. Embedded folks might want to replace
/usr/bin/printf with a hard link to /usr/bin/alias.
2010-11-19 12:56:13 +00:00
jilles
808b93da2e sh: Add binary buffered output for use by the printf builtin. 2010-11-14 15:31:59 +00:00
jilles
5ca0de0e3f sh: Update the suspend example for the change of the job control flag
from -j to -m, many years ago.

Due to r215266, this function now actually works.
2010-11-13 22:20:46 +00:00
jilles
f9809fb862 sh: Do the additional actions if 'local -' restore changes -i/-m/-E/-V.
Example:
  f() { local -; set +m; }; f
caused failure to execute external programs because the job control tty fd
was not opened.
2010-11-13 22:10:26 +00:00
jilles
e1c3452023 sh(1): Document r214304 (special builtin is illegal function name). 2010-11-12 22:40:18 +00:00
jilles
b057fb40bb sh(1): Update for r214492. "${v+"hi}there"}".
The part hi}there is not a quoted string but nevertheless the closing brace
does not terminate the expansion.
2010-11-12 22:28:47 +00:00
jilles
4de33564ff sh: Remove unused man page for echo builtin.
The information in sh(1) about the echo builtin is equivalent, though less
extensive.

The echo(1) man page (bin/echo/echo.1) is different.

Unfortunately, sh's echo builtin and /bin/echo have gone out of sync and
this probably cannot be fixed any more.

Reported by:	uqs (list of untouched files)
MFC after:	1 week
2010-11-12 15:40:00 +00:00
jilles
f2e6568807 sh(1): Modernize the introduction a bit.
In particular, remove the text about ksh-like features, which are usually
taken for granted nowadays. The original Bourne shell is fading away and for
most users our /bin/sh is one of the most minimalistic they know.
2010-11-12 14:40:20 +00:00
jilles
000173def6 sh: Fix some issues with aliases and case, by importing dash checkkwd code.
This moves the function of the noaliases variable into the checkkwd
variable. This way it is properly reset on errors and aliases can be used
normally in the commands for each case (the case labels recognize the
keyword esac but no aliases).

The new code is clearer as well.

Obtained from:	dash
2010-11-02 23:44:29 +00:00
jilles
26a6f9d45c sh(1): Correct synopsis and make precise how $0 is set.
In particular, the extra argument to set $0 with -c was not documented.

MFC after:	1 week
2010-10-31 23:03:11 +00:00
jilles
1685738e37 sh: Reindent evaltree(). 2010-10-31 12:08:16 +00:00
jilles
4de067d3c2 sh: Use iteration instead of recursion to evaluate semicolon lists.
This reduces CPU and memory usage when executing long lists (such
as long functions).
2010-10-31 12:06:02 +00:00
jilles
2ae15286ba sh: Tweak some string constants to reduce code size.
* Reduce some needless differences.
* Shorten some error messages that should not happen.
2010-10-29 21:44:43 +00:00
jilles
038f244ca5 sh: Reject function names ending in one of !%*+-=?@}~
These do something else in ksh: name=(...) is an array or compound variable
assignment and the others are extended patterns.

This is the last patch of the ones tested in the exp run.

Exp-run done by:	pav (with some other sh(1) changes)
2010-10-29 21:20:56 +00:00
jilles
f98d5a366d sh: Detect various additional errors in the parser.
Apart from detecting breakage earlier or at all, this also fixes a segfault
in the testsuite. The "handling" of the breakage left an invalid internal
representation in some cases.

Examples:
  echo a; do echo b
  echo `) echo a`
  echo `date; do do do`

Exp-run done by:	pav (with some other sh(1) changes)
2010-10-29 21:06:57 +00:00
jilles
b6e7fcf97b sh: Error out on various specials/keywords in the wrong place in backticks.
Example:
  echo `date)`

Exp-run done by:	pav (with some other sh(1) changes)
Obtained from:		NetBSD (Christos Zoulas, NetBSD PR 11317)
2010-10-29 20:23:41 +00:00
jilles
aaa3347e35 sh: Fix some issues with CTL* bytes and ${var#pat}.
subevalvar() incorrectly assumed that CTLESC bytes were present iff the
expansion was quoted. However, they are present iff various processing such
as word splitting is to be done later on.

Example:
  v=@$e@$e@$e@
  y="${v##*"$e"}"
  echo "$y"
failed if $e contained the magic CTLESC byte.

Exp-run done by:	pav (with some other sh(1) changes)
2010-10-29 19:34:57 +00:00
jilles
28ad180ab4 sh: Do IFS splitting on word in ${v+word} and ${v-word}.
The code is inspired by NetBSD sh somewhat, but different because we
preserve the old Almquist/Bourne/Korn ability to have an unquoted part in a
quoted ${v+word}. For example, "${v-"*"}" expands to $v as a single field if
v is set, but generates filenames otherwise.

Note that this is the only place where we split text literally from the
script (the similar ${v=word} assigns to v and then expands $v). The parser
must now add additional markers to allow the expansion code to know whether
arbitrary characters in substitutions are quoted.

Example:
  for i in ${$+a b c}; do echo $i; done

Exp-run done by:	pav (with some other sh(1) changes)
2010-10-29 13:42:18 +00:00
jilles
6f54496b16 sh: Only accept a '}' inside ${v+-=?...} if double-quote state matches.
If double-quote state does not match, treat the '}' literally.

This ensures double-quote state remains the same before and after a
${v+-=?...} which helps with expand.c.

It makes things like
  ${foo+"\${bar}"}
which I have seen in the wild work as expected.

Exp-run done by:	pav (with some other sh(1) changes)
2010-10-28 22:34:49 +00:00
jilles
8e66c8e658 sh: Make double-quotes quote a '}' inside ${v#...} and ${v%...}.
Exp-run done by:	pav (with some other sh(1) changes)
PR:			bin/57554
2010-10-28 21:51:14 +00:00
jilles
51f0756257 sh: Ignore double-quotes in arithmetic rather than treating them as quotes.
This provides similar behaviour, but allows a simpler parser.

This changes r206473.

Exp-run done by:	pav (with some other sh(1) changes)
2010-10-24 22:25:38 +00:00
jilles
58038d3e9e sh: Do not allow overriding a special builtin with a function.
This is a syntax error.

POSIX does not say explicitly whether defining a function with the same name
as a special builtin is allowed, but it does say that it is impossible to
call such a function.

A special builtin can still be overridden with an alias.

This commit is part of a set of changes that will ensure that when
something looks like a special builtin to the parser, it is one. (Not the
other way around, as it remains possible to call a special builtin named
by a variable or other substitution.)

Exp-run done by:	pav (with some other sh(1) changes)
2010-10-24 22:03:21 +00:00
jilles
e5f0dbf76c sh: Make sure defined functions can actually be called.
Add some conservative checks on function names:
- Disallow expansions or quoting characters; these can only be called via
  strange control characters
- Disallow '/'; these functions cannot be called anyway, as exec.c assumes
  they are pathnames
- Make the CTL* bytes work properly in function names.

These are syntax errors.

POSIX does not require us to support more than names (letters, digits and
underscores, not starting with a digit), but I do not want to restrict it
that much at this time.

Exp-run done by:	pav (with some other sh(1) changes)
2010-10-24 20:45:13 +00:00
jilles
c487e17b8f sh: Check whether dup2 was successful for >&FD and <&FD.
A failure (usually caused by FD not being open) is a redirection error.

Exp-run done by:	pav (with some other sh(1) changes)
2010-10-24 20:09:49 +00:00
jilles
ba204fa87e sh: Change ! within a pipeline to start a new pipeline instead.
This is how ksh93 treats ! within a pipeline and makes the ! in
  a | ! b | c
negate the exit status of the pipeline, as if it were
  a | { ! b | c; }

Side effect: something like
  f() ! a
is now a syntax error, because a function definition takes a command,
not a pipeline.

Exp-run done by:	pav (with some other sh(1) changes)
2010-10-24 17:06:49 +00:00
jilles
1b1731a557 sh(1): Clarify subshells/processes for pipelines.
For multi-command pipelines,
1. all commands are direct children of the shell (unlike the original
   Bourne shell)
2. all commands are executed in a subshell (unlike the real Korn shell)

MFC after:	1 week
2010-10-16 14:37:56 +00:00
jilles
f8700ae02e sh: Use <stddef.h> rather than <sys/stddef.h>.
<sys/stddef.h> is only for the kernel and conflicts with <stddef.h>.
2010-10-16 12:40:00 +00:00
obrien
2eebff9052 We only need to look as far as '..' to find 'test/'. 2010-10-13 23:31:17 +00:00
obrien
0402932766 Do not assume in growstackstr() that a "precious" character will be
immediately written into the stack after the call.  Instead let the caller
manage the "space left".

Previously, growstackstr()'s assumption causes problems with STACKSTRNUL()
where we want to be able to turn a stack into a C string, and later
pretend the NUL is not there.

This fixes a bug in STACKSTRNUL() (that grew the stack) where:
1. STADJUST() called after a STACKSTRNUL() results in an improper adjust.
   This can be seen in ${var%pattern} and ${var%%pattern} evaluation.
2. Memory leak in STPUTC() called after a STACKSTRNUL().

Reviewed by:	jilles
2010-10-13 23:29:09 +00:00
obrien
08b8d916b5 In the spirit of r90111, depend on c89 and remove the "STATIC" macro
and its usage.
2010-10-13 22:18:03 +00:00
obrien
58aac0183d If one wishes to set breakpoints of static the functions here, they
cannot be inlined.

Submitted by:	jhb
2010-10-13 18:23:43 +00:00
jhb
ec1e5e05cc Make DEBUG traces 64-bit clean:
- Use %t to print ptrdiff_t values.
- Cast a ptrdiff_t value explicitly to int for a field width specifier.

While here, sort includes.

Submitted by:	Garrett Cooper
2010-10-13 13:22:11 +00:00
jhb
630d6005f9 Suggest that DEBUG_FLAGS be used to enable extra debugging rather than
frobbing CFLAGS directly.  DEBUG_FLAGS is something that can be specified
on the make command line without having to edit the Makefile directly.

Submitted by:	Garrett Cooper
2010-10-13 13:17:38 +00:00
obrien
f31ad1c86b Consistently use "STATIC" for all functions in order to be able to set
breakpoints with in a debugger.  And use naked "static" for variables.

Noticed by:	bde
2010-10-13 04:01:01 +00:00
obrien
93c40b656a If DEBUG is 3 or greater, disable STATICization of functions.
Also correct the documented location of the trace file.
2010-10-12 19:24:41 +00:00
obrien
5289908373 Allow one to regression test 'sh' changes without having to install
a potentially bad /bin/sh first.
2010-10-12 18:20:38 +00:00
jilles
dc327c8b4d sh: Add __dead2 to two functions that do not return.
Apart from helping static analyzers, this also appears to reduce the size of
the binary slightly.
2010-09-12 22:00:31 +00:00
jilles
2beda3228f sh: Fix exit status if return is used within a loop condition. 2010-09-11 15:07:40 +00:00
jilles
694b7e6c37 sh: Apply variable assignments left-to-right in bltinlookup().
Example:
  HOME=foo HOME=bar cd
2010-09-11 14:15:50 +00:00
jilles
3f97220f48 sh(1): Remove xrefs for expr(1) and getopt(1).
expr(1) should usually not be used as various forms of parameter expansion
and arithmetic expansion replicate most of its functionality in an easier
way.

getopt(1) should not be used at all in new code. Instead, getopts(1) or
entirely manual parsing should be used.

MFC after:	1 week
2010-09-10 13:40:31 +00:00
jilles
73c5bdeaeb sh: Fix 'read' if all chars before the first IFS char are backslash-escaped.
Backslash-escaped characters did not set the flag for a non-IFS character.

MFC after:	2 weeks
2010-09-08 20:35:43 +00:00
jilles
c86bc993b1 sh: Improve comments in expand.c. 2010-09-05 21:12:48 +00:00
jilles
0f8d870bb8 sh: Get rid of some magic numbers.
MFC after:	1 week
2010-09-04 21:23:46 +00:00
jilles
642c71cb5d sh: Do not use locale for determining if something is a name.
This makes it impossible to use locale-specific characters in variable
names.

Names containing locale-specific characters make scripts only work with the
correct locale setting. Also, they did not even work in many practical cases
because multibyte character sets such as utf-8 are not supported.

This also avoids weirdness if LC_CTYPE is changed in the middle of a script.
2010-09-03 22:13:54 +00:00
jilles
44306000bd sh: Remove remnants of '!!' to negate pattern.
This Almquist extension was disabled long ago.

In pathname generation, components starting with '!!' were treated as
containing wildcards, causing unnecessary readdir (which could fail, causing
pathname generation to fail while it should not).
2010-08-22 21:18:21 +00:00
jilles
b23d3a5ce5 sh(1): Add a brief summary of arithmetic expressions. 2010-08-22 13:04:00 +00:00
jilles
0328c8f214 sh: Fix break/continue/return sometimes not skipping the rest of dot script.
In our implementation and most others, a break or continue in a dot script
can break or continue a loop outside the dot script. This should cause all
further commands in the dot script to be skipped. However, cmdloop() did not
know about this and continued to parse and execute commands from the dot
script.

As described in the man page, a return in a dot script in a function returns
from the function, not only from the dot script. There was a similar issue
as with break and continue. In various other shells, the return appears to
return from the dot script, but POSIX seems not very clear about this.
2010-08-15 21:06:53 +00:00
jilles
d713120364 sh: Add a forgotten const. 2010-08-13 20:29:43 +00:00
jilles
392fc0c63d sh: Fix shadowing of sigset. 2010-08-13 13:36:18 +00:00
jilles
8824c5ab76 sh: Fix heap-based buffer overflow in pathname generation.
The buffer for generated pathnames could be too small in some cases. It
happened to be always at least PATH_MAX long, so there was never an overflow
if the resulting pathnames would be usable.

This bug may be abused if a script subjects input from an untrusted source
to pathname generation, which a bad idea anyhow. Most shell scripts do not
work on untrusted data. secteam@ says no advisory is necessary.

PR:		bin/148733
Reported by:	Changming Sun snnn119 at gmail com
MFC after:	10 days
2010-08-10 22:45:59 +00:00
jilles
7aa77c20cf Remove unnecessary duplicate letters in mksyntax.c,
the table elements would just be overwritten twice.
2010-08-08 21:04:27 +00:00
jilles
184699830c sh: Return 0 from eval if no command was given.
This makes a difference if there is a command substitution.

To make this work, evalstring() has been changed to set exitstatus to 0 if
no command was executed (the string contained only whitespace).

Example:
  eval $(false); echo $?
should print 0.
2010-08-03 22:17:29 +00:00
jilles
21076809ad sh: Do not enter consecutive duplicates into the history.
This simply sets a flag in libedit. It has a shortcoming in that it does not
apply to multi-line commands.

Note that a configuration option for this is not going to happen, but always
having this seems better than not having it. NetBSD has done the same.

PR:		bin/54683
Obtained from:	NetBSD
MFC after:	1 month
2010-08-01 16:37:51 +00:00
jilles
f8f703f788 sh: Fix crash due to uninitialized here-document.
If an ; or & token was followed by an EOF token, pending here-documents were
left uninitialized. Execution would crash, either in the main shell process
for literal here-documents or in a child process for expanded
here-documents. In the latter case the problem is hard to detect apart from
the core dumps and log messages.

Side effect: slightly different retries on inputs where EOF is not
persistent.

Note that tools/regression/bin/sh/parser/heredoc6.0 still causes a similar
crash in a child process. The text passed to eval is malformed and should be
rejected.
2010-07-25 22:25:52 +00:00
jilles
8be68756a9 sh: Allow a background command consisting solely of redirections.
Example:
  </dev/null &

MFC after:	2 weeks
2010-07-18 12:45:31 +00:00
jilles
7e0d773037 sh: There cannot be a TNOT in simplecmd(), remove checks.
simplecmd() only handles simple commands and function definitions, neither
of which involves the ! keyword. The initial token on entry to simplecmd()
is one of the following: TSEMI, TAND, TOR, TNL, TEOF, TWORD, TRP.
2010-07-14 22:31:45 +00:00
jilles
4ae2ec7aa4 sh: Use $PWD instead of getcwd() for the \w and \W prompt expansions.
This ensures that the logical working directory (which may include
symlinks) is shown and is similar to the default behaviour of the pwd
builtin.
2010-07-02 22:17:13 +00:00
jilles
8fcbe1caf8 sh: Forget about terminated background processes sooner.
Unless $! has been referenced for a particular job or $! still contains that
job's pid, forget about it after it has terminated. If $! has been
referenced, remember the job until the wait builtin has reported its
completion (either with the pid as parameter or without parameters).

In interactive mode, jobs are forgotten after termination has been reported,
which happens before primary prompts and through the jobs builtin. Even
then, though, remember a job if $! has been referenced.

This is similar to what is suggested by POSIX and should fix most memory
leaks (which also tend to cause sh to use more CPU time) with long running
scripts that start background jobs.

Caveats:
* Repeatedly referencing $! without ever doing 'wait', like
    while :; do foo & echo started foo: $!; sleep 60; done
  will still use a lot of memory and CPU time in the long run.
* The jobs and jobid builtins do not cause a job to be remembered for longer
  like expanding $! does.

PR:		bin/55346
2010-06-29 22:37:45 +00:00
jilles
9620b35016 sh: Fix compilation with -DNO_HISTORY.
The LINENO code uses snprintf() and relied on "myhistedit.h" to pull in the
necessary <stdio.h>.

Compiling with -DNO_HISTORY disables all editing and history support and
allows linking without -ledit -ltermcap. This may be useful for embedded
systems.

MFC after:	2 weeks
2010-06-19 10:33:04 +00:00
jilles
714627407c sh: Add filename completion.
This uses the new libedit completion function with quoting support.

Unlike NetBSD, there is no 'set +o tabcomplete' option to disable
completion. I do not see any reason for such a special treatment, as
completion is rather useful and it is possible to do
  bind ^I ed-insert
to disable completion and insert a tab character instead.

Submitted by:	Guy Yur
2010-06-15 21:58:40 +00:00
jilles
caf58c06dc sh: Pass through SIGINT from a child if interactive and job control
is enabled.

This already worked if without job control.

In either case, this depends on it that a process that terminates due to
SIGINT exits on it (so not with status 1, or worse, 0).

Example:
  sleep 5; echo continued
This does not print "continued" any more if sleep is aborted via ctrl+c.

MFC after:	1 month
2010-06-06 22:27:32 +00:00
jilles
e5f96a4e05 sh: Pass TERM changes to libedit.
I have changed the patch slightly to ignore TERM changes in subshells.

PR:		bin/146916
Submitted by:	Guy Yur
Obtained from:	NetBSD
2010-06-02 19:16:58 +00:00
jilles
e65f4ccf95 sh: Fix a crash if a heredoc was not properly ended and parsing continued.
Example (in interactive mode):
  cat <<EOF && )
The next command typed caused sh to segfault, because the state for the here
document was not reset.

Like parser_temp, this uses the fact that the parser is not re-entered.
2010-05-30 14:20:32 +00:00
jilles
930ce39226 sh: Change interaction of command substitution and here documents.
If a command substitution contains a newline token, this no longer starts
here documents of outer commands. This way, we follow POSIX's idea of the
command substitution being a separate script more closely. It also matches
other shells better and is consistent with newline characters in quotes not
starting here documents.

The extension tested in parser/heredoc3.0 ($(cat <<EOF)\ntext\nEOF\n)
continues to be supported.

In particular, this change allows things like
  cat <<EOF && echo `pwd`
(a `` command substitution after a here document)
which formerly silently used an empty file as the here document, because the
EOF of the inner command "pwd" also forced an empty here document.
2010-05-30 14:11:27 +00:00
jilles
c5fcbff43a sh: Recognize "--" in . and exec.
Although "--" historically has not been required to be recognized for
certain special builtins that do not take options in POSIX, some other
implementations recognize options for them, requiring scripts to use "--" or
avoid operands starting with "-".

Operands starting with "-" can be avoided with eval by prepending a space,
and cannot occur with break, continue, exit, return and shift as they only
take numbers, nor with times as it does not take operands. With . and exec,
avoiding "-" is not so easy as it may require reimplementing the PATH
search; therefore the current proposal for POSIX is to require recognition
of "--" for them.

We continue to accept other strings starting with "-" as operands to . and
exec, and also "--" if it is alone to . (which would otherwise be invalid
anyway).
2010-05-28 22:40:24 +00:00
jilles
ce59c74efd sh(1): Rework documentation of shell variables.
* Move the "environment variables" that do not need exporting to be
  effective or that are set by the shell without exporting to a new section
  "Special Variables".
* Add special variables LINENO and PPID.
* Add environment variables LANG, LC_* and PWD; also describe ENV under
  environment variables.
2010-05-24 15:12:12 +00:00
jilles
cc01dc82d8 sh(1): Improve wording of 'Special Parameters' section. 2010-05-24 13:28:12 +00:00
jilles
95d1dcb0f4 sh: Reap any zombies before forking for a background command.
This prevents accumulating huge amounts of zombies if a script executes
many background commands but no external commands or subshells.

Note that zombies will not be reaped during long calculations (within
the shell process) or read builtins, but those actions do not create
more zombies.

The terminated background commands will also still be remembered by the
shell.

PR:		bin/55346
2010-05-24 10:35:57 +00:00
jilles
c49fe4933f sh: Fix pathname expansion with quoted slashes like *\/.
These are git commits 36f0fa8fcbc8c7b2b194addd29100fb40e73e4e9 and
d6d06ff5c2ea0fa44becc5ef4340e5f2f15073e4 in dash.

Because this is the first code I'm importing from dash to expand.c, add the
Herbert Xu copyright notice which is in dash's expand.c.

When pathname expanding *\/, the CTLESC representing the quoted state was
erroneously taken as part of the * pathname component. This CTLESC was then
seen by the pattern matching code as escaping the '\0' terminating the
string.

The code is slightly different because dash converts the CTLESC characters
to backslashes and removes all the other CTL* characters to allow
substituting glob(3).

The effect of the bug was also slightly different from dash (where nothing
matched at all). Because a CTLESC can escape a '\0' in some way, whether
files were included despite the bug depended on memory that should not be
read. In particular, on many machines /*\/ expanded to a strict subset of
what /*/ expanded to.

Example:
  echo /*"/null"

This should print /dev/null, not /*/null.

PR:		bin/146378
Obtained from:	dash
2010-05-11 23:19:28 +00:00
jilles
48c5cd85a6 sh(1): Fix "reserved word" vs "keyword" inconsistency.
Use "keyword" everywhere, like the output of the 'type' builtin, and only
mention "reserved word" once to say it is the same thing.
2010-05-09 22:03:18 +00:00
jilles
6a8de408d7 sh: Have only one copy of _PATH_STDPATH in the binary. 2010-05-08 14:00:01 +00:00
jilles
f3856c6cf2 sh: Apply locale vars on builtins, recognize LC_MESSAGES as a locale var.
This allows doing things like LC_ALL=C some_builtin to run a builtin under a
different locale, just like is possible with external programs. The
immediate reason is that this allows making printf(1) a builtin without
breaking things like LC_NUMERIC=C printf '%f\n' 1.2

This change also affects special builtins, as even though the assignment is
persistent, the export is only to the builtin (unless the variable was
already exported).

Note: for this to work for builtins that also exist as external programs
such as /bin/test, the setlocale() call must be under #ifndef SHELL. The
shell will do the setlocale() calls which may not agree with the environment
variables.
2010-05-05 21:48:40 +00:00
jilles
88403fad18 sh: Use stalloc for arith variable names.
This is simpler than the custom memory tracker I added earlier, and is also
needed by the dash arith code I plan to import.
2010-04-25 20:43:19 +00:00
jilles
286029c478 sh: On startup of the shell, use PWD from the environment if it is valid.
Unset PWD if it is incorrect and no value for it can be determined.
This preserves the logical current directory across shell invocations.

Example (assuming /home is a symlink):
$ cd
$ pwd
/home/foo
$ sh
$ pwd
/home/foo

Formerly the second pwd would show the physical path (symlinks resolved).
2010-04-17 14:35:46 +00:00
jilles
160d26da32 sh: Partially revert r206146, allowing double-quotes in arithmetic.
These do pretty much nothing (except that parentheses are ignored), but
people seem to use them and allowing them does not hurt much.

Single-quotes seem not to be used and cause silently different behaviour
with ksh93 character constants.
2010-04-11 12:24:47 +00:00
jilles
f43d9cd171 sh: Automatically enable -o emacs in interactive shells with terminals.
This makes sh a bit more friendly in single user mode, make buildenv, chroot
and the like, and matches other shells.

The -o emacs can be overridden on the command line or in the ENV file.
2010-04-05 14:15:51 +00:00
jilles
f4618de061 sh: Document the expansion changes in the man page.
Note that the following sentence
> Enclosing the full parameter expansion string in double-quotes does not
> cause the following four varieties of pattern characters to be quoted,
> whereas quoting characters within the braces has this effect.
is now true, but used to be incorrect.
2010-04-04 13:17:05 +00:00
jilles
d21d692410 sh: Do tilde expansion in substitutions.
This applies to word in ${v-word}, ${v+word}, ${v=word}, ${v?word} (which
inherits quoting from the outside) and in ${v%word}, ${v%%word}, ${v#word},
${v##word} (which does not inherit any quoting).

In all cases tilde expansion is only attempted at the start of word, even if
word contains spaces. This agrees with POSIX and other shells.

This is the last part of the patch tested in the exp-run.

Exp-run done by: erwin (with some other sh(1) changes)
2010-04-03 22:04:44 +00:00