summaryrefslogtreecommitdiffstats
path: root/bin/sh/eval.c
Commit message (Collapse)AuthorAgeFilesLines
* sh: Update associated state when restoring locals while leaving a function.jilles2016-01-101-2/+2
| | | | | | | | Some variables like PATH call a function when modified. Make sure to call this also when leaving a function where such a variable was made local. Make sure to restore local variables before shellparam, so getopts state is not clobbered.
* sh: Ensure OPTIND=1 in subshell without forking does not affect outer env.jilles2016-01-071-0/+7
| | | | | | | | | | | | Command substitutions containing a single simple command and here-document expansion are performed in a subshell environment, but may not fork. Any modified state of the shell environment should be restored afterward. The state that OPTIND=1 had been done was not saved and restored here. Note that the other parts of shellparam need not be saved and restored, since they are not modified in these situations (a fork is done before such modifications).
* sh: Avoid copying argv for simple commands.jilles2015-11-011-9/+9
| | | | | Add dummy entries before and after so arglist's array is directly usable as argv.
* sh: Make struct arglist an array instead of a linked list.jilles2015-10-111-48/+41
| | | | | | | | | | | This simplifies the code (e.g. allowing use of qsort(3) instead of a hand-rolled mergesort) and should have better cache properties. The waste of unused args arrays after resizes is approximately the same as the savings from getting rid of the next pointers. At the same time, remove a piece of global state and move some duplicated code into a function.
* sh: Fix more compiler warnings.jilles2015-03-011-1/+1
|
* sh: Prefer "" to nullstr where possible.jilles2015-02-151-1/+1
|
* sh: Remove EXP_REDIR.jilles2014-12-211-2/+2
| | | | | | | | | | EXP_REDIR was supposed to generate pathnames in redirection if exactly one file matches, as permitted but not required by POSIX in interactive mode. It is unlikely this will be implemented. No functional change is intended. MFC after: 1 week
* sh: Remove special case for '=' in set -x; always quote it in outqstr().jilles2014-11-301-9/+1
| | | | | I plan to make set -x output always printable using $'...'; avoiding quoting words containing '=' is not worth the extra complexity.
* sh: Make getopts memory-safe if with changing arguments.jilles2014-10-261-0/+1
| | | | | | | | | | | | POSIX does not permit to continuing a getopts loop with different arguments. For parsing the positional parameters, we handle this case by resetting the getopts state when the positional parameters are changed in any way (and the getopts state is local to a function). However, in the syntax getopts <optstring> <var> <arg...>, changes could lead to invalid memory access. In the syntax getopts <optstring> <var> <arg...>, store a copy of the arguments and continue to use them until getopts is reset.
* sh: Fix break/continue/return in multiline eval.jilles2014-10-121-0/+2
| | | | | Example: eval $'return\necho bad'
* sh: Eliminate some gotos.jilles2014-10-051-7/+5
|
* sh: Allow arbitrarily large numbers in break and continue.jilles2014-07-201-1/+9
| | | | The argument is capped to loopnest, so strtol()'s [ERANGE] can be ignored.
* sh: Split set -x output into a separate function.jilles2013-12-061-34/+41
|
* sh: Make return return from the closest function or dot script.jilles2013-09-041-10/+4
| | | | | | | | | | | | | Formerly, return always returned from a function if it was called from a function, even if there was a closer dot script. This was for compatibility with the Bourne shell which only allowed returning from functions. Other modern shells and POSIX return from the function or the dot script, whichever is closest. Git 1.8.4's rebase --continue depends on the POSIX behaviour. Reported by: Christoph Mallon, avg
* sh: Remove unnecessary reset functions.jilles2013-08-161-1/+0
| | | | These are already handled by exception handlers.
* sh: Remove #define MKINIT.jilles2013-07-251-1/+1
| | | | MKINIT only served for the removed mkinit. Many variables can be static now.
* sh: Remove mkinit.jilles2013-07-251-6/+3
| | | | | | | | | | | | | | 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.
* sh: Do not close(-1) if pipe() fails.jilles2013-06-281-1/+2
|
* sh: Don't modify exit status when break/continue/return passes !.jilles2013-04-121-0/+2
| | | | | | | | This matches what would happen if ! P were to be replaced with if P; then false; else true; fi. Example: f() { ! return 0; }; f
* sh: If a SIGINT or SIGQUIT interrupts "wait", return status 128+sig.jilles2013-02-231-1/+1
|
* sh: Fix a crash with the stackmark code.jilles2013-02-191-0/+2
| | | | | | | | | | | | | | | | 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
* sh: Expand here documents in the current process.jilles2013-02-031-0/+35
| | | | | | | | | | | | | | | | | 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.
* sh: Move some stackmarks to fix high memory usage in some loops.jilles2013-01-201-11/+5
| | | | | | | | | | | | 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
* sh: Pass $? to command substitution containing compound/multiple commands.jilles2013-01-141-2/+1
| | | | | Example: false; echo $(echo $?; :)
* sh: Detect and flag write errors on stdout in builtins.jilles2012-12-121-0/+6
| | | | | | | 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
* sh: Prefer internal nextopt() to libc getopt().jilles2012-09-151-12/+5
| | | | | | | | | 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.
* sh: Expand assignment-like words specially for export/readonly/local.jilles2012-07-151-3/+50
| | | | | | | | | | | | | | | | | | | | | | | | | | Examples: export x=~ now expands the tilde local y=$1 is now safe, even if $1 contains IFS characters or metacharacters. For a word to "look like an assignment", it must start with a name followed by an equals sign, none of which may be quoted. The special treatment applies when the first word (potentially after "command") is "export", "readonly" or "local". There may be quoting characters but no expansions. If "local" is overridden with a function there is no special treatment ("export" and "readonly" cannot be overridden with a function). If things like local arr=(1 2 3) are ever allowed in the future, they cannot call a "local" function. This would either be a run-time error or it would call the builtin. This matches Austin Group bug #351, planned for the next issue of POSIX.1. PR: bin/166771
* sh: Use vfork in a few common cases.jilles2012-02-041-0/+9
| | | | | | | | | | | | | | | | | This uses vfork() for simple commands and command substitutions containing a single simple command, invoking an external program under certain conditions (no redirections or variable assignments, non-interactive shell, no job control). These restrictions limit the amount of code executed in a vforked child. There is a large speedup (for example 35%) in microbenchmarks. The difference in buildkernel is smaller (for example 0.5%) but still statistically significant. See http://lists.freebsd.org/pipermail/freebsd-hackers/2012-January/037581.html for some numbers. The use of vfork() can be disabled by setting a variable named SH_DISABLE_VFORK.
* sh: Fix $? in the first command of a 'for'.jilles2012-01-221-1/+4
| | | | | | In the first command of a 'for', $? should be the exit status of the last pipeline (command substitution in the word list or command before 'for'), not always 0.
* sh: Fix execution of multiple statements in a trap when evalskip is setdumbbell2012-01-161-1/+1
| | | | | | | | | | | Before this fix, only the first statement of the trap was executed if evalskip was set. This is for example the case when: o "-e" is set for this shell o a trap is set on EXIT o a function returns 1 and causes the script to abort Reviewed by: jilles MFC after: 2 weeks
* sh: Fix some bugs with exit status from case containing ;&.jilles2012-01-151-9/+24
| | | | | | | | | | | | | Also, rework evalcase() to not evaluate any tree. Instead, return the NCLISTFALLTHRU node and handle it in evaltree(). Fixed bugs: * If a ;& list with non-zero exit status is followed by an empty ;; or final list, the exit status of the case command should be equal to the exit status of the ;& list, not 0. * An empty ;& case should not reset $?.
* sh: Fix two bugs with case and exit status:jilles2012-01-151-1/+3
| | | | | | | * If no pattern is matched, POSIX says the exit status shall be 0 (even if there are command substitutions). * If a pattern is matched and there are no command substitutions, the first command should see the $? from before the case command, not always 0.
* sh: Do not force special builtins non-special in optimized command subst.jilles2011-12-281-2/+1
| | | | | | | | | This is not necessary: errors are already caught in evalbackcmd() and forcelocal handles changes to variables. Note that this depends on r223024. MFC after: 4 weeks
* sh: Remove impossible evalskip check in 'for'.jilles2011-11-271-3/+0
|
* sh: Reduce one level of evaltree() recursion when executing 'case'.jilles2011-11-261-11/+9
| | | | | | | Free expanded case text before executing commands. Remove impossible evalskip checks (expanding an argument cannot set evalskip anymore since $(break) and the like are properly executed in a subshell environment).
* sh: Remove special support for background simple commands.jilles2011-06-181-5/+3
| | | | It expands the arguments in the parent shell process, which is incorrect.
* sh: Add case statement fallthrough (with ';&' instead of ';;').jilles2011-06-171-0/+8
| | | | | | | | | | | | Replacing ;; with the new control operator ;& will cause the next list to be executed as well without checking its pattern, continuing until a list ends with ;; or until the end of the case statement. This is like omitting "break" in a C "switch" statement. The sequence ;& was formerly invalid. This feature is proposed for the next POSIX issue in Austin Group issue #449.
* sh: Reduce unnecessary forks with eval.jilles2011-06-161-1/+2
| | | | | | | | | | The eval special builtin now runs the code with EV_EXIT if it was run with EV_EXIT itself. In particular, this eliminates one fork when a command substitution contains an eval command that ends with an external program or a subshell. This is similar to what r220978 did for functions.
* sh: Save/restore changed variables in optimized command substitution.jilles2011-06-121-7/+11
| | | | | | | | | | | In optimized command substitution, save and restore any variables changed by expansions (${var=value} and $((var=assigned))), instead of trying to determine if an expansion may cause such changes. If $! is referenced in optimized command substitution, do not cause jobs to be remembered longer. This fixes $(jobs $!) again, simplifies the man page and shortens the code.
* sh: Do parameter expansion before printing PS4 (set -x).jilles2011-06-091-2/+3
| | | | | | | | | | | | | | | | The function name expandstr() and the general idea of doing this kind of expansion by treating the text as a here document without end marker is from dash. All variants of parameter expansion and arithmetic expansion also work (the latter is not required by POSIX but it does not take extra code and many other shells also allow it). Command substitution is prevented because I think it causes too much code to be re-entered (for example creating an unbounded recursion of trace lines). Unfortunately, our LINENO is somewhat crude, otherwise PS4='$LINENO+ ' would be quite useful.
* sh: Fix $? in heredocs on simple commands.jilles2011-06-051-1/+2
| | | | PR: bin/41410
* sh: Honour -n while processing -c string.jilles2011-06-041-1/+1
|
* sh: Expand aliases after assignments and redirections.jilles2011-05-211-9/+3
|
* sh: Avoid close(-1) when evaluating a multi-command pipeline.jilles2011-05-151-1/+2
| | | | Valgrind complains about this.
* sh: Set $? to 0 for background commands.jilles2011-04-251-3/+6
| | | | | | | | | | 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.
* sh: Allow EV_EXIT through function calls, make {...} <redir more consistent.jilles2011-04-231-12/+13
| | | | | | | | | | | | | | | | | | | | | 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.
* sh: Remove clearcmdentry()'s now unused argument.jilles2011-02-051-3/+3
|
* sh: Remove special code for shell scripts without magic number.jilles2011-02-041-18/+10
| | | | | | | | | | 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.
* sh: Do not call exitshell() from evalcommand() unless evalcommand() forkedjilles2011-01-051-4/+5
| | | | | | itself. This ensures that certain traps caused by builtins are executed.
* sh: Check readonly status for assignments on regular builtins.jilles2011-01-011-2/+1
| | | | | | | | | | 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
OpenPOWER on IntegriCloud