source: rtems/cpukit/libcsupport/src/privateenv.c @ 21595c7

Last change on this file since 21595c7 was f6161c72, checked in by Jennifer Averett <Jennifer.Averett@…>, on 01/03/03 at 18:14:09

2003-01-03 Till Straumann <strauman@…>

  • ChangeLog?, base_fs.c, getpwent.c, privateenv.c Per PR303, Fix violation of node_access copy syemantics
  • 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(rtems_user_env_t *env)
38{
39        if (env != &rtems_global_user_env
40#ifdef HAVE_USERENV_REFCNT
41                && --env->refcnt <= 0
42#endif
43                ) {
44                rtems_filesystem_freenode( &env->current_directory);
45                rtems_filesystem_freenode( &env->root_directory);
46                free(env);
47        }
48}
49
50rtems_status_code rtems_libio_set_private_env(void) {
51  rtems_status_code                                     sc;
52  rtems_id                                              task_id;
53  rtems_filesystem_location_info_t              loc;
54
55  sc=rtems_task_ident(RTEMS_SELF,0,&task_id);
56  if (sc != RTEMS_SUCCESSFUL) return sc;
57
58  /* Only for the first time a malloc is necesary */
59  if (rtems_current_user_env==&rtems_global_user_env) {
60   rtems_user_env_t     *tmp = malloc(sizeof(rtems_user_env_t));
61   if (!tmp)
62     return RTEMS_NO_MEMORY;
63
64#ifdef HAVE_USERENV_REFCNT
65   tmp->refcnt = 1;
66#endif
67
68   sc = rtems_task_variable_add(RTEMS_SELF,(void*)&rtems_current_user_env,free_user_env);
69   if (sc != RTEMS_SUCCESSFUL) {
70         /* don't use free_user_env because the pathlocs are
71          * not initialized yet
72          */
73     free(tmp);
74     return sc;
75   }
76   rtems_current_user_env = tmp;
77  };
78
79  *rtems_current_user_env = rtems_global_user_env; /* get the global values*/
80  rtems_current_user_env->task_id=task_id;         /* mark the local values*/
81 
82  /* get a clean root */
83  rtems_filesystem_root    = THE_ROOT_FS_LOC;
84
85  /* Clone the pathlocs. In contrast to most other
86   * code we must _not_ free the original locs because
87   * what we are trying to do here is forking off
88   * clones.
89   */
90
91  rtems_filesystem_evaluate_path("/", 0, &loc, 0);
92  rtems_filesystem_root    = loc;
93  rtems_filesystem_evaluate_path("/", 0, &loc, 0);
94  rtems_filesystem_current = loc;
95
96  return RTEMS_SUCCESSFUL;
97}
98
99/*
100 *  Share a same private environment beetween two task:
101 *   Task_id (remote) and RTEMS_SELF(current).
102 */
103
104/* NOTE:
105 *
106 * THIS CODE HAS NO PROTECTION IMPLEMENTED
107 *
108 * Tasks who wish to share their environments must
109 *
110 *  a) assert that no participants are concurrently
111 *     executing
112 *     libio_share_private_env() and/or libio_set_private_env()
113 *
114 *  b) mutex access to rtems_filesystem_current, rtems_filesytem_root
115 *     while changing any of those (chdir(), chroot()).
116 */
117
118#ifndef HAVE_USERENV_REFCNT
119rtems_status_code rtems_libio_share_private_env(rtems_id task_id) {
120  rtems_status_code  sc;
121  rtems_user_env_t * shared_user_env;
122  rtems_id           current_task_id;
123
124  sc=rtems_task_ident(RTEMS_SELF,0,&current_task_id);
125  if (sc != RTEMS_SUCCESSFUL) return sc;
126
127  if (rtems_current_user_env->task_id==current_task_id) {
128   /* kill the current user env & task_var*/     
129        rtems_user_env_t        *tmp = rtems_current_user_env;
130   sc = rtems_task_variable_delete(RTEMS_SELF,(void*)&rtems_current_user_env);
131   if (sc != RTEMS_SUCCESSFUL) return sc;
132   free_user_env(tmp);   
133  };
134
135  /* AT THIS POINT, rtems_current_user_env is DANGLING */
136
137  sc = rtems_task_variable_get(task_id,(void*)&rtems_current_user_env,
138                                       (void*)&shared_user_env       );
139  if (sc != RTEMS_SUCCESSFUL)
140    goto bailout;
141
142  sc = rtems_task_variable_add(RTEMS_SELF,(void*)&rtems_current_user_env,free_user_env);
143  if (sc != RTEMS_SUCCESSFUL)
144    goto bailout;
145 
146  /* the current_user_env is the same pointer that remote env */
147  rtems_current_user_env = shared_user_env;
148
149  /* increase the reference count */
150#ifdef HAVE_USERENV_REFCNT
151  rtems_current_user_env->refcnt++;
152#endif
153
154  return RTEMS_SUCCESSFUL;
155
156bailout:
157  /* fallback to the global env */
158  rtems_current_user_env = &rtems_global_user_env;
159  return sc;
160}
161#endif
Note: See TracBrowser for help on using the repository browser.