summaryrefslogtreecommitdiffstats
path: root/bin/sh/eval.c
Commit message (Collapse)AuthorAgeFilesLines
* 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
* sh: Avoid side effects from builtins in optimized command substitution.jilles2010-12-301-5/+27
| | | | | | | | | | | | | | | | | | 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.
* sh: Don't do optimized command substitution if expansions have side effects.jilles2010-12-281-1/+15
| | | | | | | | | | | | | | | | | | | | | | | | | 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.
* sh: Make expansion errors in optimized command substitution non-fatal.jilles2010-12-281-1/+15
| | | | | | 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).
* sh: Code size optimizations to "stack string" memory allocation:jilles2010-11-231-2/+1
| | | | | | | | * 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.
* sh: Code size optimizations to buffered output.jilles2010-11-201-6/+6
| | | | | | This is mainly less use of the outc macro. No functional change is intended, but code size is about 2K less on i386.
* sh: Reindent evaltree().jilles2010-10-311-76/+76
|
* sh: Use iteration instead of recursion to evaluate semicolon lists.jilles2010-10-311-5/+10
| | | | | This reduces CPU and memory usage when executing long lists (such as long functions).
* sh: Tweak some string constants to reduce code size.jilles2010-10-291-1/+1
| | | | | * Reduce some needless differences. * Shorten some error messages that should not happen.
* In the spirit of r90111, depend on c89 and remove the "STATIC" macroobrien2010-10-131-18/+18
| | | | and its usage.
* Consistently use "STATIC" for all functions in order to be able to setobrien2010-10-131-2/+2
| | | | | | breakpoints with in a debugger. And use naked "static" for variables. Noticed by: bde
* sh: Fix exit status if return is used within a loop condition.jilles2010-09-111-0/+2
|
* sh: Get rid of some magic numbers.jilles2010-09-041-2/+2
| | | | MFC after: 1 week
* sh: Add a forgotten const.jilles2010-08-131-1/+1
|
* sh: Return 0 from eval if no command was given.jilles2010-08-031-1/+7
| | | | | | | | | | | 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.
* sh: Recognize "--" in . and exec.jilles2010-05-281-0/+6
| | | | | | | | | | | | | | | | | | 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).
* sh: Have only one copy of _PATH_STDPATH in the binary.jilles2010-05-081-3/+2
|
* sh: Apply locale vars on builtins, recognize LC_MESSAGES as a locale var.jilles2010-05-051-0/+4
| | | | | | | | | | | | | | | | 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.
* sh: Do not abort on a redirection error on a compound command.jilles2010-03-141-4/+42
| | | | | | | | | | | | | | Redirection errors on subshells already did not abort the shell because the redirection is executed in the subshell. Other shells seem to agree that these redirection errors should not abort the shell. Also ensure that the redirections will be cleaned up properly in cases like command eval '{ shift x; } 2>/dev/null' Example: { echo bad; } </var/empty/x; echo good
* sh: Do not abort on a redirection error if there is no command word.jilles2010-03-131-1/+7
| | | | | | | | | | | Although simple commands without a command word (only assignments and/or redirections) are much like special builtins, POSIX and most shells seem to agree that redirection errors should not abort the shell in this case. Of course, the assignments persist and assignment errors are fatal. To get the old behaviour portably, use the ':' special builtin. To get the new behaviour portably, given that there are no assignments, use the 'true' regular builtin.
* sh: Make sure to popredir() even if a function caused an error.jilles2010-03-061-1/+3
|
* sh: Make sure to popredir() even if a special builtin caused an error.jilles2010-03-061-2/+3
|
* sh: Improve the command builtin:jilles2010-03-061-32/+63
| | | | | | | | * avoid unnecessary fork * allow executing builtins via command * executing a special builtin via command removes its special properties Obtained from: NetBSD (parts)
* sh: Send the "not found" message for builtin <cmd> to redirected fd 2.jilles2010-01-031-5/+11
|
* sh: Fix some bugs with backquoted builtins:jilles2010-01-011-11/+12
| | | | | | | | | | | | - correctly handle error output in $(builtin 2>&1), clarify out1/out2 vs output/errout in the code - treat all builtins as regular builtins so errors do not abort the shell and variable assignments do not persist - respect the caller's INTOFF Some bugs still exist: - expansion errors may still abort the shell - some side effects of expansions and builtins persist
* sh: Allow command -pv and command -pV (lookup using _PATH_STDPATH).jilles2009-12-311-1/+1
|
* sh: Ensure funcnest is decremented if there was an error in the function.jilles2009-12-301-2/+3
| | | | | | This will be important when things like 'command eval f' will be possible. Currently, the funcnest = 0 assignment in RESET (called when returning to the top level after an error in interactive mode) is really sufficient.
* sh: Various warning fixes (from WARNS=6 NO_WERROR=1):jilles2009-12-271-4/+3
| | | | | | | - const - initializations to silence -Wuninitialized (it was safe anyway) - remove nested extern declarations - rename "index" locals to "idx"
* Fix some cases where file descriptors from redirections leak to programs.jilles2009-11-291-1/+0
| | | | | | | | | | | | | | | | - Redirecting fds that were not open before kept two copies of the redirected file. sh -c '{ :; } 7>/dev/null; fstat -p $$; true' (both fd 7 and 10 remained open) - File descriptors used to restore things after redirection were not set close-on-exec, instead they were explicitly closed before executing a program normally and before executing a shell procedure. The latter must remain but the former is replaced by close-on-exec. sh -c 'exec 7</; { exec fstat -p $$; } 7>/dev/null; true' (fd 10 remained open) The examples above are simpler than the testsuite because I do not want to use fstat or procstat in the testsuite.
* Fix various things about SIGINT handling:jilles2009-11-221-1/+1
| | | | | | | | | | | | | | | | | | * exception handlers are now run with interrupts disabled, which avoids many race conditions * fix some cases where SIGINT only aborts one command and continues the script, in particular if a SIGINT causes an EINTR error which trumped the interrupt. Example: sh -c 'echo < /some/fifo; echo This should not be printed' The fifo should not have writers. When pressing ctrl+c to abort the open, the shell used to continue with the next command. Example: sh -c '/bin/echo < /some/fifo; echo This should not be printed' Similar. Note, however, that this particular case did not and does not work in interactive mode with job control enabled.
* sh: Ensure the same command input file is on top after executing a builtin.jilles2009-11-221-0/+3
| | | | | | | | | | | | | This avoids weirdness when 'fc -e vi' or the like is done and there is a syntax error in the file. Formerly an interactive shell tried to execute stuff after the syntax error and exited. This should also avoid similar issues with 'command eval' and 'command .' when 'command' is implemented properly as in NetBSD sh. Special builtins did not have this problem since errors in them cause the shell to exit or to reset various state such as the current command input file.
* sh: Send the "xyz: not found" message to redirected fd 2.jilles2009-10-061-7/+2
| | | | | | | | | | This also fixes that trying to execute a non-regular file with a command name without '/' returns 127 instead of 126. The fix is rather simplistic: treat CMDUNKNOWN as if the command were found as an external program. The resulting fork is a bit wasteful but executing unknown commands should not be very frequent. PR: bin/137659
* sh: Fix crash with empty functions (f() { }) introduced in r196483jilles2009-08-281-2/+2
| | | | | | | | | | | | Empty pairs of braces are represented by a NULL node pointer, just like empty lines at the top level. Support for empty pairs of braces may be removed later. They make the code more complex, have inconsistent behaviour (may or may not change $?), are not specified by POSIX and are not allowed by some other shells like bash, dash and ksh93. Reported by: kan
* sh: Fix crash when undefining or redefining a currently executing function.jilles2009-08-231-2/+5
| | | | | | | | Add a reference count to function definitions. Memory may leak if multiple SIGINTs arrive in interactive mode, this will be fixed later by changing SIGINT handling. PR: bin/137640
* Quote -x tracing output so it is unambiguous.jilles2009-06-231-2/+17
| | | | | | It is usually but not always suitable for re-input to the shell. Approved by: ed (mentor) (implicit)
* Do not fork for a subshell if it is the last thing this shell is doingjilles2009-06-231-2/+2
| | | | | | | | | | | | | | | | | | | | | (EV_EXIT). The fork is still done as normal if any traps are active. In many cases, the fork can be avoided even without this change by using {} instead of (), but in practice many scripts use (), likely because the syntax is simpler. Example: sh -c '(/bin/sleep 10)& sleep 1;ps -p $! -o comm=' Now prints "sleep" instead of "sh". $! is more useful this way. Most shells (dash, bash, pdksh, ksh93, zsh) seem to print "sleep" for this. Example: sh -c '( ( ( (ps jT))))' Now shows no waiting shell processes instead of four. Most shells (dash, bash, pdksh, ksh93, zsh) seem to show zero or one. PR: bin/74404 Approved by: ed (mentor) (implicit)
* sh: Improve handling of setjmp/longjmp volatile:jilles2009-06-231-15/+7
| | | | | | | | | | | - remove ineffective and unnecessary (void) &var; [1] - remove some unnecessary volatile keywords - add a necessary volatile keyword - save the old handler before doing something that could use the saved value Submitted by: Christoph Mallon [1] Approved by: ed (mentor)
* Avoid leaving unnecessary waiting shells in many forms of sh -c COMMAND.jilles2009-06-131-8/+11
| | | | | | | | | | | | | | | | | | | | | | This change only affects strings passed to -c, when the -s option is not used. The approach is to check if there may be additional data in the string after parsing each command. If there is none, use the EV_EXIT flag so that a fork may be omitted in specific cases. If there are empty lines after the command, the check will not see the end and forks will not be omitted. The same thing seems to happen in bash. Example: sh -c 'ps lT' No longer shows a shell process waiting for ps to finish. PR: bin/113860 Reviewed by: stefanf Approved by: ed (mentor)
* Don't skip forking for an external command if any traps are active.jilles2009-06-131-1/+1
| | | | | | | | | | | | | | | | | Example: sh -c '(trap "echo trapped" EXIT; sleep 3)' now correctly prints "trapped". With this check, it is no longer necessary to check for -T explicitly in that case. This is a useful bugfix by itself and also important because I plan to skip forking more often. PR: bin/113860 (part of) PR: bin/74404 (part of) Reviewed by: stefanf Approved by: ed (mentor)
* correctly test for __GNUC__ macro (non-GCC compilers do not have it defined ↵rse2009-06-011-1/+1
| | | | at all)
* Fix the eval command in combination with set -e. Before this change the shellstefanf2009-05-311-3/+5
| | | | | | | | | would always terminate if eval returned with a non-zero exit status regardless if the status was actually tested. Unfortunately a new file-scope variable is needed, the alternative would only be to add a new parameter to all built-ins. PR: 134881
* Don't let trailing empty lines overwrite the result of the last command with 0.stefanf2009-04-041-1/+2
| | | | | | | This affects the built-ins eval, fc, and trap and also the string passed to sh with the -c option. Submitted by: Jilles Tjoelker
OpenPOWER on IntegriCloud