summaryrefslogtreecommitdiffstats
path: root/bin/sh
diff options
context:
space:
mode:
authorjilles <jilles@FreeBSD.org>2013-09-04 22:10:16 +0000
committerjilles <jilles@FreeBSD.org>2013-09-04 22:10:16 +0000
commitad7328341af15585f1dee4fbb63f288d2b2917e2 (patch)
tree00235be2a41fac24160537f8172d9ce83957898a /bin/sh
parent206a10e8a633f64ba34396341d375e620bba21d2 (diff)
downloadFreeBSD-src-ad7328341af15585f1dee4fbb63f288d2b2917e2.zip
FreeBSD-src-ad7328341af15585f1dee4fbb63f288d2b2917e2.tar.gz
sh: Make return return from the closest function or dot script.
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
Diffstat (limited to 'bin/sh')
-rw-r--r--bin/sh/eval.c14
-rw-r--r--bin/sh/eval.h3
-rw-r--r--bin/sh/main.c2
-rw-r--r--bin/sh/sh.16
4 files changed, 10 insertions, 15 deletions
diff --git a/bin/sh/eval.c b/bin/sh/eval.c
index 655bf81..b8f76d5 100644
--- a/bin/sh/eval.c
+++ b/bin/sh/eval.c
@@ -324,7 +324,7 @@ skipping: if (evalskip == SKIPCONT && --skipcount <= 0) {
}
if (evalskip == SKIPBREAK && --skipcount <= 0)
evalskip = 0;
- if (evalskip == SKIPFUNC || evalskip == SKIPFILE)
+ if (evalskip == SKIPRETURN)
status = exitstatus;
break;
}
@@ -1068,7 +1068,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
funcnest--;
popredir();
INTON;
- if (evalskip == SKIPFUNC) {
+ if (evalskip == SKIPRETURN) {
evalskip = 0;
skipcount = 0;
}
@@ -1305,14 +1305,8 @@ returncmd(int argc, char **argv)
{
int ret = argc > 1 ? number(argv[1]) : oexitstatus;
- if (funcnest) {
- evalskip = SKIPFUNC;
- skipcount = 1;
- } else {
- /* skip the rest of the file */
- evalskip = SKIPFILE;
- skipcount = 1;
- }
+ evalskip = SKIPRETURN;
+ skipcount = 1;
return ret;
}
diff --git a/bin/sh/eval.h b/bin/sh/eval.h
index a6e87b2..4129757 100644
--- a/bin/sh/eval.h
+++ b/bin/sh/eval.h
@@ -67,5 +67,4 @@ extern int skipcount;
/* reasons for skipping commands (see comment on breakcmd routine) */
#define SKIPBREAK 1
#define SKIPCONT 2
-#define SKIPFUNC 3
-#define SKIPFILE 4
+#define SKIPRETURN 3
diff --git a/bin/sh/main.c b/bin/sh/main.c
index 295f277..e4974ea 100644
--- a/bin/sh/main.c
+++ b/bin/sh/main.c
@@ -231,7 +231,7 @@ cmdloop(int top)
popstackmark(&smark);
setstackmark(&smark);
if (evalskip != 0) {
- if (evalskip == SKIPFILE)
+ if (evalskip == SKIPRETURN)
evalskip = 0;
break;
}
diff --git a/bin/sh/sh.1 b/bin/sh/sh.1
index 174788d..ea1d899 100644
--- a/bin/sh/sh.1
+++ b/bin/sh/sh.1
@@ -1145,8 +1145,10 @@ command is
.Pp
.D1 Ic return Op Ar exitstatus
.Pp
-It terminates the current executional scope, returning from the previous
-nested function, sourced script, or shell instance, in that order.
+It terminates the current executional scope, returning from the closest
+nested function or sourced script;
+if no function or sourced script is being executed,
+it exits the shell instance.
The
.Ic return
command is implemented as a special built-in command.
OpenPOWER on IntegriCloud