source: rtems/cpukit/libcsupport/src/privateenv.c @ 83eda9b

4.104.114.84.9
Last change on this file since 83eda9b was 83eda9b, checked in by Ralf Corsepius <ralf.corsepius@…>, on Feb 28, 2003 at 8:06:58 AM

Merger from rtems-4-6-branch.

  • Property mode set to 100644
File size: 4.3 KB
Line 
1/*
2 *  Instantatiate a private user environment for the calling thread.
3 *
4 *  Submitted by: fernando.ruiz@ctv.es (correo@fernando-ruiz.com)
5 *
6 *  COPYRIGHT (c) 1989-2000.
7 *  On-Line Applications Research Corporation (OAR).
8 *
9 *  The license and distribution terms for this file may be
10 *  found in the file LICENSE in this distribution or at
11 *  http://www.OARcorp.com/rtems/license.html.
12 *
13 *  $Id$
14 */
15
16#if HAVE_CONFIG_H
17#include "config.h"
18#endif
19
20#include <stdlib.h>     /* free */
21
22#include <rtems.h>
23#include <rtems/libio.h>
24#include <rtems/libio_.h>
25
26extern Chain_Control rtems_filesystem_mount_table_control;
27
28#define THE_ROOT_FS_LOC \
29        (((rtems_filesystem_mount_table_entry_t*)\
30           rtems_filesystem_mount_table_control.first)->mt_fs_root)
31
32/* cleanup a user environment
33 * NOTE: this must be called with
34 *       thread dispatching disabled!
35 */
36static void
37free_user_env(void *venv)
38{
39  rtems_user_env_t *env = (rtems_user_env_t*) venv ;
40
41        if (env != &rtems_global_user_env
42#ifdef HAVE_USERENV_REFCNT
43                && --env->refcnt <= 0
44#endif
45                ) {
46                rtems_filesystem_freenode( &env->current_directory);
47                rtems_filesystem_freenode( &env->root_directory);
48                free(env);
49        }
50}
51
52rtems_status_code rtems_libio_set_private_env(void) {
53  rtems_status_code                                     sc;
54  rtems_id                                              task_id;
55  rtems_filesystem_location_info_t              loc;
56
57  sc=rtems_task_ident(RTEMS_SELF,0,&task_id);
58  if (sc != RTEMS_SUCCESSFUL) return sc;
59
60  /* Only for the first time a malloc is necesary */
61  if (rtems_current_user_env==&rtems_global_user_env) {
62   rtems_user_env_t     *tmp = malloc(sizeof(rtems_user_env_t));
63   if (!tmp)
64     return RTEMS_NO_MEMORY;
65
66#ifdef HAVE_USERENV_REFCNT
67   tmp->refcnt = 1;
68#endif
69
70   sc = rtems_task_variable_add(RTEMS_SELF,(void*)&rtems_current_user_env,(void(*)(void *))free_user_env);
71   if (sc != RTEMS_SUCCESSFUL) {
72         /* don't use free_user_env because the pathlocs are
73          * not initialized yet
74          */
75     free(tmp);
76     return sc;
77   }
78   rtems_current_user_env = tmp;
79  }; 
80
81  *rtems_current_user_env = rtems_global_user_env; /* get the global values*/
82  rtems_current_user_env->task_id=task_id;         /* mark the local values*/
83 
84  /* get a clean root */
85  rtems_filesystem_root    = THE_ROOT_FS_LOC;
86
87  /* Clone the pathlocs. In contrast to most other
88   * code we must _not_ free the original locs because
89   * what we are trying to do here is forking off
90   * clones.
91   */
92
93  rtems_filesystem_evaluate_path("/", 0, &loc, 0);
94  rtems_filesystem_root    = loc;
95  rtems_filesystem_evaluate_path("/", 0, &loc, 0);
96  rtems_filesystem_current = loc;
97
98  return RTEMS_SUCCESSFUL;
99}
100
101/*
102 *  Share a same private environment beetween two task:
103 *   Task_id (remote) and RTEMS_SELF(current).
104 */
105
106/* NOTE:
107 *
108 * THIS CODE HAS NO PROTECTION IMPLEMENTED
109 *
110 * Tasks who wish to share their environments must
111 *
112 *  a) assert that no participants are concurrently
113 *     executing
114 *     libio_share_private_env() and/or libio_set_private_env()
115 *
116 *  b) mutex access to rtems_filesystem_current, rtems_filesytem_root
117 *     while changing any of those (chdir(), chroot()).
118 */
119
120#ifndef HAVE_USERENV_REFCNT
121rtems_status_code rtems_libio_share_private_env(rtems_id task_id) {
122  rtems_status_code  sc;
123  rtems_user_env_t * shared_user_env;
124  rtems_id           current_task_id;
125
126  sc=rtems_task_ident(RTEMS_SELF,0,&current_task_id);
127  if (sc != RTEMS_SUCCESSFUL) return sc;
128
129  if (rtems_current_user_env->task_id==current_task_id) {
130   /* kill the current user env & task_var*/     
131        rtems_user_env_t        *tmp = rtems_current_user_env;
132   sc = rtems_task_variable_delete(RTEMS_SELF,(void*)&rtems_current_user_env);
133   if (sc != RTEMS_SUCCESSFUL) return sc;
134   free_user_env(tmp);   
135  };
136
137  /* AT THIS POINT, rtems_current_user_env is DANGLING */
138
139  sc = rtems_task_variable_get(task_id,(void*)&rtems_current_user_env,
140                                       (void*)&shared_user_env       );
141  if (sc != RTEMS_SUCCESSFUL)
142    goto bailout;
143
144  sc = rtems_task_variable_add(RTEMS_SELF,(void*)&rtems_current_user_env,free_user_env);
145  if (sc != RTEMS_SUCCESSFUL)
146    goto bailout;
147 
148  /* the current_user_env is the same pointer that remote env */
149  rtems_current_user_env = shared_user_env;
150
151  /* increase the reference count */
152#ifdef HAVE_USERENV_REFCNT
153  rtems_current_user_env->refcnt++;
154#endif
155
156  return RTEMS_SUCCESSFUL;
157
158bailout:
159  /* fallback to the global env */
160  rtems_current_user_env = &rtems_global_user_env;
161  return sc;
162}
163#endif
Note: See TracBrowser for help on using the repository browser.