9
0
Fork 0

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 <s.hauer@pengutronix.de>
This commit is contained in:
Sascha Hauer 2012-08-10 12:40:01 +02:00
parent 58713d3274
commit 16edced39e
2 changed files with 31 additions and 25 deletions

View File

@ -38,26 +38,6 @@
LIST_HEAD(command_list);
EXPORT_SYMBOL(command_list);
#ifdef CONFIG_SHELL_HUSH
static int do_exit(int argc, char *argv[])
{
int r;
r = 0;
if (argc > 1)
r = simple_strtoul(argv[1], NULL, 0);
return -r - 2;
}
BAREBOX_CMD_START(exit)
.cmd = do_exit,
.usage = "exit script",
BAREBOX_CMD_END
#endif
void barebox_cmd_usage(struct command *cmdtp)
{
#ifdef CONFIG_LONGHELP

View File

@ -557,6 +557,18 @@ static int builtin_getopt(struct p_context *ctx, struct child_prog *child,
}
#endif
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);
else
ret = execute_binfmt(globbuf.gl_pathc, globbuf.gl_pathv);
@ -1885,16 +1899,28 @@ BAREBOX_CMD_START(source)
BAREBOX_CMD_HELP(cmd_source_help)
BAREBOX_CMD_END
#ifdef CONFIG_HUSH_GETOPT
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"
"\n"
"exit script with a status of n. If n is omitted, the exit status is that\n"
"of the last command executed\n";
BAREBOX_CMD_START(exit)
.cmd = do_dummy_command,
.usage = "exit script",
BAREBOX_CMD_HELP(cmd_exit_help)
BAREBOX_CMD_END
#ifdef CONFIG_HUSH_GETOPT
static const __maybe_unused char cmd_getopt_help[] =
"Usage: getopt <optstring> <var>\n"
"\n"
@ -1905,7 +1931,7 @@ static const __maybe_unused char cmd_getopt_help[] =
"can be accessed starting from $1\n";
BAREBOX_CMD_START(getopt)
.cmd = do_getopt,
.cmd = do_dummy_command,
.usage = "getopt <optstring> <var>",
BAREBOX_CMD_HELP(cmd_getopt_help)
BAREBOX_CMD_END