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 Feb 14, 2020 at 6:09:56 PM

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
Line 
1/**
2 *  @file
3 *
4 *  @brief Instantiate a Private User Environment
5 *  @ingroup LibIOEnv
6 */
7
8/*
9 *  Submitted by: fernando.ruiz@ctv.es (correo@fernando-ruiz.com)
10 *
11 *  COPYRIGHT (c) 1989-2010.
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
16 *  http://www.rtems.org/license/LICENSE.
17 */
18
19#if HAVE_CONFIG_H
20  #include "config.h"
21#endif
22
23#include <stdlib.h>
24
25#include <rtems/libio_.h>
26#include <rtems/score/threadimpl.h>
27#include <rtems/score/userextimpl.h>
28#include <rtems/sysinit.h>
29
30/**
31 *  Instantiate a private user environment for the calling thread.
32 */
33
34static void rtems_libio_free_user_env(rtems_user_env_t *env)
35{
36  bool uses_global_env = env == &rtems_global_user_env;
37
38  if (!uses_global_env) {
39    rtems_filesystem_global_location_release(env->current_directory, false);
40    rtems_filesystem_global_location_release(env->root_directory, false);
41    free(env);
42  }
43}
44
45rtems_status_code rtems_libio_set_private_env(void)
46{
47  rtems_status_code sc = RTEMS_SUCCESSFUL;
48  rtems_user_env_t *old_env = rtems_current_user_env;
49  bool uses_global_env = old_env == &rtems_global_user_env;
50
51  if (uses_global_env) {
52    Thread_Life_state life_state =
53      _Thread_Set_life_protection(THREAD_LIFE_PROTECTED);
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      ) {
67        Thread_Control *executing = _Thread_Get_executing();
68
69        executing->user_environment = new_env;
70      } else {
71        sc = RTEMS_UNSATISFIED;
72      }
73
74      if (sc != RTEMS_SUCCESSFUL) {
75        rtems_libio_free_user_env(new_env);
76      }
77    } else {
78      sc = RTEMS_NO_MEMORY;
79    }
80
81    _Thread_Set_life_protection(life_state);
82  }
83
84  return sc;
85}
86
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;
91
92  if (uses_private_env) {
93    Thread_Life_state life_state =
94      _Thread_Set_life_protection(THREAD_LIFE_PROTECTED);
95    Thread_Control *executing;
96
97    rtems_libio_free_user_env(env);
98    executing = _Thread_Get_executing();
99    executing->user_environment = NULL;
100
101    _Thread_Set_life_protection(life_state);
102  }
103}
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.