summary refs log tree commit diff
path: root/src (unfollow)
Commit message (Collapse)Author
2014-10-06[BUILTIN] Do not allow break to break across function callsHerbert Xu
As it is if you do a multi-level break inside a function it'll actually include loops outside of the function call. This is counterintuitive. This patch changes this by saving and resetting loopnest when entering a function. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2014-10-06[BUILTIN] Exit without arguments in a trap should use status outside trapsHerbert Xu
POSIX now requires that exit without arguments in a trap should return the last command status prior to executing traps. This patch implements this behaviour. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2014-10-03[EVAL] Do not clobber exitstatus in evalcommandHerbert Xu
All originators of EXERROR have been setting the exitstatus for a while now. So it is no longer appropriate to set it explicitly in evalcommand. In fact doing so may cause the original exitstatus to be lost. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2014-10-02[ERROR] Set exitstatus in onintHerbert Xu
Currently the exit status when we receive SIGINT is set in evalcommand which means that it doesn't always get set. For example, if you press CTRL-C at the prompt of an interactive dash, the exit status is not set to 130 as it is in many other Bourne shells. This patch fixes this by moving the setting of the exit status into onint which also simplifies evalcommand. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2014-10-02[TRAP] Make sure evalskip is zero before running trapsHerbert Xu
As it is if dotrap is called with evalskip set to a nonzero value, it'll try to execute any set traps. The result is that the first command in the first set trap will be executed while the rest of the trap will be silently ignored due to evalskip. This is highly counterintuitive, even though both bash and ksh exhibit a similar behaviour. This patch fixes it by skipping trap processing if evalskip is set on entry. It also adds a dotrap call to the top of evaltree to ensure that while continue; do continue; done has a chance of running traps. Finally the pendingsigs check is moved into dotrap for compactness. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2014-10-02[EVAL] Fix use-after-free in dotrap/evalstringHerbert Xu
The function dotrap calls evalstring using the stored trap string. If evalstring then unsets that exact trap string then we will end up using freed memory. This patch fixes it by making evalstring always duplicate the string before using it. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2014-09-29[PARSER] Add nlprompt/nlnoprompt helpersHerbert Xu
This patch adds the nlprompt/nlnoprompt helpers to isolate code dealing with newlines and prompting. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2014-09-29[PARSER] Handle backslash newlines properly after dollar signHerbert Xu
On Tue, Aug 26, 2014 at 12:34:42PM +0000, Eric Blake wrote: > On 08/26/2014 06:15 AM, Oleg Bulatov wrote: > > Hi! > > > > While playing with sh generators I found that dash and bash have different > > interpretations for <slash><newline> sequence. > > > > $ dash -c 'EDIT=xxx; echo $EDIT\ > >> OR' > > xxxOR > > Buggy. > > > $ bash -c 'EDIT=xxx; echo $EDIT\ > > OR' > > /usr/bin/vim > > Correct behavior. > > > > > $ dash -c 'echo "$\ > > (pwd)"' > > $(pwd) > > > > Is it undefined behaviour in POSIX? > > No, it's well-defined, and dash is buggy. POSIX says: > > http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_03 > > "the shell shall break its input into tokens by applying the first > applicable rule below to the next character in its input" > > Rule 4 covers backslash handling, while rule 5 covers locating the end > of a word to be subject to $ expansion. Therefore, rule 4 should happen > first. Rule 4 defers to the section on quoting, with the caveat that > <newline> joining is the only substitution that happens immediately as > part of the parsing: > > http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_02 > > "If a <newline> follows the <backslash>, the shell shall interpret this > as line continuation. The <backslash> and <newline> shall be removed > before splitting the input into tokens. Since the escaped <newline> is > removed entirely from the input and is not replaced by any white space, > it cannot serve as a token separator." > > So the fact that dash is treating the elided backslash-newline as a > token separator, and parsing your input as if ${EDIT}OR instead of > ${EDITOR} is a bug in dash. I agree. This patch should resolve this problem and similar ones affecting blackslash newlines after we encounter a dollar sign. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2014-09-29[INPUT] Kill pgetc_macroHerbert Xu
pgetc_macro is identical to pgetc except that it's a macro and pgetc isn't. Since there is very little performance difference on modern systems it's time to kill pgetc_macro. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2014-09-28[BUILTIN] Correctly handle test ! ! = !Herbert Xu
This patch adds a special case in testcmd for the 4-argument expression beginning with a !. Without this ! ! = ! is deemed a syntax error, which breaks POSIX. Note that this special case does not extend down into subexpressions so if ! ! = ! is used inside parentheses then a syntax error will still occur as before. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2014-09-26Release 0.5.8.Herbert Xu
2014-09-26[MAN] Clarify "trap '' signals" syntax in manual pageJonathan Nieder
When the manpage states | <action> may be null, which cause the specified signals to be ignored. it is not immediately obvious what it means for an action to be null. Clarify by explicitly referring to an empty string, as opposed to a NULL pointer or the string "null". Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2014-09-26[MAN] 0 and EXIT both work for exit trapsAdam Buchbinder
I saw a discussion in which there was some confusion over whether or not you can use a symbolic name, since the manpage doesn't specifically say so. Signed-off-by: Adam Buchbinder <adam.buchbinder@gmail.com> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2014-09-26[MAN] Change characters for printf precision to bytesHerbert Xu
On Sun, Mar 09, 2014 at 11:11:43AM +0000, Jeroen van Dijke wrote: > > There seems to be a bug in the dash man page, at least in 0.5.7. It reads: > > Precision: > An optional period, `.', followed by an optional digit string giving a precision which specifies the number of digits to appear after the decimal point, for e and f formats, or the maximum number of *characters* to be printed from a string (b and s for- > mats); if the digit string is missing, the precision is treated as zero; > > dash behaves cuts to the number of bytes > > $ length=10; printf "%.${length}s\n" "eeeeeeeeeeeeeeeeeeeeeeeee" > eeeeeeeeee > $ length=10; printf "%.${length}s\n" "ëëëëëëëëëëëëëëëëëëëëëëëëë” > ëëëëë > > > The POSIX specification (2008) says: > > precision Gives the minimum number of digits to appear for the d, o, i, u, x, or X conversion specifiers (the field is padded with leading zeros), the number of digits to appear after the radix character for the e and f conversion specifiers, the maximum number of significant digits for the g conversion specifier; or the maximum number of *bytes* to be written from a string in the s conversion specifier. The precision shall take the form of a ( '.' ) followed by a decimal digit string; a null digit string is treated as zero. > > So it seems to me that “characters” should be changed to “bytes”. Indeed and this patch makes that change. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2014-09-26[JOBS] Fix off-by-one error for multiple of four job numbersHarald van Dijk
On 29/07/13 23:44, Luigi Tarenga wrote: > hi list, > while writing a script to execute parallel ssh command on many host I found > a strange behavior of dash. I can replicate it with a very simple script but > didn't find any documentation about dash or POSIX that can explain it. > > tested on centos 6.4 (dash 0.5.5.1) and wih dash compiled from source (0.5.7) > the following script reports error: > > #!/bin/dash > > sleep 3 & > sleep 3 & > sleep 3 & > sleep 3 & > > #/bin/true > jobs -l > > wait %1 > wait %2 > wait %3 > wait %4 > > [vortex@lizard ~]$ ./dash-0.5.7/src/dash test.sh > [4] + 4569 Running > [3] - 4568 Running > [2] 4567 Running > [1] 4566 Running > prova: 14: wait: No such job: %4 > [vortex@lizard ~]$ echo $? > 2 Yes, this looks like a bug to me. The number of allocated jobs is always kept as a multiple of four, and the first check in considering whether the job number is valid is "if it's greater than or equal to the number of allocated job, it's invalid". That doesn't look right. That would only be right if jobs were zero-based, but they aren't. If it's exactly equal to the number of available jobs, it can still be valid. It works when adding /bin/true, because four more more jobs end up allocated internally. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2014-09-26[BUILTIN] Set command -p path to /usr/sbin:/usr/bin:/sbin:/binHerbert Xu
Exclude /usr/local from command -p PATH. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2014-09-26[BUILTIN] Small optimisation of command -pv changeHerbert Xu
This patch moves the pathval call into the describe_command function and also eliminates an unnecessary branch when DEBUG is off. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2014-09-26[BUILTIN] command: allow combining -p with -vHarald van Dijk
On 10/07/13 20:18, Craig Loomis wrote: > Dash (0.5.7 and git master) does not implement 'command -p' > according to the standard, and opens an intriguing security hole to > anyone trying this scheme. > > When using 'command -v' to simply print the path to an executable, > '-p' has no effect: You're right. dash has never supported combining -p with -v, but back in 2005 this was seemingly accidentally changed from reporting a syntax error to silently ignoring the -p option, only about a month after dash moved to git. Making sure that -p is respected even when -v is used is easy enough, see attached patch. Tested even with explicit PATH overrides: PATH=/path/to/some/other/dash command -pv dash correctly outputs /bin/dash on my system. > the path that 'command -p cmd' uses is a compiled-in constant > from dash's src/var.c:defpathvar, which starts with > "/usr/local/sbin:/usr/local/bin". To me, that is both completely > unexpected and pretty scary -- /usr/local/bin is (very) often less > well secured or checked than, say, /bin: Agreed. However, IMO, it does make sense for defpathvar to start with /usr/local/*: it has two separate functions, it also serves as the default path (hence the name) when dash is started with no PATH set at all. I think fixing this should be done in a way so that command -p does not use defpathvar, not by changing defpathvar. bash uses the same confstr function for this that getconf uses, and it shouldn't be too much work to make dash use that too. If no one else comes up with a working patch or a better approach, I'll try to get that working. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2013-08-23[BUILTIN] Fixed argument parsing crash in testHerbert Xu
When nexpr gets an unexpected EOI, this may cause crashes further up the call chain because we've advanced t_wp too far. Fix it by checking for EOI in nexpr and only advancing t_wp if we've got more arguments. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2013-08-23[VAR] Initialise OPTIND after importing environmentHerbert Xu
On Sat, Mar 23, 2013 at 01:46:20AM +0000, Chris F.A. Johnson wrote: > > According to both the dash man page and the POSIX spec, "When the > shell is invoked, OPTIND is initialized to 1." > > However, it actually takes the value of the environment variable > if it exists: > > $ OPTIND=4 dash -c 'echo "$OPTIND"' > 4 > $ OPTIND=4 bash -c 'echo "$OPTIND"' > 1 > $ OPTIND=4 ksh -c 'echo "$OPTIND"' > 1 > $ OPTIND=4 ksh93 -c 'echo "$OPTIND"' > 1 This patch fixes this by initialising OPTIND after importing the environment. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2013-08-23[VAR] Add newline when tracing in poplocalvarsPeter Rosin
Signed-off-by: Peter Rosin <peda@lysator.liu.se> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2013-08-23[MAN] Markup fixes in manual for mandoc 1.12.1Jérémie Courrèges-Anglas
with Aleksey we briefly discussed the mdoc compatibility of the manpage, here's a patch that makes mandoc 1.12.1 happier and behaves correctly against groff 1.21. I want to include it in the staging dash-0.5.7 OpenBSD port. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2013-08-23[BUILTIN] Use PRIdMAX instead of %j in printfHarald van Dijk
On 12/03/2012 05:59 PM, Harald van Dijk wrote: > On 12/03/2012 08:42 AM, Roy wrote: >> MSYS libc does not support %j[dXx] format, only %ll[dXx] is supported. >> >> diff --git a/src/bltin/printf.c b/src/bltin/printf.c >> index 893295c..12ce660 100644 >> --- a/src/bltin/printf.c >> +++ b/src/bltin/printf.c >> @@ -319,11 +319,12 @@ mklong(const char *str, const char *ch) >> char *copy; >> size_t len; >> >> - len = ch - str + 3; >> + len = ch - str + 4; >> STARTSTACKSTR(copy); >> copy = makestrspace(len, copy); >> - memcpy(copy, str, len - 3); >> - copy[len - 3] = 'j'; >> + memcpy(copy, str, len - 4); >> + copy[len - 4] = 'l'; >> + copy[len - 3] = 'l'; >> copy[len - 2] = *ch; >> copy[len - 1] = '\0'; >> return (copy); > > The calling code uses the result to print intmax_t and uintmax_t values. > Printing intmax_t values with %lld is wrong, this will only work if > intmax_t is really a typedef for long long (which may be true on your > system, but is not required by the standard). > > The other patch that Jonathan linked to should work just fine. Here's a slightly tweaked version of that patch. Regardless of whether PRIdMAX is defined as "jd" or as "lld", the use of memcpy here, first copying "jd"/"lld" and the null byte, and only changing the 'd' after that, surprisingly results in slightly shorter object code than the original byte-by-byte approach, even though memcpy is fully inlined. Perhaps that could be a reason for applying this, even if the original reason for it, making the code work on not-quite-conforming systems, isn't good enough to get it in dash. Tested with normal glibc, and with glibc hacked to not provide PRIdMAX. Reviewed-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2013-08-23[EXPAND] Propagate EXP_QPAT in subevalvarHerbert Xu
On Tue, Aug 28, 2012 at 01:27:24PM +0000, Todor Vlaev wrote: > > While playing around with parameter expansion I noticed that the > following didn't work in dash (dash 0.5.5.1-7.4ubuntu1) as compared > to bash even though I believe it should be POSIX-compliant: > > my_str=swan; last_char="${my_str#${my_str%?}}"; echo ${last_char} > > If the double quotes are removed, the last character is printed correctly. > > At a quick glance through the commits after the 0.5.5.1 release I saw > the following bug fix. Could it be related? > > 0d7d66039b614b642c775432fd64aa8c11f9a64d > [EXPAND] Fix quoted pattern patch breakage We need to propagate EXP_QPAT in subevalvar as otherwise a nested parameter expansion within subevalvar may be expanded incorrectly. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2013-08-23[MAN] Fix typo for waitKimo Rosenbaum
This is a small patch to fix the paragraph about 'wait' in the dash manpage. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2012-07-03[BUILTIN] Add support for ulimit -rChristoph Mathys
I recently found myself in need to have dash support 'ulimit -r' to set maximum realtime priority. Attached is a patch that adds the parameter to the builtin ulimit command and updates the manpage. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2012-07-03Avoid overflow for very long variable nameJim Meyering
Otherwise, this: $ perl -le 'print "v"x(2**31+1) ."=1"' | dash provokes integer overflow: (gdb) bt #0 doformat (dest=0x61d580, f=0x416a08 "%s: %d: %s: ", ap=0x7fffffffd308) at output.c:310 #1 0x00000000004128c1 in outfmt (file=0x61d580, fmt=0x416a08 "%s: %d: %s: ") at output.c:257 #2 0x000000000040382e in exvwarning2 (msg=0x417339 "Out of space", ap=0x7fffffffd468) at error.c:125 #3 0x000000000040387e in exverror (cond=1, msg=0x417339 "Out of space", ap=0x7fffffffd468) at error.c:156 #4 0x0000000000403938 in sh_error (msg=0x417339 "Out of space") at error.c:172 #5 0x000000000040c970 in ckmalloc (nbytes=18446744071562067984) at memalloc.c:57 #6 0x000000000040ca78 in stalloc (nbytes=18446744071562067972) at memalloc.c:132 #7 0x000000000040ece9 in grabstackblock (len=18446744071562067972) at memalloc.h:67 #8 0x00000000004106b5 in readtoken1 (firstc=118, syntax=0x419522 "", eofmark=0x0, striptabs=0) at parser.c:1040 #9 0x00000000004101a4 in xxreadtoken () at parser.c:826 #10 0x000000000040fe1d in readtoken () at parser.c:697 #11 0x000000000040edcc in parsecmd (interact=0) at parser.c:145 #12 0x000000000040c679 in cmdloop (top=1) at main.c:224 #13 0x000000000040c603 in main (argc=2, argv=0x7fffffffd9f8) at main.c:178 #8 0x00000000004106b5 in readtoken1 (firstc=118, syntax=0x419522 "", eofmark=0x0, striptabs=0) at parser.c:1040 1040 grabstackblock(len); (gdb) p len $30 = -2147483644 Signed-off-by: Jim Meyering <meyering@redhat.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2012-02-25[VAR] Sanitise environment variable names on entryHerbert Xu
On Tue, Feb 14, 2012 at 10:48:48AM +0000, harald@redhat.com wrote: > > "export -p" prints all environment variables, without checking if the > environment variable is a valid dash variable name. > > IMHO, the only valid usecase for "export -p" is to eval the output. > > $ eval $(export -p); echo OK > OK > > Without this patch the following test does error out with: > > test.py: > import os > os.environ["test-test"]="test" > os.environ["test_test"]="test" > os.execv("./dash", [ './dash', '-c', 'eval $(export -p); echo OK' ]) > > $ python test.py > ./dash: 1: export: test-test: bad variable name > > Of course the results can be more evil, if the environment variable > name is crafted, that it injects valid shell code. This patch fixes the issue by sanitising all environment variable names upon entry into the shell. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2011-08-17[SHELL] Add top-level autogen.shDavid S. Miller
Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2011-08-17[SHELL] Allow building without LINEO supportDavid S. Miller
Simply specify --disable-lineno to configure. Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2011-08-17[ARITH] Avoid imaxdiv when only one of the results is wantedHarald van Dijk
dash rather pointlessly calls imaxdiv, only to discard one of its results. The call was already made conditional a while back because some systems don't have imaxdiv, but the generated code for the version with imaxdiv and the one with / and % is identical (with GCC 4.6.1 or ICC 12.0.2, with -O0, -O2 or -Os), so it could just as well go entirely to clean up the code a little bit. Signed-off-by: Harald van Dijk <harald@gigawatt.nl> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2011-07-15[SHELL] Fix klibc DEBUG compilationmaximilian attems
dash didn't compile in DEBUG mode against klibc for all long time. Now it only fails at link stage for not having setlinebuf(3) and freopen(3). Fixes: usr/dash/show.o: In function `opentrace': show.c:(.text+0x36): undefined reference to `freopen' show.c:(.text+0x86): undefined reference to `setlinebuf' Skip setlinebuf and use fclose/fopen inside __KLIBC__ Compile tested with debug in klibc and against glibc in dash repo. Signed-off-by: maximilian attems <max@stro.at> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2011-07-09[BUILTIN] Merge SKIPFUNC/SKIPFILE and only clear SKIPFUNC when leaving dotcmdHerbert Xu
Currently upon leaving a dotcmd the evalskip state is reset so if a continue/break statement is used within a dot script it would have no effect outside of the dot script. This is inconsistent with other shells. This patch is based on one by Jilles Tjoelker and only clears SKIPFUNC when leaving a dot script. As a result continue/break will remain in effect. It also merges SKIPFUNC/SKIPFILE as they have no practical difference. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2011-07-08Release 0.5.7.Herbert Xu
2011-07-08[EVAL] Avoid using undefined handlerJim Meyering
* src/eval.c (evalbltin, evalfun): Set savehandler before calling setjmp with the possible "goto *done", where savehandler is used. Otherwise, clang warns that "Assigned value is garbage or undefined" at the point where "savehandler" is used on the RHS. Signed-off-by: Jim Meyering <meyering@redhat.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2011-07-08[MEMALLOC] Avoid clang warning about dead store to "size"Jim Meyering
* src/memalloc.c (makestrspace): Remove dead store. Signed-off-by: Jim Meyering <meyering@redhat.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2011-07-08[MEMALLOC] Avoid gcc warning: variable 'oldstackp' set but not usedJim Meyering
* src/memalloc.c (growstackblock): Remove declaration and set of set-but-not-used variable. Also remove a stray space-before-TAB. Signed-off-by: Jim Meyering <meyering@redhat.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2011-07-07[BUILTIN] Eliminate unnecessary promotion in echocmdHerbert Xu
The patch to make outc into an inline function created an unnecessary promotion in echocmd due to its use of char vs. the int used by outc. This patch changes echocmd to use int instead. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2011-07-07[OUTPUT] Make outc an inline functionJonathan Nieder
As "gcc -pedantic" warns, ISO C forbids conditional expressions with only one void side. So the (needslow ? slowpath() : fastpath) code for outc in the !USE_GLIBC_STDIO case might not be portable. More importantly, it's hard to read. Rip it out and replace it with an inline function which should generate the same code. Reported-by: Szabolcs Nagy <nsz@port70.net> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2011-07-07[MAN] Remove spurious space in descriptions of PS1, PS2, PS4Kalle Olavi Niemitalo
From: Kalle Olavi Niemitalo <kon@iki.fi> LANG=C man dash shows: PS1 The primary prompt string, which defaults to ``$ '', unless you are the superuser, in which case it defaults to ``# ''. PS2 The secondary prompt string, which defaults to ``> ''. PS4 Output before each line when execution trace (set -x) is enabled, defaults to ``+ ''. Each of the documented default values has a graphic character and two spaces between the quotation marks. However, the actual default values have only one space, rather than two. Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2011-07-07[SHELL] Optimize dash -c "command" to avoid a forkHerbert Xu
On Sun, Apr 10, 2011 at 07:36:49AM +0000, Jonathan Nieder wrote: > From: Jilles Tjoelker <jilles@stack.nl> > Date: Sat, 13 Jun 2009 16:17:45 -0500 > > This change only affects strings passed to -c, when the -s option is > not used. > > Use the EV_EXIT flag to inform the eval machinery that the string > being passed is the entirety of input. This way, a fork may be > omitted in many special cases. > > If there are empty lines after the last command, the evalcmd will not > see the end early enough 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. > > [jn: ported from FreeBSD SVN r194128. Bugs are mine.] > > Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Instead of detecting EOF using the input layer, I'm going to use the parser instead. In either case, we always have to read ahead in order to complete the parsing of the previous node. Therefore we always know whether there is more to come, except in the case where we see a newline/semicolon or similar. For the purposes of sh -c, this should be sufficient. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2011-07-07[EVAL] Remove unused EV_BACKCMD flagJonathan Nieder
The original ash defered forking commands in backquotes so builtins could be run in the same context as the shell. This behavior was controlled using the EV_BACKCMD to evaltree. Unfortunately, as Matthias Scheler noticed in 1999 (NetBSD PR/7814), the result was counterintuitive; for example, echo "`cd /`" would change the cwd. So ash 0.3.5 left out that optimization. The EV_BACKCMD codepath stayed around, unused. Some time between ash 0.3.5-11 and ash 0.3.8-37, Debian ash omitted the EV_BACKCMD pathway by guarding it with #ifdef notyet. In dash 0.5.1 and later, the commented code is no more. Let's finish the job and remove the last vestiges. If someone wants to work on omitting the fork in backcmd, the remaining hints are not going to be very helpful, anyway. Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2011-03-15[PARSER] Fix clobbering of checkkwdHerbert Xu
On Sun, Nov 07, 2010 at 02:21:21AM +0000, Jonathan Nieder wrote: > > Just ran into some strange behavior: > > $ cat test.sh > #!/bin/sh > echo hello >greeting > cat <<EOF && > $(cat greeting) > EOF > { > echo $? > cat greeting > } >/dev/null > > > $ sh test.sh > hello > test.sh: 7: {: not found > 127 > hello > test.sh: 10: Syntax error: "}" unexpected > > bash, mksh, pdksh, and ksh93 all print hello as expected. The problem > is reproducible with all versions of dash in the git repo. This is caused by the clobbering of checkkwd due to readtoken recursion while parsing a here document. This patch fixes it by saving the original value of checkkwd. Reported-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2011-03-15[DEBUG] Use va_copy when reusing a va_listJonathan Nieder
When tracing (with the DEBUG compile-time option set to 1 or 2), exverror calls TRACEV to print its arguments before passing them on. So the arguments are consumed by the time exvwarning looks for them, resulting in a segfault: $ sh -c '"' sh: Syntax error: Unterminated quoted string $ sh -o debug -c '"' sh: Segmentation fault (core dumped) Make a copy with va_copy to avoid this. Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2011-03-15[EXPAND] Free IFS state after here document expansionJonathan Nieder
Here's another bug bisecting to f42e443bb ([EXPAND] Fix ifsfirst/ifslastp leak, 2010-09-08). It was found with the following test case, based on the configure script for Tracker: dash -x -c ' <<-_ACEOF $@ _ACEOF exec ' - abcdefgh + + exec �a exec: 1: : Permission denied The missing ifsfree call is in expandarg when it returns to openhere during here document expansion. Reported-by: Aurelien Jarno <aurel32@debian.org> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2011-03-15[SHELL] Improve LINENO supportHarald van Dijk
This patch improves LINENO support by storing line numbers in the parse tree, for commands as well as for function definitions. It makes LINENO behaves properly when calling functions, and has the added benefit of improved line numbers in error messages when the last-parsed command is not the last-executed one. It removes the earlier LINENO support, and instead sets LINENO from evaltree when a command is executed Signed-off-by: Harald van Dijk <harald@gigawatt.nl> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2011-03-15[EVAL] Let funcnode refer to a function definition, not its first commandHarald van Dijk
It is not unrelated: I changed the meaning of struct funcnode's field n to refer to the function definition, rather than the list of the function's commands, because I needed to refer to the function definition node from evalfun, which only gets passed a funcnode. But it is something that could be applied independently (without being useful by itself), so I've attached it as a separate patch for easier review. Signed-off-by: Harald van Dijk <harald@gigawatt.nl> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2011-03-15[SHELL] Port to SolarisBrian Koropoff
- Solaris lacks paths.h and the various _PATH_* #defines. Check for them in configure.ac and fall back on the usual suspects when they are missing. - Older Solaris lacks isblank(), and versions that have it use a macro. Check for the declaration in configure.ac and fall back on a naive version when missing. - Older Solaris does not support %jd (intmax_t) in format strings, but it does support the PRIdMAX macro from inttypes.h. Do a configure check for PRIdMAX and use it in the code. If it doesn't exist, define it to "lld" when sizeof(long long) equals sizeof(intmax_t) as this is more likely to work on older systems. Otherwise, use "jd" and hope for the best. - Older Solaris lacks stdint.h, but inttypes.h provides the same types and works on all platforms I've tried dash on, so just use it instead. - Older Solaris doesn't like it when vsnprintf() is passed a NULL buffer (in violation of the POSIX spec, of course). Pass a 1-byte dummy buffer instead. - Solaris lacks tempfile and mktemp programs. Fall back on a "good-enough" custom function in mkbuiltins. Signed-off-by: Brian Koropoff <bkoropoff@gmail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2011-03-11[BUILTIN] Fix backslash handling in read(1)Herbert Xu
The new read(1) implementation incorrectly assumes that ifsbreakup ignores characters escaped by CTLESC. As such it fails to handle backslashes except for escaping newlines. This patch makes it use recordregion for every part that isn't escaped by a backslash. Reported-by: Jilles Tjoelker <jilles@stack.nl> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2011-03-10[BUILTIN] Dotcmd should exit with zero when doing nothingJonathan Nieder
Tim Allen wrote: > The POSIX specification for the dot command[1] states: > > EXIT STATUS > Returns the value of the last command executed, or a zero exit > status if no command is executed. > > If an empty file is sourced, then "no command is executed" I agree. Looking through "git log --patch src/main.c", though, I find v0.5.3~42 (Do not clobber exit status in dotcmd., 2005-03-03), which appears to have been meant to take care of the following case: $ cat printstatus.sh echo $? $ false $ . ./printstatus.sh 1 I wonder if the following on top might help (imitating evalcmd)? Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>