From d8a91555127ade80dfe71e2d9c823c7350eea05f Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Fri, 20 Apr 2001 21:11:25 +0000 Subject: 2001-04-20 Correo Fernando-ruiz * include/rtems/libio_.h, libc/chroot.c, libc/privateenv.c: Private environment and chroot() enhancements and fixes. Comments: + privateenv has been modified to let at chroot() to be more POSIX like Sergei Organov recommended. + A task owner lets that rtems_set_private_env() will be called twice or more times. + chroot() can be called without a previous rtems_set_private_env(); (transpanrently) + The second call of rtems_set_private_env() makes a internal chroot("/") into global imfs_root. + chroot() runs like chdir() without a previous chdir("/") with the global root. + The current directory can be in a wrong place like Linux and many other Unices. --- c/src/exec/include/rtems/libio_.h | 3 ++ c/src/exec/libcsupport/include/rtems/libio_.h | 3 ++ c/src/exec/libcsupport/src/chroot.c | 19 +++------ c/src/exec/libcsupport/src/privateenv.c | 56 +++++++++++++++++++++++---- c/src/lib/ChangeLog | 17 ++++++++ c/src/lib/include/rtems/libio_.h | 3 ++ c/src/lib/libc/chroot.c | 19 +++------ c/src/lib/libc/privateenv.c | 56 +++++++++++++++++++++++---- 8 files changed, 134 insertions(+), 42 deletions(-) (limited to 'c') diff --git a/c/src/exec/include/rtems/libio_.h b/c/src/exec/include/rtems/libio_.h index cda8faacf5..2496eefd70 100644 --- a/c/src/exec/include/rtems/libio_.h +++ b/c/src/exec/include/rtems/libio_.h @@ -209,6 +209,7 @@ extern rtems_libio_t *rtems_libio_iop_freelist; * External structures */ typedef struct { + rtems_id task_id; rtems_filesystem_location_info_t current_directory; rtems_filesystem_location_info_t root_directory; /* Default mode for all files. */ @@ -229,6 +230,8 @@ extern rtems_user_env_t rtems_global_user_env; */ rtems_status_code rtems_libio_set_private_env(void); +rtems_status_code rtems_libio_share_private_env(rtems_id task_id) ; + /* diff --git a/c/src/exec/libcsupport/include/rtems/libio_.h b/c/src/exec/libcsupport/include/rtems/libio_.h index cda8faacf5..2496eefd70 100644 --- a/c/src/exec/libcsupport/include/rtems/libio_.h +++ b/c/src/exec/libcsupport/include/rtems/libio_.h @@ -209,6 +209,7 @@ extern rtems_libio_t *rtems_libio_iop_freelist; * External structures */ typedef struct { + rtems_id task_id; rtems_filesystem_location_info_t current_directory; rtems_filesystem_location_info_t root_directory; /* Default mode for all files. */ @@ -229,6 +230,8 @@ extern rtems_user_env_t rtems_global_user_env; */ rtems_status_code rtems_libio_set_private_env(void); +rtems_status_code rtems_libio_share_private_env(rtems_id task_id) ; + /* diff --git a/c/src/exec/libcsupport/src/chroot.c b/c/src/exec/libcsupport/src/chroot.c index e05e51029e..a7645943b4 100644 --- a/c/src/exec/libcsupport/src/chroot.c +++ b/c/src/exec/libcsupport/src/chroot.c @@ -30,14 +30,15 @@ int chroot( int result; rtems_filesystem_location_info_t loc; - if (rtems_current_user_env == &rtems_global_user_env) + /* an automatic call to new private env the first time */ + if (rtems_current_user_env == &rtems_global_user_env) { + rtems_libio_set_private_env(); /* try to set a new private env*/ + if (rtems_current_user_env == &rtems_global_user_env) /* not ok */ set_errno_and_return_minus_one( ENOTSUP ); + }; loc = rtems_filesystem_root; /* save the value */ - /* if has been already changed */ - rtems_filesystem_root = rtems_global_user_env.root_directory; - result = chdir(pathname); if (result) { rtems_filesystem_root = loc; /* restore the value */ @@ -45,15 +46,5 @@ int chroot( }; rtems_filesystem_root = rtems_filesystem_current; - result = chdir("/"); - if (result) { - rtems_filesystem_root = loc; /* restore the value */ - set_errno_and_return_minus_one( errno ); - }; - - /*XXX : Call this? Sorry but I don't known if it is necesary */ - /* The old root. - rtems_filesystem_freenode( &loc ); - */ return 0; } diff --git a/c/src/exec/libcsupport/src/privateenv.c b/c/src/exec/libcsupport/src/privateenv.c index 4dc0144acc..7b1e5d1e8e 100644 --- a/c/src/exec/libcsupport/src/privateenv.c +++ b/c/src/exec/libcsupport/src/privateenv.c @@ -23,15 +23,57 @@ rtems_status_code rtems_libio_set_private_env(void) { rtems_status_code sc; + rtems_id task_id; - sc = rtems_task_variable_add(RTEMS_SELF,(void*)&rtems_current_user_env,free); - if (sc != RTEMS_SUCCESSFUL) - return sc; + sc=rtems_task_ident(RTEMS_SELF,0,&task_id); + if (sc != RTEMS_SUCCESSFUL) return sc; - rtems_current_user_env = malloc(sizeof(rtems_user_env_t)); - if (!rtems_current_user_env) - return RTEMS_NO_MEMORY; + /* Only for the first time a malloc is necesary */ + if (rtems_current_user_env==&rtems_global_user_env) { + sc = rtems_task_variable_add(RTEMS_SELF,(void*)&rtems_current_user_env,free); + if (sc != RTEMS_SUCCESSFUL) return sc; + rtems_current_user_env = malloc(sizeof(rtems_user_env_t)); + if (!rtems_current_user_env) + return RTEMS_NO_MEMORY; + }; + + /* the side effect desired . chroot("/") */ + *rtems_current_user_env = rtems_global_user_env; /* get the global values*/ + rtems_current_user_env->task_id=task_id; /* mark the local values*/ + + return RTEMS_SUCCESSFUL; +} + +/* + * Share a same private environment beetween two task: + * Task_id (remote) and RTEMS_SELF(current). + */ + +rtems_status_code rtems_libio_share_private_env(rtems_id task_id) { + rtems_status_code sc; + rtems_user_env_t * shared_user_env; + rtems_id current_task_id; + + sc=rtems_task_ident(RTEMS_SELF,0,¤t_task_id); + if (sc != RTEMS_SUCCESSFUL) return sc; + + if (rtems_current_user_env->task_id==current_task_id) { + /* kill the current user env & task_var*/ + free(rtems_current_user_env); + sc = rtems_task_variable_delete(RTEMS_SELF,(void*)&rtems_current_user_env); + if (sc != RTEMS_SUCCESSFUL) return sc; + }; + + sc = rtems_task_variable_get(task_id,(void*)&rtems_current_user_env, + (void*)&shared_user_env ); + if (sc != RTEMS_SUCCESSFUL) return sc; + + /* don't free(NULL'ed) at the task_delete. It is a shared var... */ + sc = rtems_task_variable_add(RTEMS_SELF,(void*)&rtems_current_user_env,NULL); + if (sc != RTEMS_SUCCESSFUL) return sc; + + /* the current_user_env is the same pointer that remote env */ + rtems_current_user_env = shared_user_env; - *rtems_current_user_env = rtems_global_user_env; return RTEMS_SUCCESSFUL; } diff --git a/c/src/lib/ChangeLog b/c/src/lib/ChangeLog index ed9895eb30..49c66aaafe 100644 --- a/c/src/lib/ChangeLog +++ b/c/src/lib/ChangeLog @@ -1,3 +1,20 @@ +2001-04-20 Correo Fernando-ruiz + + * include/rtems/libio_.h, libc/chroot.c, libc/privateenv.c: + Private environment and chroot() enhancements and fixes. Comments: + + privateenv has been modified to let at chroot() to be more + POSIX like Sergei Organov recommended. + + A task owner lets that rtems_set_private_env() will be + called twice or more times. + + chroot() can be called without a previous + rtems_set_private_env(); (transpanrently) + + The second call of rtems_set_private_env() makes a internal + chroot("/") into global imfs_root. + + chroot() runs like chdir() without a previous chdir("/") with + the global root. + + The current directory can be in a wrong place like Linux and + many other Unices. + 2001-04-16 Joel Sherrill * include/rtc.h: New file. diff --git a/c/src/lib/include/rtems/libio_.h b/c/src/lib/include/rtems/libio_.h index cda8faacf5..2496eefd70 100644 --- a/c/src/lib/include/rtems/libio_.h +++ b/c/src/lib/include/rtems/libio_.h @@ -209,6 +209,7 @@ extern rtems_libio_t *rtems_libio_iop_freelist; * External structures */ typedef struct { + rtems_id task_id; rtems_filesystem_location_info_t current_directory; rtems_filesystem_location_info_t root_directory; /* Default mode for all files. */ @@ -229,6 +230,8 @@ extern rtems_user_env_t rtems_global_user_env; */ rtems_status_code rtems_libio_set_private_env(void); +rtems_status_code rtems_libio_share_private_env(rtems_id task_id) ; + /* diff --git a/c/src/lib/libc/chroot.c b/c/src/lib/libc/chroot.c index e05e51029e..a7645943b4 100644 --- a/c/src/lib/libc/chroot.c +++ b/c/src/lib/libc/chroot.c @@ -30,14 +30,15 @@ int chroot( int result; rtems_filesystem_location_info_t loc; - if (rtems_current_user_env == &rtems_global_user_env) + /* an automatic call to new private env the first time */ + if (rtems_current_user_env == &rtems_global_user_env) { + rtems_libio_set_private_env(); /* try to set a new private env*/ + if (rtems_current_user_env == &rtems_global_user_env) /* not ok */ set_errno_and_return_minus_one( ENOTSUP ); + }; loc = rtems_filesystem_root; /* save the value */ - /* if has been already changed */ - rtems_filesystem_root = rtems_global_user_env.root_directory; - result = chdir(pathname); if (result) { rtems_filesystem_root = loc; /* restore the value */ @@ -45,15 +46,5 @@ int chroot( }; rtems_filesystem_root = rtems_filesystem_current; - result = chdir("/"); - if (result) { - rtems_filesystem_root = loc; /* restore the value */ - set_errno_and_return_minus_one( errno ); - }; - - /*XXX : Call this? Sorry but I don't known if it is necesary */ - /* The old root. - rtems_filesystem_freenode( &loc ); - */ return 0; } diff --git a/c/src/lib/libc/privateenv.c b/c/src/lib/libc/privateenv.c index 4dc0144acc..7b1e5d1e8e 100644 --- a/c/src/lib/libc/privateenv.c +++ b/c/src/lib/libc/privateenv.c @@ -23,15 +23,57 @@ rtems_status_code rtems_libio_set_private_env(void) { rtems_status_code sc; + rtems_id task_id; - sc = rtems_task_variable_add(RTEMS_SELF,(void*)&rtems_current_user_env,free); - if (sc != RTEMS_SUCCESSFUL) - return sc; + sc=rtems_task_ident(RTEMS_SELF,0,&task_id); + if (sc != RTEMS_SUCCESSFUL) return sc; - rtems_current_user_env = malloc(sizeof(rtems_user_env_t)); - if (!rtems_current_user_env) - return RTEMS_NO_MEMORY; + /* Only for the first time a malloc is necesary */ + if (rtems_current_user_env==&rtems_global_user_env) { + sc = rtems_task_variable_add(RTEMS_SELF,(void*)&rtems_current_user_env,free); + if (sc != RTEMS_SUCCESSFUL) return sc; + rtems_current_user_env = malloc(sizeof(rtems_user_env_t)); + if (!rtems_current_user_env) + return RTEMS_NO_MEMORY; + }; + + /* the side effect desired . chroot("/") */ + *rtems_current_user_env = rtems_global_user_env; /* get the global values*/ + rtems_current_user_env->task_id=task_id; /* mark the local values*/ + + return RTEMS_SUCCESSFUL; +} + +/* + * Share a same private environment beetween two task: + * Task_id (remote) and RTEMS_SELF(current). + */ + +rtems_status_code rtems_libio_share_private_env(rtems_id task_id) { + rtems_status_code sc; + rtems_user_env_t * shared_user_env; + rtems_id current_task_id; + + sc=rtems_task_ident(RTEMS_SELF,0,¤t_task_id); + if (sc != RTEMS_SUCCESSFUL) return sc; + + if (rtems_current_user_env->task_id==current_task_id) { + /* kill the current user env & task_var*/ + free(rtems_current_user_env); + sc = rtems_task_variable_delete(RTEMS_SELF,(void*)&rtems_current_user_env); + if (sc != RTEMS_SUCCESSFUL) return sc; + }; + + sc = rtems_task_variable_get(task_id,(void*)&rtems_current_user_env, + (void*)&shared_user_env ); + if (sc != RTEMS_SUCCESSFUL) return sc; + + /* don't free(NULL'ed) at the task_delete. It is a shared var... */ + sc = rtems_task_variable_add(RTEMS_SELF,(void*)&rtems_current_user_env,NULL); + if (sc != RTEMS_SUCCESSFUL) return sc; + + /* the current_user_env is the same pointer that remote env */ + rtems_current_user_env = shared_user_env; - *rtems_current_user_env = rtems_global_user_env; return RTEMS_SUCCESSFUL; } -- cgit v1.2.3