[2a929cc] | 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 | |
---|
[d3ba9b35] | 20 | #include <stdlib.h> /* free */ |
---|
| 21 | |
---|
[2a929cc] | 22 | #include <rtems.h> |
---|
| 23 | #include <rtems/libio.h> |
---|
| 24 | #include <rtems/libio_.h> |
---|
| 25 | |
---|
[f6161c72] | 26 | extern 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 | */ |
---|
| 36 | static void |
---|
[83eda9b] | 37 | free_user_env(void *venv) |
---|
[f6161c72] | 38 | { |
---|
[83eda9b] | 39 | rtems_user_env_t *env = (rtems_user_env_t*) venv ; |
---|
| 40 | |
---|
[f6161c72] | 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 | |
---|
[2a929cc] | 52 | rtems_status_code rtems_libio_set_private_env(void) { |
---|
[f6161c72] | 53 | rtems_status_code sc; |
---|
| 54 | rtems_id task_id; |
---|
| 55 | rtems_filesystem_location_info_t loc; |
---|
[2a929cc] | 56 | |
---|
[d8a9155] | 57 | sc=rtems_task_ident(RTEMS_SELF,0,&task_id); |
---|
| 58 | if (sc != RTEMS_SUCCESSFUL) return sc; |
---|
[2a929cc] | 59 | |
---|
[d8a9155] | 60 | /* Only for the first time a malloc is necesary */ |
---|
[f6161c72] | 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) |
---|
[d8a9155] | 64 | return RTEMS_NO_MEMORY; |
---|
[f6161c72] | 65 | |
---|
| 66 | #ifdef HAVE_USERENV_REFCNT |
---|
| 67 | tmp->refcnt = 1; |
---|
| 68 | #endif |
---|
| 69 | |
---|
[8860f103] | 70 | sc = rtems_task_variable_add(RTEMS_SELF,(void*)&rtems_current_user_env,(void(*)(void *))free_user_env); |
---|
[f6161c72] | 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; |
---|
[d8a9155] | 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*/ |
---|
[f6161c72] | 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; |
---|
[d8a9155] | 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 | |
---|
[f6161c72] | 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 |
---|
[d8a9155] | 121 | rtems_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,¤t_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*/ |
---|
[f6161c72] | 131 | rtems_user_env_t *tmp = rtems_current_user_env; |
---|
[d8a9155] | 132 | sc = rtems_task_variable_delete(RTEMS_SELF,(void*)&rtems_current_user_env); |
---|
| 133 | if (sc != RTEMS_SUCCESSFUL) return sc; |
---|
[f6161c72] | 134 | free_user_env(tmp); |
---|
[d8a9155] | 135 | }; |
---|
| 136 | |
---|
[f6161c72] | 137 | /* AT THIS POINT, rtems_current_user_env is DANGLING */ |
---|
| 138 | |
---|
[d8a9155] | 139 | sc = rtems_task_variable_get(task_id,(void*)&rtems_current_user_env, |
---|
| 140 | (void*)&shared_user_env ); |
---|
[f6161c72] | 141 | if (sc != RTEMS_SUCCESSFUL) |
---|
| 142 | goto bailout; |
---|
[d8a9155] | 143 | |
---|
[f6161c72] | 144 | sc = rtems_task_variable_add(RTEMS_SELF,(void*)&rtems_current_user_env,free_user_env); |
---|
| 145 | if (sc != RTEMS_SUCCESSFUL) |
---|
| 146 | goto bailout; |
---|
[d8a9155] | 147 | |
---|
| 148 | /* the current_user_env is the same pointer that remote env */ |
---|
| 149 | rtems_current_user_env = shared_user_env; |
---|
[2a929cc] | 150 | |
---|
[f6161c72] | 151 | /* increase the reference count */ |
---|
| 152 | #ifdef HAVE_USERENV_REFCNT |
---|
| 153 | rtems_current_user_env->refcnt++; |
---|
| 154 | #endif |
---|
| 155 | |
---|
[2a929cc] | 156 | return RTEMS_SUCCESSFUL; |
---|
[f6161c72] | 157 | |
---|
| 158 | bailout: |
---|
| 159 | /* fallback to the global env */ |
---|
| 160 | rtems_current_user_env = &rtems_global_user_env; |
---|
| 161 | return sc; |
---|
[2a929cc] | 162 | } |
---|
[f6161c72] | 163 | #endif |
---|