path: root/common/hush.c
diff options
authorSascha Hauer <>2012-08-10 12:40:01 +0200
committerSascha Hauer <>2012-08-10 20:59:55 +0200
commit16edced39ecf4c316179b72c01af249f85b36218 (patch)
tree6f11dee57e63318e6100e2f0b43a9c3b1b771c4b /common/hush.c
parent58713d32746d49ad39ba17658fe82f1b98b80b2e (diff)
hush: Make exit a shell builtin
'exit' used to do its job by returning value < 0. This is a sign for hush that 'exit' is executed. This has problems: - Often commands accidently return a negative value. This causes the shell to exit. - execute_binfmt returns a negative value when it does not find a binary to execute. This again causes the shell to exit. Returning a negative error value seems to be the right thing to do, but catching this in the shell would mean that the exit command does not work anymore. - if called without arguments exit is supposed to return the code of the last command. As a command exit has no access to this code. This patch changes exit to be a builtin and also fixes the last return code problem. While at it, update the help text. Signed-off-by: Sascha Hauer <>
Diffstat (limited to 'common/hush.c')
1 files changed, 31 insertions, 5 deletions
diff --git a/common/hush.c b/common/hush.c
index 8200931..288114c 100644
--- a/common/hush.c
+++ b/common/hush.c
@@ -557,6 +557,18 @@ static int builtin_getopt(struct p_context *ctx, struct child_prog *child,
+static int builtin_exit(struct p_context *ctx, struct child_prog *child,
+ int argc, char *argv[])
+ int r;
+ r = last_return_code;
+ if (argc > 1)
+ r = simple_strtoul(argv[1], NULL, 0);
+ return -r - 2;
static void remove_quotes_in_str(char *src)
char *trg = src;
@@ -775,6 +787,8 @@ static int run_pipe_real(struct p_context *ctx, struct pipe *pi)
if (!strcmp(globbuf.gl_pathv[0], "getopt"))
ret = builtin_getopt(ctx, child, globbuf.gl_pathc, globbuf.gl_pathv);
+ else if (!strcmp(globbuf.gl_pathv[0], "exit"))
+ ret = builtin_exit(ctx, child, globbuf.gl_pathc, globbuf.gl_pathv);
ret = execute_binfmt(globbuf.gl_pathc, globbuf.gl_pathv);
@@ -1885,16 +1899,28 @@ BAREBOX_CMD_START(source)
-static int do_getopt(int argc, char *argv[])
+static int do_dummy_command(int argc, char *argv[])
- * This function is never reached. The 'getopt' command is
- * only here to provide a help text for the getopt builtin.
+ * This function is never reached. These commands are only here to
+ * provide help texts for the builtins.
return 0;
+static const __maybe_unused char cmd_exit_help[] =
+"Usage: exit [n]\n"
+"exit script with a status of n. If n is omitted, the exit status is that\n"
+"of the last command executed\n";
+ .cmd = do_dummy_command,
+ .usage = "exit script",
+ BAREBOX_CMD_HELP(cmd_exit_help)
static const __maybe_unused char cmd_getopt_help[] =
"Usage: getopt <optstring> <var>\n"
@@ -1905,7 +1931,7 @@ static const __maybe_unused char cmd_getopt_help[] =
"can be accessed starting from $1\n";
- .cmd = do_getopt,
+ .cmd = do_dummy_command,
.usage = "getopt <optstring> <var>",