source: rtems/cpukit/libcsupport/src/privateenv.c @ ba74ebde

5
Last change on this file since ba74ebde was ba74ebde, checked in by Sebastian Huber <sebastian.huber@…>, on 02/14/20 at 18:09:56

libio: Add POSIX user environment pointer to TCB

The IO library used a POSIX key to store an optional POSIX user
environment pointer. This pulled in the POSIX keys support in every
application configuration. Add a user environment pointer to the thread
control block (TCB) instead. Applications which do not need the POSIX
user environment will just get an overhead of one pointer per thread.

Close #3882.

  • Property mode set to 100644
File size: 3.4 KB
RevLine 
[3b7c123]1/**
[41b590f9]2 *  @file
[3b7c123]3 *
[41b590f9]4 *  @brief Instantiate a Private User Environment
5 *  @ingroup LibIOEnv
[3b7c123]6 */
7
[2a929cc]8/*
9 *  Submitted by: fernando.ruiz@ctv.es (correo@fernando-ruiz.com)
10 *
[e77a1934]11 *  COPYRIGHT (c) 1989-2010.
[2a929cc]12 *  On-Line Applications Research Corporation (OAR).
13 *
14 *  The license and distribution terms for this file may be
15 *  found in the file LICENSE in this distribution or at
[c499856]16 *  http://www.rtems.org/license/LICENSE.
[2a929cc]17 */
18
19#if HAVE_CONFIG_H
[3b7c123]20  #include "config.h"
[2a929cc]21#endif
22
[3b7c123]23#include <stdlib.h>
[d3ba9b35]24
[2a929cc]25#include <rtems/libio_.h>
[776a50c]26#include <rtems/score/threadimpl.h>
[ba74ebde]27#include <rtems/score/userextimpl.h>
28#include <rtems/sysinit.h>
[2a929cc]29
[41b590f9]30/**
31 *  Instantiate a private user environment for the calling thread.
32 */
33
[ba74ebde]34static void rtems_libio_free_user_env(rtems_user_env_t *env)
[5c0c0cf]35{
[3b7c123]36  bool uses_global_env = env == &rtems_global_user_env;
37
38  if (!uses_global_env) {
[66fac03]39    rtems_filesystem_global_location_release(env->current_directory, false);
40    rtems_filesystem_global_location_release(env->root_directory, false);
[7d5c27e]41    free(env);
[a006af31]42  }
[f6161c72]43}
44
[e77a1934]45rtems_status_code rtems_libio_set_private_env(void)
46{
[3e50148]47  rtems_status_code sc = RTEMS_SUCCESSFUL;
[3b7c123]48  rtems_user_env_t *old_env = rtems_current_user_env;
49  bool uses_global_env = old_env == &rtems_global_user_env;
50
[7d5c27e]51  if (uses_global_env) {
[9949d8a7]52    Thread_Life_state life_state =
53      _Thread_Set_life_protection(THREAD_LIFE_PROTECTED);
[3b7c123]54    rtems_user_env_t *new_env = calloc(1, sizeof(*new_env));
55
56    if (new_env != NULL) {
57      *new_env = *old_env;
58      new_env->root_directory =
59        rtems_filesystem_global_location_obtain(&old_env->root_directory);
60      new_env->current_directory =
61        rtems_filesystem_global_location_obtain(&old_env->current_directory);
62
63      if (
64        !rtems_filesystem_global_location_is_null(new_env->root_directory)
65          && !rtems_filesystem_global_location_is_null(new_env->current_directory)
66      ) {
[ba74ebde]67        Thread_Control *executing = _Thread_Get_executing();
68
69        executing->user_environment = new_env;
[3b7c123]70      } else {
71        sc = RTEMS_UNSATISFIED;
72      }
73
74      if (sc != RTEMS_SUCCESSFUL) {
[5c0c0cf]75        rtems_libio_free_user_env(new_env);
[3b7c123]76      }
77    } else {
78      sc = RTEMS_NO_MEMORY;
79    }
[776a50c]80
[9949d8a7]81    _Thread_Set_life_protection(life_state);
[e77a1934]82  }
[d8a9155]83
[3b7c123]84  return sc;
[d8a9155]85}
86
[3b7c123]87void rtems_libio_use_global_env(void)
88{
89  rtems_user_env_t *env = rtems_current_user_env;
90  bool uses_private_env = env != &rtems_global_user_env;
[f6161c72]91
[3b7c123]92  if (uses_private_env) {
[9949d8a7]93    Thread_Life_state life_state =
94      _Thread_Set_life_protection(THREAD_LIFE_PROTECTED);
[ba74ebde]95    Thread_Control *executing;
[776a50c]96
97    rtems_libio_free_user_env(env);
[ba74ebde]98    executing = _Thread_Get_executing();
99    executing->user_environment = NULL;
[776a50c]100
[9949d8a7]101    _Thread_Set_life_protection(life_state);
[3b7c123]102  }
[2a929cc]103}
[ba74ebde]104
105static void rtems_libio_env_thread_terminate(Thread_Control *the_thread)
106{
107  rtems_user_env_t *env = the_thread->user_environment;
108
109  if (env != NULL) {
110    rtems_libio_free_user_env(env);
111  }
112}
113
114static void rtems_libio_env_thread_restart(
115  Thread_Control *executing,
116  Thread_Control *the_thread
117)
118{
119  (void) executing;
120  rtems_libio_env_thread_terminate( the_thread );
121}
122
123static User_extensions_Control rtems_libio_env_extensions = {
124  .Callouts = {
125    .thread_restart = rtems_libio_env_thread_restart,
126    .thread_terminate = rtems_libio_env_thread_terminate
127  }
128};
129
130static void rtems_libio_env_init(void)
131{
132  _User_extensions_Add_API_set(&rtems_libio_env_extensions);
133}
134
135RTEMS_SYSINIT_ITEM(
136  rtems_libio_env_init,
137  RTEMS_SYSINIT_USER_ENVIRONMENT,
138  RTEMS_SYSINIT_ORDER_MIDDLE
139);
Note: See TracBrowser for help on using the repository browser.