Re: [PATCH] libmisc/shell: Fix the handling of joel scripts in telnet

2020-02-17 Thread Chris Johns
On 17/2/20 8:47 pm, Chris Johns wrote:
> 
>> On 17 Feb 2020, at 5:51 pm, Sebastian Huber 
>>  wrote:
>>
>> On 17/02/2020 07:05, chr...@rtems.org wrote:
>>> From: Chris Johns
>>> - 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
>>> - Work around #3970
>>> - 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
>>
>> Any changes required in existing Telnet application code after this patch?
> 
> No. The intention is to not break telnet.

Actually this may not be true, it depends on how the user has implemented their
telnet command. If it is similar to the libbsd telnet test it will build but
fail at runtime. The call `rtems_shell_dup_current_env` needs to be made. I am
going enforce this by checking the magic number in the struct in the shell main
loop call.

The libbsd telnet test needs to be ...

static void
telnet_shell(char *name, void *arg)
{
rtems_shell_env_t env;

rtems_shell_dup_current_env();

env.devname = name;
env.taskname = "TLNT";
env.login_check = NULL;
env.forever = false;

rtems_shell_main_loop();
}

The env dup call is present in 4.11.

Chris
___
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

[4.11 PATCH] libmisc/shell: Fix the handling of joel scripts in telnet

2020-02-17 Thread chrisj
From: Chris Johns 

- 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 #3877
---
 cpukit/libmisc/shell/shell.c   | 205 +++--
 cpukit/libmisc/shell/shell.h   |   9 +-
 testsuites/libtests/shell01/init.c | 123 -
 3 files changed, 265 insertions(+), 72 deletions(-)

diff --git a/cpukit/libmisc/shell/shell.c b/cpukit/libmisc/shell/shell.c
index 5f042f5855..fd2148acfd 100644
--- a/cpukit/libmisc/shell/shell.c
+++ b/cpukit/libmisc/shell/shell.c
@@ -40,20 +40,35 @@
 #include 
 #include 
 
+#define SHELL_STD_DEBUG 0
+
+#if SHELL_STD_DEBUG
+static FILE* default_stdout;
+#define shell_std_debug(...) fprintf(default_stdout, __VA_ARGS__)
+#else
+#define shell_std_debug(...)
+#endif
+
 const rtems_shell_env_t rtems_global_shell_env = {
   .magic = rtems_build_name('S', 'E', 'N', 'V'),
+  .managed   = false,
   .devname   = CONSOLE_DEVICE_NAME,
   .taskname  = "SHGL",
   .exit_shell= false,
   .forever   = true,
-  .errorlevel= -1,
   .echo  = false,
   .cwd   = "/",
   .input = NULL,
   .output= NULL,
   .output_append = false,
+  .parent_stdin  = NULL,
+  .parent_stdout = NULL,
+  .parent_stderr = NULL,
   .wake_on_end   = RTEMS_ID_NONE,
-  .login_check   = NULL
+  .exit_code = NULL,
+  .login_check   = NULL,
+  .uid   = 0,
+  .gid   = 0
 };
 
 static pthread_once_t rtems_shell_once = PTHREAD_ONCE_INIT;
@@ -64,7 +79,7 @@ static pthread_key_t rtems_shell_current_env_key;
  *  Initialize the shell user/process environment information
  */
 static rtems_shell_env_t *rtems_shell_init_env(
-  rtems_shell_env_t *shell_env_p
+  rtems_shell_env_t *shell_env_parent
 )
 {
   rtems_shell_env_t *shell_env;
@@ -72,11 +87,16 @@ static rtems_shell_env_t *rtems_shell_init_env(
   shell_env = malloc(sizeof(rtems_shell_env_t));
   if ( !shell_env )
 return NULL;
-  if ( !shell_env_p ) {
+
+  if ( shell_env_parent == NULL ) {
+shell_env_parent = rtems_shell_get_current_env();
+  }
+  if ( shell_env_parent == NULL ) {
 *shell_env = rtems_global_shell_env;
   } else {
-*shell_env = *shell_env_p;
+*shell_env = *shell_env_parent;
   }
+  shell_env->managed = true;
   shell_env->taskname = NULL;
 
   return shell_env;
@@ -92,14 +112,16 @@ static void rtems_shell_env_free(
   rtems_shell_env_t *shell_env;
   shell_env = (rtems_shell_env_t *) ptr;
 
-  if ( !ptr )
+  if ( ptr == NULL )
 return;
 
-  if ( shell_env->input )
-free((void *)shell_env->input);
-  if ( shell_env->output )
-free((void *)shell_env->output);
-  free( ptr );
+  if ( shell_env->managed ) {
+if ( shell_env->input )
+  free((void *)shell_env->input);
+if ( shell_env->output )
+  free((void *)shell_env->output);
+free( ptr );
+  }
 }
 
 static void rtems_shell_create_file(const char *name, const char *content)
@@ -131,6 +153,10 @@ static void rtems_shell_init_once(void)
   struct passwd pwd;
   struct passwd *pwd_res;
 
+#if SHELL_STD_DEBUG
+  default_stdout = stdout;
+#endif
+
   pthread_key_create(_shell_current_env_key, rtems_shell_env_free);
 
   /* dummy call to init /etc dir */
@@ -170,15 +196,22 @@ rtems_shell_env_t *rtems_shell_get_current_env(void)
 void rtems_shell_dup_current_env(rtems_shell_env_t *copy)
 {
   rtems_shell_env_t *env = rtems_shell_get_current_env();
-  if (env) {
+  if (env != NULL) {
 *copy = *env;
   }
   else {
-memset(copy, 0, sizeof(rtems_shell_env_t));
-copy->magic= rtems_build_name('S', 'E', 'N', 'V');
-copy->devname  = CONSOLE_DEVICE_NAME;
-copy->taskname = "RTSH";
+*copy = rtems_global_shell_env;
+copy->magic = rtems_build_name('S', 'E', 'N', 'V');
+copy->devname   = CONSOLE_DEVICE_NAME;
+copy->taskname  = "RTSH";
+copy->parent_stdout = stdout;
+copy->parent_stdin  = stdin;
+copy->parent_stderr = stderr;
   }
+  /*
+   * Duplicated environments are not managed.
+   */
+  copy->managed = false;
 }
 
 /*
@@ -707,10 +740,9 @@ static bool rtems_shell_init_user_env(void)
 #define RTEMS_SHELL_PROMPT_SIZE   (128)
 
 bool rtems_shell_main_loop(
-  rtems_shell_env_t *shell_env_arg
+  rtems_shell_env_t *shell_env
 )
 {
-  rtems_shell_env_t *shell_env;
   inteno;
   struct termios term;
   struct termios previous_term;
@@ -729,9 +761,8 @@ bool rtems_shell_main_loop(
 
   rtems_shell_init_environment();
 
-  shell_env = rtems_shell_init_env(shell_env_arg);
-  if (shell_env == NULL) {
-rtems_error(0, "rtems_shell_init_env");
+  if (shell_env->magic != rtems_build_name('S', 'E', 'N', 'V')) {
+rtems_error(0, "invalid shell environment passed 

Re: [PATCH] libmisc/shell: Fix the handling of joel scripts in telnet

2020-02-17 Thread Chris Johns

> On 17 Feb 2020, at 5:51 pm, Sebastian Huber 
>  wrote:
> 
> On 17/02/2020 07:05, chr...@rtems.org wrote:
>> From: Chris Johns
>> - 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
>> - Work around #3970
>> - 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
> 
> Any changes required in existing Telnet application code after this patch?

No. The intention is to not break telnet. 

Chris

___
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

Re: [PATCH] libmisc/shell: Fix the handling of joel scripts in telnet

2020-02-16 Thread Sebastian Huber

On 17/02/2020 07:05, chr...@rtems.org wrote:

From: Chris Johns

- 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
- Work around #3970
- 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


Any changes required in existing Telnet application code after this patch?

--
Sebastian Huber, embedded brains GmbH

Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone   : +49 89 189 47 41-16
Fax : +49 89 189 47 41-09
E-Mail  : sebastian.hu...@embedded-brains.de
PGP : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.
___
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

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

2020-02-16 Thread chrisj
From: Chris Johns 

- 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
- Work around #3970
- 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
---
 cpukit/include/rtems/shell.h   |   9 +-
 cpukit/libmisc/shell/shell.c   | 212 -
 testsuites/libtests/shell01/init.c | 121 +++-
 3 files changed, 270 insertions(+), 72 deletions(-)

diff --git a/cpukit/include/rtems/shell.h b/cpukit/include/rtems/shell.h
index 973db16605..71fc1dd8c7 100644
--- a/cpukit/include/rtems/shell.h
+++ b/cpukit/include/rtems/shell.h
@@ -217,19 +217,24 @@ extern rtems_status_code rtems_shell_script(
 /**
  *  Private environment associated with each shell instance.
  */
-typedef struct {
+typedef struct rtems_shell_env {
   /** '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;
 
diff --git a/cpukit/libmisc/shell/shell.c b/cpukit/libmisc/shell/shell.c
index c2ea3c4afa..208ea7cca6 100644
--- a/cpukit/libmisc/shell/shell.c
+++ b/cpukit/libmisc/shell/shell.c
@@ -20,6 +20,7 @@
 #include 
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -38,20 +39,35 @@
 #include 
 #include 
 
+#define SHELL_STD_DEBUG 0
+
+#if SHELL_STD_DEBUG
+static FILE* default_stdout;
+#define shell_std_debug(...) fprintf(default_stdout, __VA_ARGS__)
+#else
+#define shell_std_debug(...)
+#endif
+
 const rtems_shell_env_t rtems_global_shell_env = {
   .magic = rtems_build_name('S', 'E', 'N', 'V'),
+  .managed   = false,
   .devname   = CONSOLE_DEVICE_NAME,
   .taskname  = "SHGL",
   .exit_shell= false,
   .forever   = true,
-  .errorlevel= -1,
   .echo  = false,
   .cwd   = "/",
   .input = NULL,
   .output= NULL,
   .output_append = false,
+  .parent_stdin  = NULL,
+  .parent_stdout = NULL,
+  .parent_stderr = NULL,
   .wake_on_end   = RTEMS_ID_NONE,
-  .login_check   = NULL
+  .exit_code = NULL,
+  .login_check   = NULL,
+  .uid   = 0,
+  .gid   = 0
 };
 
 static pthread_once_t rtems_shell_once = PTHREAD_ONCE_INIT;
@@ -62,7 +78,7 @@ static pthread_key_t rtems_shell_current_env_key;
  *  Initialize the shell user/process environment information
  */
 static rtems_shell_env_t *rtems_shell_init_env(
-  rtems_shell_env_t *shell_env_p
+  rtems_shell_env_t *shell_env_parent
 )
 {
   rtems_shell_env_t *shell_env;
@@ -70,12 +86,17 @@ static rtems_shell_env_t *rtems_shell_init_env(
   shell_env = malloc(sizeof(rtems_shell_env_t));
   if ( !shell_env )
 return NULL;
-  if ( !shell_env_p ) {
+
+  if ( shell_env_parent == NULL ) {
+shell_env_parent = rtems_shell_get_current_env();
+  }
+  if ( shell_env_parent == NULL ) {
 *shell_env = rtems_global_shell_env;
-shell_env->taskname = NULL;
   } else {
-*shell_env = *shell_env_p;
+*shell_env = *shell_env_parent;
   }
+  shell_env->managed = true;
+  shell_env->taskname = NULL;
 
   return shell_env;
 }
@@ -90,14 +111,16 @@ static void rtems_shell_env_free(
   rtems_shell_env_t *shell_env;
   shell_env = (rtems_shell_env_t *) ptr;
 
-  if ( !ptr )
+  if ( ptr == NULL )
 return;
 
-  if ( shell_env->input )
-free((void *)shell_env->input);
-  if ( shell_env->output )
-free((void *)shell_env->output);
-  free( ptr );
+  if ( shell_env->managed ) {
+if ( shell_env->input )
+  free((void *)shell_env->input);
+if ( shell_env->output )
+  free((void *)shell_env->output);
+free( ptr );
+  }
 }
 
 static void rtems_shell_create_file(const char *name, const char *content)
@@ -129,6 +152,10 @@ static void rtems_shell_init_once(void)
   struct passwd pwd;
   struct passwd *pwd_res;
 
+#if SHELL_STD_DEBUG
+  default_stdout = stdout;
+#endif
+
   pthread_key_create(_shell_current_env_key, rtems_shell_env_free);
 
   /* dummy call to init /etc dir */
@@ -168,15 +195,22 @@ rtems_shell_env_t *rtems_shell_get_current_env(void)
 void rtems_shell_dup_current_env(rtems_shell_env_t *copy)
 {
   rtems_shell_env_t *env = rtems_shell_get_current_env();
-  if (env) {
+  if (env != NULL) {
 *copy = *env;
   }
   else {
-memset(copy, 0, sizeof(rtems_shell_env_t));
-copy->magic= rtems_build_name('S', 'E', 'N', 'V');
-copy->devname  = CONSOLE_DEVICE_NAME;
-copy->taskname = "RTSH";
+*copy = rtems_global_shell_env;
+