#3877 closed defect (fixed)

No output from joel scripts in telnet (cloned)

Reported by: Chris Johns Owned by: Chris Johns <chrisj@…>
Priority: normal Milestone: 4.11.4
Component: shell Version: 4.11
Severity: normal Keywords:
Cc: Blocked By: #3870


Cloned from #3859:

Running a joel script in a telnet session results in the output being sent to the global stdout. For example:

$ telnet
Connected to
Escape character is '^]'.

RTEMS Shell on /dev/pty0. Use 'help' to list commands.
[/] # cat j
#! joel
ls -las /
[/] # ./j
[/] #

The bug is a new shell main loop task will default to the global stdout, stdin etc and has no information about the parent's std handles. A joel script runs in it's own work task and does not know the telnet's std handles.

There are a related set of issues in the handling of the shell_env variable, POSIX key handling and the use of the external call rtems_shell_main_loop.

The telnet example in libbsd has:

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

	memset(&env, 0, sizeof(env));

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


This is problematic as control of the env has been lost and this make backwards comptatable changes difficult. Control of this struct needs to be brought back under the shell code.

Currently the posix key is set in the parent task only when the run entry point is used. The run's created shell_env is then passed to the shell's main loop task as an argument from which it is cloned. This means an env is malloced in each run call and again in the main loop of the shell.

The current code leaks memory as repeated calls to a joel script in a shell will set the key over and over. The destructor is only called when the task is deleted. We have to assume the cleanup of any shell_env allocated externally to the shell code has to be handled externally.

Setting the key in the main loop task is problematic because telnet code such as the example in libbsd uses a local stack shell_env and the key has a destructor that blindly free's the key's memory when a task is released.


  1. Add parent_stdout, parent_stdin, and parent_stderr to the shell_env and set to the parent's std handles.
  2. Add a managed flag to shell_env and only set when allocated by rtems_shell_init_env. Change rtems_shell_env_free to only free the shell_env if managed.
  3. Remove all key sets and have only one in the shell's main loop code.
  4. Change rtems_shell_init_env to get the current tasks key and clone that before cloning the global env.
  5. Update rtems_shell_dup_current_env to set the parent std handles.
  6. Have the main loop use the parent std handles rather than the global handles.
  7. Check the magic field has been set in the shell's main loop and raise an error if not set. The only code to set this field should reside in shell.c. Code such as libbsd will need to call rtems_shell_dup_current_env.

Change History (2)

comment:1 Changed on Feb 20, 2020 at 1:21:07 AM by Chris Johns <chrisj@…>

Owner: set to Chris Johns <chrisj@…>
Resolution: fixed
Status: newclosed

In 4d906d6a/rtems:

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 #3877

comment:2 Changed on Apr 14, 2020 at 10:29:17 PM by Chris Johns <chrisj@…>

In 55d9d8c/rtems:

libmisc/shell: Updating joel script handling fixes from RTEMS 5

Updates #3877

Note: See TracTickets for help on using tickets.