libmisc/shell: Fix the handling of joel scripts in telnet

- Fix the passing of std[in/out] to child threads
- Fix deleting of managed memory in the key destructor
- Only set the key in the main loop thread
- Only allocate a shell env outside of the main loop
- Fix memory leak if the task start fails
- Remove error level from shell env, it cannot be returned this way. Add
  exit_code but the API is broken so it cannot be returned.

Closes #3859
This commit is contained in:
Chris Johns committed 2020-04-15 08:30:30 +10:00
1 parent 4f32722e33
commit d007cc2cee
3 files changed
+395 -106

No files matched your search

+6 -1
View File
@@ -220,16 +220,21 @@ extern rtems_status_code rtems_shell_script(
typedef struct {
/** 'S','E','N','V': Shell Environment */
rtems_name magic;
bool managed;
const char *devname;
const char *taskname;
bool exit_shell; /* logout */
bool forever; /* repeat login */
int errorlevel;
int *exit_code;
bool exit_on_error;
bool echo;
char cwd[256];
const char *input;
const char *output;
bool output_append;
FILE *parent_stdin;
FILE *parent_stdout;
FILE *parent_stderr;
rtems_id wake_on_end;
rtems_shell_login_check_t login_check;
File diff suppressed because it is too large. Load diff
+120 -3
View File
@@ -50,6 +50,122 @@ static const char etc_group[] =
"E::7:y,z\n"
"F::8:s,moop,t\n";
static const char joel_in[] =
"#! joel\n"
"jtst hello world\n"
"jtst 1 2 3 4 5\n";
static const char joel_out_1[] =
" 3 'jtst hello world'\n"
" 6 'jtst 1 2 3 4 5'\n";
static const char joel_out_2[] =
"\n"
"RTEMS Shell on (null). Use 'help' to list commands.\n"
" 3 'jtst hello world'\n"
" 6 'jtst 1 2 3 4 5'\n";
static int joel_test_command(int argc, char** argv)
{
int i;
fprintf(stdout, "%2d '", argc);
for (i = 0; i < argc; ++i) {
fprintf(stdout, argv[i]);
if (i < (argc - 1))
fprintf(stdout, " ");
}
fprintf(stdout, "'\n");
return 0;
}
static void test_joel(void)
{
/*
* Running a joel script tests the shell main loop.
*/
char buf[sizeof(joel_out_2) + 1];
rtems_shell_cmd_t* cmd;
FILE *in;
FILE *out;
FILE *current_stdout = stdout;
FILE *current_stdin = stdin;
size_t len;
rtems_status_code sc;
/*
* Use a private command due to the way the testsuite maps printk onto printf.
*/
cmd = rtems_shell_add_cmd("jtst", "misc", "joel test", joel_test_command);
rtems_test_assert(cmd != NULL);
len = strlen(joel_in);
in = fopen("/jin", "w");
rtems_test_assert(in != NULL);
rtems_test_assert(fwrite(joel_in, sizeof(char), len, in) == len);
rtems_test_assert(fclose(in) == 0);
/*
* The shell opens the input and output files.
*/
sc = rtems_shell_script(
"JTST",
8 * 1024,
1,
"/jin",
"/jout",
false,
true,
false);
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
out = fopen("/jout", "r");
rtems_test_assert(out != NULL);
rtems_test_assert(!feof(out));
memset(buf, 0, sizeof(buf));
len = fread(buf, sizeof(char), sizeof(buf), out);
rtems_test_assert(len > 0);
rtems_test_assert(strcmp(joel_out_1, buf) == 0);
rtems_test_assert(fclose(out) == 0);
/*
* The shell task inherits the parent stdin and stdout
*/
in = fopen("/jin", "r");
rtems_test_assert(in != NULL);
out = fopen("/jout", "w");
rtems_test_assert(out != NULL);
stdin = in;
stdout = out;
sc = rtems_shell_script(
"JTST",
8 * 1024,
1,
"stdin",
"stdout",
false,
true,
false);
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
stdout = current_stdout;
stdin = current_stdin;
rtems_test_assert(fclose(in) == 0);
rtems_test_assert(fclose(out) == 0);
out = fopen("/jout", "r");
rtems_test_assert(out != NULL);
rtems_test_assert(!feof(out));
memset(buf, 0, sizeof(buf));
len = fread(buf, sizeof(char), sizeof(buf), out);
rtems_test_assert(len > 0);
rtems_test_assert(strcmp(joel_out_2, buf) == 0);
rtems_test_assert(fclose(out) == 0);
}
static void test(void)
{
rtems_user_env_t *uenv;
@@ -163,6 +279,7 @@ static void Init(rtems_task_argument arg)
TEST_BEGIN();
test();
test_joel();
TEST_END();
rtems_test_exit(0);
@@ -171,10 +288,10 @@ static void Init(rtems_task_argument arg)
#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 4
#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 5
#define CONFIGURE_MAXIMUM_TASKS 1
#define CONFIGURE_MAXIMUM_POSIX_KEYS 1
#define CONFIGURE_MAXIMUM_TASKS 3
#define CONFIGURE_MAXIMUM_POSIX_KEYS 2
#define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS 2
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION