diff --git a/sys/shell/shell.c b/sys/shell/shell.c index 297344043f..d03faac2e3 100644 --- a/sys/shell/shell.c +++ b/sys/shell/shell.c @@ -38,7 +38,8 @@ #include "shell.h" #include "shell_commands.h" -#define ETX '\x03' /** ASCII "End-of-Text", or ctrl-C */ +#define ETX '\x03' /** ASCII "End-of-Text", or Ctrl-C */ +#define EOT '\x04' /** ASCII "End-of-Transmission", or Ctrl-D */ #define BS '\x08' /** ASCII "Backspace" */ #define DEL '\x7f' /** ASCII "Delete" */ @@ -411,6 +412,9 @@ static int readline(char *buf, size_t size) switch (c) { + case EOT: + /* Ctrl-D terminates the current shell instance. */ + /* fall-thru */ case EOF: return EOF; diff --git a/tests/shell/main.c b/tests/shell/main.c index 5afa5f51ec..23f7c67021 100644 --- a/tests/shell/main.c +++ b/tests/shell/main.c @@ -97,13 +97,18 @@ static const shell_command_t shell_commands[] = { int main(void) { - printf("test_shell.\n"); /* define buffer to be used by the shell */ char line_buf[SHELL_DEFAULT_BUFSIZE]; /* define own shell commands */ + shell_run_once(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE); + + puts("shell exited"); + + /* Restart the shell after the previous one exits, so that we can test + * Ctrl-D exit */ shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE); /* or use only system shell commands */ diff --git a/tests/shell/tests/01-run.py b/tests/shell/tests/01-run.py index e74e7dfa0d..2d180e32b8 100755 --- a/tests/shell/tests/01-run.py +++ b/tests/shell/tests/01-run.py @@ -182,6 +182,19 @@ def check_erase_long_line(child, longline): child.expect_exact('"echo"') +def check_control_d(child): + # The current shell instance was initiated by shell_run_once(). The shell will exit. + child.sendline(CONTROL_D) + child.expect_exact('shell exited') + + # The current shell instance was initiated by shell_run(). The shell will respawn + # automatically except on native. On native, RIOT is shut down completely, + # therefore exclude this part. + if BOARD != 'native': + child.sendline(CONTROL_D) + child.expect_exact(PROMPT) + + def testfunc(child): # avoid sending an extra empty line on native. if BOARD == 'native': @@ -199,6 +212,8 @@ def testfunc(child): check_erase_long_line(child, longline) + check_control_d(child) + # loop other defined commands and expected output for cmd, expected in CMDS: check_cmd(child, cmd, expected)