Commit Graph

737 Commits

Author SHA1 Message Date
christos 2e317a68f7 PR/48843: Jarmo Jaakkola: Soften the language in the manual page,
making less promises about behavior not explicitly stated in the standard.
2014-06-01 17:46:06 +00:00
christos 01f35fcceb PR/48843: Jarmo Jaakkola: dot commands mess up scope nesting tracking
Evaluation of commands goes completely haywire if a file containing
a break/continue/return command outside its "intended" scope is sourced
using a dot command inside its "intended" scope.  The main symptom is
not exiting from the sourced file when supposed to, leading to evaluation
of commands that were not supposed to be evaluated.  A secondary symptom
is that these extra commands are not evaluated correctly, as some of them
are skipped.  Some examples are listed in the How-To-Repeat section.

According to the POSIX standard, this is how it should work:
    dot:
        The shell shall execute commands from the file in the current
        environment.
    break:
        The break utility shall exit from the smallest enclosing for, while,
        or until loop, [...]
    continue:
        The continue utility shall return to the top of the smallest
        enclosing for, while, or until loop, [...]
    return:
        The return utility shall cause the shell to stop executing
        the current function or dot script.  If the shell is not currently
        executing a function or dot script, the results are unspecified.

It is clear that return should return from a sourced file, which
it does not do.  Whether break and continue should work from the sourced
file might be debatable.  Because the dot command says "in the current
environment", I'd say yes.  In any case, it should not fail in weird
ways like it does now!

The problems occur with return (a) and break/continue (b) because:
    1)  dotcmd() does not record the function nesting level prior to
        sourcing the file nor does it touch the loopnest variable,
        leading to either
    2   a) returncmd() being unable to detect that it should not set
           evalskip to SKIPFUNC but SKIPFILE, or
        b) breakcmd() setting evalskip to SKIPCONT or SKIPBREAK,
        leading to
    3)  cmdloop() not detecting that it should skip the rest of
        the file, due to only checking for SKIPFILE.
The result is that cmdloop() keeps executing lines from the file
whilst evalskip is set, which is the main symptom.  Because
evalskip is checked in multiple places in eval.c, the secondary
symptom appears.
>How-To-Repeat:
Run the following script:

    printf "break\necho break1; echo break2" >break
    printf "continue\necho continue1; echo continue2" >continue
    printf "return\necho return1; echo return2" >return

    while true; do . ./break; done

    for i in 1 2; do . ./continue; done

    func() {
        . ./return
    }
    func

No output should be produced, but instead this is the result:
    break1
    continue1
    continue1
    return1

The main symptom is evident from the unexpected output and the secondary
one from the fact that there are no lines with '2' in them.
>Fix:
Here is patch to src/bin/sh to fix the above problems.  It keeps
track of the function nesting level at the beginning of a dot command
to enable the return command to work properly.

I also changed the undefined-by-standard functionality of the return
command when it's not in a dot command or function from (indirectly)
exiting the shell to being silently ignored.  This was done because
the previous way has at least one bug: the shell exits without asking
for confirmation when there are stopped jobs.

Because I read the standard to mean that break and continue should have
an effect outside the sourced file, that's how I implemented it.  For what
it's worth, this also seems to be what bash does.  Also laziness, because
this way required no changes to loopnesting tracking.  If this is not
wanted, it might make sense to move the nesting tracking to the inputfile
stack.

The patch also does some clean-up to reduce the amount of global
variables by moving the dotcmd() and the find_dot_file() functions from
main.c to eval.c and making in_function() a proper function.
2014-05-31 14:42:18 +00:00
christos 318c2b5cda PR/48729: Torbjörn Granlund: Avoid negative index in array ref. 2014-04-11 01:49:45 +00:00
dholland c4044741ea don't use sprintf 2014-03-23 05:07:59 +00:00
christos 1468e9a310 explain why forks fail 2014-01-26 22:38:20 +00:00
roy 7969ec4d55 Add wctype(3) support to Shell Patterns.
Obtained from FreeBSD.
2014-01-20 14:05:51 +00:00
christos bc1be752a1 whitespace fixes 2014-01-01 19:50:44 +00:00
christos 316fbf0f9f There was a case where \n did not increase plinno 2014-01-01 19:06:45 +00:00
christos 87802d4338 clarify further. 2014-01-01 18:29:39 +00:00
christos 724ab0808b explain the previous fix. 2014-01-01 16:55:28 +00:00
christos 9bcdabb166 allow case statement without any patterns. 2013-12-31 22:53:57 +00:00
christos 5c83aa644a PR/48312: Dieter Roelands: According to TOG, unset should not return an error
for functions are variables that were not previously set:
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
2013-11-01 16:49:02 +00:00
mrg 5a3d1851d6 #ifdef a variable decl/setting with it's use. 2013-10-30 08:38:40 +00:00
ast 83d9b54597 Fix PR bin/48202 [non-critical/low]:
sh +nounset and `for X; do` iteration fails if parameter set empty
by applying and testing FreeBSD's patch of Oct 24 2009 for this; see
  http://svnweb.freebsd.org/base/head/bin/sh/expand.c?r1=198453&r2=198454
Also created an ATF test in tests/bin/sh/t_expand.sh for this error and
corrected a space->tabs problem there as well.
2013-10-06 21:05:50 +00:00
christos b258a62a64 add stdio.h 2013-10-02 21:48:55 +00:00
christos ca8473e079 document LINENO
XXX: someone should fix all the .Ev stuff because some of them are just
shell variables .Va and are not really exported to the environment. See
the FreeBSD man page.
2013-10-02 20:42:56 +00:00
christos 018a6f7864 add crude $LINENO support for FreeBSD 2013-10-02 19:52:58 +00:00
yamt 44f7683783 fix descriptor leaks. PR/47805
this fix was taken from FreeBSD SVN rev 199953 (Jilles Tjoelker)
    ------------------------------------------------------------------------
    r199953 | jilles | 2009-11-30 07:33:59 +0900 (Mon, 30 Nov 2009) | 16 lines

    Fix some cases where file descriptors from redirections leak to programs.

    - 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.
2013-06-27 23:22:04 +00:00
yamt 071e965c48 constify 2013-06-12 01:36:52 +00:00
simonb 3a5cb7b1be Document that a here-document can finish at an EOF as well as at the
delimiter.
2013-05-09 11:43:27 +00:00
dholland 7e346d08a4 Add const. 2013-04-28 17:01:28 +00:00
christos 2135348107 PR/47608: Robert Elz: ``var=value func-call'' does not export var in the
function (+FIX)
2013-03-02 22:02:32 +00:00
dsl 0e82f4eb77 include limits.h for CHAR_MIN 2013-01-02 22:28:42 +00:00
dsl 658a58d038 Add support for '%n' being a shorthand for 'fg %n'. 2012-12-31 14:10:15 +00:00
dsl 7d60739ae7 Fix the expansion of "$(foo-$bar}" so that IFS isn't applied when
expanding $bar.
Noted by Greg Troxel on tech-userlevel running some 'git' tests.
Should fix PR bin/47361
2012-12-22 20:15:22 +00:00
christos 6814c65d63 PR/47317: Henning Petersen: Replace index() with strchr() 2012-12-13 19:33:23 +00:00
apb ee9a2498cf Adjust everything under src (but outside src/tools) to use
the TOOLDIR version of libnbcompat, associated include files,
and associated defs.mk file, instead of the version from the
.OBJDIR of src/tools/compat.  This should fix PR 47188.
2012-12-02 12:55:27 +00:00
wiz f8c0e3497a - Correct macro usage;
- improve wording, including creating more consistency therein.

From Bug Hunting.
2012-10-03 19:37:36 +00:00
wiz c650101e34 - improve punctuation;
- improve (create more consistency in) spelling;
- remove unnecessary (and in part ignored) macros, as well as an
  unnecessary argument to `.Bl' (fixes mandoc(1) warnings);
- improve wording;
- bump date.

Patch from Bug Hunting.
2012-08-26 14:30:38 +00:00
wiz 123b56dc76 Initialize two variables for clang. 2012-06-17 20:48:27 +00:00
joerg 0adfd5e0b3 Make sure temp_path is always initialised, even if mklocal fails.
Make sure to restore localvars, even if possibly leaking memory.
Discussed with christos@
2012-06-14 18:56:54 +00:00
njoly 089201c2fd Allow thread limit queries by adding the new -r flag to ulimit. Add
the corresponding documentation in the man page.
2012-06-11 18:28:10 +00:00
christos 426530cc5c support RLIMIT_NTHR. 2012-06-09 02:49:48 +00:00
christos a080d61232 include <limits.h> for CHAR_MIN/CHAR_MAX 2012-03-28 20:11:25 +00:00
christos 1cd38287c6 PR/43597: Don't break from parsing word tokens in we are in double quotes.
Fixes: sh -c 'echo "${foo:="first-word"} second-word"'
2012-03-25 18:49:13 +00:00
matt da4f7877a7 Use C89 function definitions 2012-03-20 18:42:28 +00:00
joerg 66dd2755f5 Add __printflike attribution to use vprintf and friends with an argument
as format string.
2012-03-15 02:02:20 +00:00
joerg a401c50446 Don't use a for-loop with empty body. 2012-02-23 18:23:33 +00:00
christos 1847bab548 PR/45613: Aleksey Cheusov: /bin/sh: 'set -e' + 'if eval false' problem
Fixed from: http://www.freebsd.org/cgi/query-pr.cgi?pr=134881&cat=
2011-11-14 18:24:45 +00:00
christos 13d04b5999 print the flag too next to the units like bash does. 2011-10-11 15:27:11 +00:00
christos 790e94dff8 Merge duplicate information. 2011-10-05 13:15:30 +00:00
apb b0bdcb0f27 .Dq Dv \&: 2011-10-04 18:11:27 +00:00
christos 113ec67ab4 Mention what happens when we don't include :. It would be nice to use
.Dv :
but it produces ``'':
2011-10-04 18:07:39 +00:00
dholland d88c027e8a A feature that wasn't implemented for 4.4alpha and still isn't implemented
is just plain not implemented.
2011-09-11 06:02:20 +00:00
plunky 9f61b80465 NULL does not need a cast 2011-08-31 16:24:54 +00:00
joerg 490b73bf85 Mark yyerror as static and __dead. 2011-08-29 14:50:27 +00:00
christos 0404783632 document another non-literal format string 2011-08-23 10:47:06 +00:00
christos 69a4e2ee5b PR/45269: Andreas Gustafsson: Instead of falling off the edge when eating trailing newlines
if the block has moved, arrange so that trailing newlines are never placed in the string
in the first place, by accumulating them and adding them only after we've encountered a
non-newline character. This allows also for more efficient appending since we know how much
we need beforehand. From FreeBSD.
2011-08-23 10:04:39 +00:00
christos d452d7e758 - add pid to the trace file so that we don't keep overwriting ourselves
- use va_copy to print the trace arguments so that we don't deplete it for the real printf
2011-08-23 10:01:32 +00:00
christos 819193d44d add more gcc printf format attributes 2011-08-23 09:59:20 +00:00