diff options
author | Chris Johns <chrisj@rtems.org> | 2010-03-04 06:36:51 +0000 |
---|---|---|
committer | Chris Johns <chrisj@rtems.org> | 2010-03-04 06:36:51 +0000 |
commit | 8ec7abb551a23bdf47509189145885a364810006 (patch) | |
tree | 7b5fa486b93583479b97f05a51c7370dd0c2d69f /cpukit/libcsupport/src/_rename_r.c | |
parent | This commit was generated by cvs2svn to compensate for changes in r22694, (diff) | |
download | rtems-8ec7abb551a23bdf47509189145885a364810006.tar.bz2 |
010-03-04 Chris Johns <chrisj@rtems.org>
* libcsupport/include/rtems/libio.h, libcsupport/src/_rename_r.c:
Add a rename file op and have rename use it.
* libfs/Makefile.am, libfs/src/dosfs/msdos_rename.c,
libfs/src/imfs/imfs_rename.c: New files to support the rename file
op.
* libfs/src/imfs/imfs.h: Add rename interface.
* libfs/src/imfs/imfs_init.c: Add rename handler.
* libfs/src/imfs/miniimfs_init.c: Fix up ops struct.
* libfs/src/dosfs/msdos.h: Add msdos_rename and remove
msdos_file_link.
* libfs/src/dosfs/msdos_create.c: Remove the link call.
* libfs/src/dosfs/msdos_eval.c: Fix a path parsing bug.
* libfs/src/dosfs/msdos_init.c: Add rename handler and clean up
the struct naming.
* libfs/src/rfs/rtems-rfs-link.c, libfs/src/rfs/rtems-rfs-link.h:
Change the link call to allow linking of directories if told to
and change the unlink to handle unlink directories that are not
empty so rename can be supported.
* libfs/src/rfs/rtems-rfs-rtems-dir.c: Fix the link/unlink calls.
* libfs/src/rfs/rtems-rfs-rtems.c: Add a rename handler. Fix the
link/unlink calls.
* libfs/src/dosfs/msdos_dir.c, libfs/src/dosfs/msdos_format.c,
libfs/src/dosfs/msdos_misc.c, httpd/asp.c,
libfs/src/nfsclient/src/nfs.c: Work around a newlib warning when
using the is*() family of calls.
Diffstat (limited to 'cpukit/libcsupport/src/_rename_r.c')
-rw-r--r-- | cpukit/libcsupport/src/_rename_r.c | 104 |
1 files changed, 102 insertions, 2 deletions
diff --git a/cpukit/libcsupport/src/_rename_r.c b/cpukit/libcsupport/src/_rename_r.c index 12eeb59e53..d12355c8d0 100644 --- a/cpukit/libcsupport/src/_rename_r.c +++ b/cpukit/libcsupport/src/_rename_r.c @@ -20,7 +20,8 @@ #include <sys/stat.h> #include <unistd.h> -#include <reent.h> +#include <rtems/libio_.h> +#include <rtems/seterr.h> int _rename_r( struct _reent *ptr __attribute__((unused)), @@ -28,6 +29,104 @@ int _rename_r( const char *new ) { + int old_parent_pathlen; + rtems_filesystem_location_info_t old_loc; + rtems_filesystem_location_info_t old_parent_loc; + rtems_filesystem_location_info_t new_parent_loc; + int i; + int result; + const char *name; + bool free_old_parentloc = false; + + /* + * Get the parent node of the old path to be renamed. Find the parent path. + */ + + old_parent_pathlen = rtems_filesystem_dirname ( old ); + + if ( old_parent_pathlen == 0 ) + rtems_filesystem_get_start_loc( old, &i, &old_parent_loc ); + else { + result = rtems_filesystem_evaluate_path( old, old_parent_pathlen, + RTEMS_LIBIO_PERMS_WRITE, + &old_parent_loc, + false ); + if ( result != 0 ) + return -1; + + free_old_parentloc = true; + } + + /* + * Start from the parent to find the node that should be under it. + */ + + old_loc = old_parent_loc; + name = old + old_parent_pathlen; + name += rtems_filesystem_prefix_separators( name, strlen( name ) ); + + result = rtems_filesystem_evaluate_relative_path( name , strlen( name ), + 0, &old_loc, false ); + if ( result != 0 ) { + if ( free_old_parentloc ) + rtems_filesystem_freenode( &old_parent_loc ); + rtems_set_errno_and_return_minus_one( result ); + } + + /* + * Get the parent of the new node we are renaming to. + */ + + rtems_filesystem_get_start_loc( new, &i, &new_parent_loc ); + + if ( !new_parent_loc.ops->evalformake_h ) { + if ( free_old_parentloc ) + rtems_filesystem_freenode( &old_parent_loc ); + rtems_filesystem_freenode( &old_loc ); + rtems_set_errno_and_return_minus_one( ENOTSUP ); + } + + result = (*new_parent_loc.ops->evalformake_h)( &new[i], &new_parent_loc, &name ); + if ( result != 0 ) { + rtems_filesystem_freenode( &new_parent_loc ); + if ( free_old_parentloc ) + rtems_filesystem_freenode( &old_parent_loc ); + rtems_filesystem_freenode( &old_loc ); + rtems_set_errno_and_return_minus_one( result ); + } + + /* + * Check to see if the caller is trying to rename across file system + * boundaries. + */ + + if ( old_parent_loc.mt_entry != new_parent_loc.mt_entry ) { + rtems_filesystem_freenode( &new_parent_loc ); + if ( free_old_parentloc ) + rtems_filesystem_freenode( &old_parent_loc ); + rtems_filesystem_freenode( &old_loc ); + rtems_set_errno_and_return_minus_one( EXDEV ); + } + + if ( !new_parent_loc.ops->rename_h ) { + rtems_filesystem_freenode( &new_parent_loc ); + if ( free_old_parentloc ) + rtems_filesystem_freenode( &old_parent_loc ); + rtems_filesystem_freenode( &old_loc ); + rtems_set_errno_and_return_minus_one( ENOTSUP ); + } + + result = (*new_parent_loc.ops->rename_h)( &old_parent_loc, &old_loc, &new_parent_loc, name ); + + rtems_filesystem_freenode( &new_parent_loc ); + if ( free_old_parentloc ) + rtems_filesystem_freenode( &old_parent_loc ); + rtems_filesystem_freenode( &old_loc ); + + return result; +} + +#if 0 struct stat sb; int s; @@ -38,5 +137,6 @@ int _rename_r( if ( s < 0 ) return s; return S_ISDIR(sb.st_mode) ? rmdir( old ) : unlink( old ); -} +#endif + #endif |