diff options
Diffstat (limited to 'cpukit/libcsupport')
-rw-r--r-- | cpukit/libcsupport/include/rtems/libio.h | 8 | ||||
-rw-r--r-- | cpukit/libcsupport/include/rtems/libio_.h | 19 | ||||
-rw-r--r-- | cpukit/libcsupport/src/base_fs.c | 4 | ||||
-rw-r--r-- | cpukit/libcsupport/src/chdir.c | 2 | ||||
-rw-r--r-- | cpukit/libcsupport/src/chmod.c | 2 | ||||
-rw-r--r-- | cpukit/libcsupport/src/chown.c | 2 | ||||
-rw-r--r-- | cpukit/libcsupport/src/chroot.c | 2 | ||||
-rw-r--r-- | cpukit/libcsupport/src/eval.c | 84 | ||||
-rw-r--r-- | cpukit/libcsupport/src/fchdir.c | 2 | ||||
-rw-r--r-- | cpukit/libcsupport/src/link.c | 3 | ||||
-rw-r--r-- | cpukit/libcsupport/src/mount.c | 2 | ||||
-rw-r--r-- | cpukit/libcsupport/src/open.c | 4 | ||||
-rw-r--r-- | cpukit/libcsupport/src/privateenv.c | 4 | ||||
-rw-r--r-- | cpukit/libcsupport/src/readlink.c | 3 | ||||
-rw-r--r-- | cpukit/libcsupport/src/rmdir.c | 44 | ||||
-rw-r--r-- | cpukit/libcsupport/src/stat.c | 3 | ||||
-rw-r--r-- | cpukit/libcsupport/src/unlink.c | 48 | ||||
-rw-r--r-- | cpukit/libcsupport/src/unmount.c | 2 | ||||
-rw-r--r-- | cpukit/libcsupport/src/utime.c | 2 |
19 files changed, 176 insertions, 64 deletions
diff --git a/cpukit/libcsupport/include/rtems/libio.h b/cpukit/libcsupport/include/rtems/libio.h index 5f840647db..44e8b59267 100644 --- a/cpukit/libcsupport/include/rtems/libio.h +++ b/cpukit/libcsupport/include/rtems/libio.h @@ -128,6 +128,7 @@ typedef int (*rtems_filesystem_fcntl_t)( ); typedef int (*rtems_filesystem_rmnod_t)( + rtems_filesystem_location_info_t *parent_loc, /* IN */ rtems_filesystem_location_info_t *pathloc /* IN */ ); @@ -174,6 +175,7 @@ typedef int (*rtems_filesystem_mknod_t)( typedef int (*rtems_filesystem_evalpath_t)( const char *pathname, /* IN */ + int pathnamelen, /* IN */ int flags, /* IN */ rtems_filesystem_location_info_t *pathloc /* IN/OUT */ ); @@ -191,7 +193,8 @@ typedef int (*rtems_filesystem_link_t)( ); typedef int (*rtems_filesystem_unlink_t)( - rtems_filesystem_location_info_t *pathloc /* IN */ + rtems_filesystem_location_info_t *parent_pathloc, /* IN */ + rtems_filesystem_location_info_t *pathloc /* IN */ ); typedef int (*rtems_filesystem_chown_t)( @@ -326,7 +329,8 @@ struct rtems_filesystem_mount_table_entry_tt { * When someone adds a mounted filesystem on a real device, * this will need to be used. * - * The best option long term for this is probably an open file descriptor. + * The lower layers can manage how this is managed. Leave as a + * string. */ char *dev; }; diff --git a/cpukit/libcsupport/include/rtems/libio_.h b/cpukit/libcsupport/include/rtems/libio_.h index f64fefb2e8..dfde83145d 100644 --- a/cpukit/libcsupport/include/rtems/libio_.h +++ b/cpukit/libcsupport/include/rtems/libio_.h @@ -234,16 +234,29 @@ int rtems_libio_is_file_open( * File System Routine Prototypes */ -int rtems_filesystem_evaluate_path( +int rtems_filesystem_evaluate_relative_path( const char *pathname, + int pathnamelen, int flags, rtems_filesystem_location_info_t *pathloc, int follow_link ); -int rtems_filesystem_evaluate_parent( +int rtems_filesystem_evaluate_path( + const char *pathname, + int pathnamelen, int flags, - rtems_filesystem_location_info_t *pathloc + rtems_filesystem_location_info_t *pathloc, + int follow_link +); + +int rtems_filesystem_dirname( + const char *pathname +); + +int rtems_filesystem_prefix_separators( + const char *pathname, + int pathnamelen ); void rtems_filesystem_initialize(void); diff --git a/cpukit/libcsupport/src/base_fs.c b/cpukit/libcsupport/src/base_fs.c index 91466a5b07..328bcce60a 100644 --- a/cpukit/libcsupport/src/base_fs.c +++ b/cpukit/libcsupport/src/base_fs.c @@ -89,10 +89,10 @@ void rtems_filesystem_initialize( void ) */ rtems_filesystem_root = entry->mt_fs_root; /* Clone the root pathloc */ - rtems_filesystem_evaluate_path("/", 0, &loc, 0); + rtems_filesystem_evaluate_path("/", 1, 0, &loc, 0); rtems_filesystem_root = loc; /* One more clone for the current node */ - rtems_filesystem_evaluate_path("/", 0, &loc, 0); + rtems_filesystem_evaluate_path("/", 1, 0, &loc, 0); rtems_filesystem_current = loc; /* Note: the global_env's refcnt doesn't matter diff --git a/cpukit/libcsupport/src/chdir.c b/cpukit/libcsupport/src/chdir.c index fb6f7e6497..ccc7a567ba 100644 --- a/cpukit/libcsupport/src/chdir.c +++ b/cpukit/libcsupport/src/chdir.c @@ -35,7 +35,7 @@ int chdir( */ result = rtems_filesystem_evaluate_path( - pathname, RTEMS_LIBIO_PERMS_SEARCH, &loc, true ); + pathname, strlen( pathname ), RTEMS_LIBIO_PERMS_SEARCH, &loc, true ); if ( result != 0 ) return -1; diff --git a/cpukit/libcsupport/src/chmod.c b/cpukit/libcsupport/src/chmod.c index a19302517d..459314f736 100644 --- a/cpukit/libcsupport/src/chmod.c +++ b/cpukit/libcsupport/src/chmod.c @@ -34,7 +34,7 @@ int chmod( rtems_filesystem_location_info_t loc; int result; - status = rtems_filesystem_evaluate_path( path, 0, &loc, true ); + status = rtems_filesystem_evaluate_path( path, strlen( path ), 0, &loc, true ); if ( status != 0 ) return -1; diff --git a/cpukit/libcsupport/src/chown.c b/cpukit/libcsupport/src/chown.c index 4784315d57..22d2a77127 100644 --- a/cpukit/libcsupport/src/chown.c +++ b/cpukit/libcsupport/src/chown.c @@ -33,7 +33,7 @@ int chown( rtems_filesystem_location_info_t loc; int result; - if ( rtems_filesystem_evaluate_path( path, 0x00, &loc, true ) ) + if ( rtems_filesystem_evaluate_path( path, strlen( path ), 0x00, &loc, true ) ) return -1; if ( !loc.ops->chown_h ) { diff --git a/cpukit/libcsupport/src/chroot.c b/cpukit/libcsupport/src/chroot.c index d3e1198d0a..ccda4d6d7a 100644 --- a/cpukit/libcsupport/src/chroot.c +++ b/cpukit/libcsupport/src/chroot.c @@ -44,7 +44,7 @@ int chroot( } /* clone the new root location */ - if (rtems_filesystem_evaluate_path(".", 0, &loc, 0)) { + if (rtems_filesystem_evaluate_path(".", 1, 0, &loc, 0)) { /* our cwd has changed, though - but there is no easy way of return :-( */ rtems_set_errno_and_return_minus_one( errno ); } diff --git a/cpukit/libcsupport/src/eval.c b/cpukit/libcsupport/src/eval.c index 7c9c0a7e47..5870155189 100644 --- a/cpukit/libcsupport/src/eval.c +++ b/cpukit/libcsupport/src/eval.c @@ -21,8 +21,9 @@ #include <rtems/libio_.h> #include <rtems/seterr.h> -int rtems_filesystem_evaluate_path( +int rtems_filesystem_evaluate_relative_path( const char *pathname, + int pathnamelen, int flags, rtems_filesystem_location_info_t *pathloc, int follow_link @@ -42,16 +43,10 @@ int rtems_filesystem_evaluate_path( if ( !pathloc ) rtems_set_errno_and_return_minus_one( EIO ); /* should never happen */ - /* - * Evaluate the path using the optable evalpath. - */ - - rtems_filesystem_get_start_loc( pathname, &i, pathloc ); - if ( !pathloc->ops->evalpath_h ) rtems_set_errno_and_return_minus_one( ENOTSUP ); - result = (*pathloc->ops->evalpath_h)( &pathname[i], flags, pathloc ); + result = (*pathloc->ops->evalpath_h)( &pathname[i], pathnamelen, flags, pathloc ); /* * Get the Node type and determine if you need to follow the link or @@ -90,34 +85,79 @@ int rtems_filesystem_evaluate_path( */ result = (*pathloc->ops->eval_link_h)( pathloc, flags ); - } } return result; } - -int rtems_filesystem_evaluate_parent( +int rtems_filesystem_evaluate_path( + const char *pathname, + int pathnamelen, int flags, - rtems_filesystem_location_info_t *pathloc + rtems_filesystem_location_info_t *pathloc, + int follow_link ) { - rtems_filesystem_location_info_t parent; - int result; + int i; + int result; + rtems_filesystem_node_types_t type; + + /* + * Verify Input parameters. + */ + + if ( !pathname ) + rtems_set_errno_and_return_minus_one( EFAULT ); if ( !pathloc ) rtems_set_errno_and_return_minus_one( EIO ); /* should never happen */ - if ( !pathloc->ops->evalpath_h ) - rtems_set_errno_and_return_minus_one( ENOTSUP ); + /* + * Evaluate the path using the optable evalpath. + */ + + rtems_filesystem_get_start_loc( pathname, &i, pathloc ); + + /* + * We evaluation the path relative to the start location we get got. + */ + return rtems_filesystem_evaluate_relative_path( pathname, + pathnamelen, + flags, + pathloc, + follow_link ); +} - parent = *pathloc; - result = (*pathloc->ops->evalpath_h)( "..", flags, &parent ); - if (result != 0){ - return -1; +int rtems_filesystem_dirname( + const char *pathname +) +{ + int len = strlen( pathname ); + + while ( len ) { + len--; + if ( rtems_filesystem_is_separator( pathname[len] ) ) + break; } - rtems_filesystem_freenode( &parent ); - return result; + return len; +} + +int rtems_filesystem_prefix_separators( + const char *pathname, + int pathnamelen +) +{ + /* + * Eat any separators at start of the path. + */ + int stripped = 0; + while ( *pathname && pathnamelen && rtems_filesystem_is_separator( *pathname ) ) + { + pathname++; + pathnamelen--; + stripped++; + } + return stripped; } diff --git a/cpukit/libcsupport/src/fchdir.c b/cpukit/libcsupport/src/fchdir.c index 603288614d..0f3cf9ebb3 100644 --- a/cpukit/libcsupport/src/fchdir.c +++ b/cpukit/libcsupport/src/fchdir.c @@ -76,7 +76,7 @@ int fchdir( rtems_filesystem_current = iop->pathinfo; /* clone the current node */ - if (rtems_filesystem_evaluate_path(".", 0, &loc, 0)) { + if (rtems_filesystem_evaluate_path(".", 1, 0, &loc, 0)) { /* cloning failed; restore original and bail out */ rtems_filesystem_current = saved; return -1; diff --git a/cpukit/libcsupport/src/link.c b/cpukit/libcsupport/src/link.c index c105a33742..bcad166182 100644 --- a/cpukit/libcsupport/src/link.c +++ b/cpukit/libcsupport/src/link.c @@ -37,7 +37,8 @@ int link( * Get the node we are linking to. */ - result = rtems_filesystem_evaluate_path( existing, 0, &existing_loc, true ); + result = rtems_filesystem_evaluate_path( existing, strlen( existing ), + 0, &existing_loc, true ); if ( result != 0 ) return -1; diff --git a/cpukit/libcsupport/src/mount.c b/cpukit/libcsupport/src/mount.c index 04264ad234..d21a084be0 100644 --- a/cpukit/libcsupport/src/mount.c +++ b/cpukit/libcsupport/src/mount.c @@ -139,7 +139,7 @@ int mount( if ( mount_point ) { if ( rtems_filesystem_evaluate_path( - mount_point, RTEMS_LIBIO_PERMS_RWX, &loc, true ) == -1 ) + mount_point, strlen( mount_point ), RTEMS_LIBIO_PERMS_RWX, &loc, true ) == -1 ) goto cleanup_and_bail; loc_to_free = &loc; diff --git a/cpukit/libcsupport/src/open.c b/cpukit/libcsupport/src/open.c index 1bc83ed7bc..f45215ec0d 100644 --- a/cpukit/libcsupport/src/open.c +++ b/cpukit/libcsupport/src/open.c @@ -111,7 +111,7 @@ int open( */ status = rtems_filesystem_evaluate_path( - pathname, eval_flags, &loc, true ); + pathname, strlen( pathname ), eval_flags, &loc, true ); if ( status == -1 ) { if ( errno != ENOENT ) { @@ -133,7 +133,7 @@ int open( } /* Sanity check to see if the file name exists after the mknod() */ - status = rtems_filesystem_evaluate_path( pathname, 0x0, &loc, true ); + status = rtems_filesystem_evaluate_path( pathname, strlen( pathname ), 0x0, &loc, true ); if ( status != 0 ) { /* The file did not exist */ rc = EACCES; goto done; diff --git a/cpukit/libcsupport/src/privateenv.c b/cpukit/libcsupport/src/privateenv.c index 286a2f6733..d61f9013a9 100644 --- a/cpukit/libcsupport/src/privateenv.c +++ b/cpukit/libcsupport/src/privateenv.c @@ -91,9 +91,9 @@ rtems_status_code rtems_libio_set_private_env(void) { * clones. */ - rtems_filesystem_evaluate_path("/", 0, &loc, 0); + rtems_filesystem_evaluate_path("/", 1, 0, &loc, 0); rtems_filesystem_root = loc; - rtems_filesystem_evaluate_path("/", 0, &loc, 0); + rtems_filesystem_evaluate_path("/", 1, 0, &loc, 0); rtems_filesystem_current = loc; return RTEMS_SUCCESSFUL; diff --git a/cpukit/libcsupport/src/readlink.c b/cpukit/libcsupport/src/readlink.c index 957e27d1c8..9252871208 100644 --- a/cpukit/libcsupport/src/readlink.c +++ b/cpukit/libcsupport/src/readlink.c @@ -30,7 +30,8 @@ ssize_t readlink( if (!buf) rtems_set_errno_and_return_minus_one( EFAULT ); - result = rtems_filesystem_evaluate_path( pathname, 0, &loc, false ); + result = rtems_filesystem_evaluate_path( pathname, strlen( pathname ), + 0, &loc, false ); if ( result != 0 ) return -1; diff --git a/cpukit/libcsupport/src/rmdir.c b/cpukit/libcsupport/src/rmdir.c index 4b1de71c8a..ca0129fd3b 100644 --- a/cpukit/libcsupport/src/rmdir.c +++ b/cpukit/libcsupport/src/rmdir.c @@ -28,20 +28,42 @@ int rmdir( const char *pathname ) { + int parentpathlen; + const char *name; + rtems_filesystem_location_info_t parentloc; rtems_filesystem_location_info_t loc; + int i; int result; - + /* - * Get the node where we wish to go. + * Get the parent node of the node we wish to remove. Find the parent path. */ - result = rtems_filesystem_evaluate_path( pathname, 0, &loc, false ); - if ( result != 0 ) - return -1; + parentpathlen = rtems_filesystem_dirname ( pathname ); - result = rtems_filesystem_evaluate_parent(RTEMS_LIBIO_PERMS_WRITE, &loc ); - if (result != 0) { - rtems_filesystem_freenode( &loc ); + if ( parentpathlen == 0 ) + rtems_filesystem_get_start_loc( pathname, &i, &parentloc ); + else { + result = rtems_filesystem_evaluate_path(pathname, parentpathlen, + RTEMS_LIBIO_PERMS_WRITE, + &parentloc, + false ); + if ( result != 0 ) + return -1; + } + + /* + * Start from the parent to find the node that should be under it. + */ + + loc = parentloc; + name = pathname + parentpathlen; + name += rtems_filesystem_prefix_separators( name, strlen( name ) ); + + result = rtems_filesystem_evaluate_relative_path( name , strlen( name ), + 0, &loc, false ); + if ( result != 0 ) { + rtems_filesystem_freenode( &parentloc ); return -1; } @@ -51,11 +73,13 @@ int rmdir( if ( !loc.ops->node_type_h ){ rtems_filesystem_freenode( &loc ); + rtems_filesystem_freenode( &parentloc ); rtems_set_errno_and_return_minus_one( ENOTSUP ); } if ( (*loc.ops->node_type_h)( &loc ) != RTEMS_FILESYSTEM_DIRECTORY ){ rtems_filesystem_freenode( &loc ); + rtems_filesystem_freenode( &parentloc ); rtems_set_errno_and_return_minus_one( ENOTDIR ); } @@ -65,12 +89,14 @@ int rmdir( if ( !loc.handlers->rmnod_h ){ rtems_filesystem_freenode( &loc ); + rtems_filesystem_freenode( &parentloc ); rtems_set_errno_and_return_minus_one( ENOTSUP ); } - result = (*loc.handlers->rmnod_h)( &loc ); + result = (*loc.handlers->rmnod_h)( &parentloc, &loc ); rtems_filesystem_freenode( &loc ); + rtems_filesystem_freenode( &parentloc ); return result; } diff --git a/cpukit/libcsupport/src/stat.c b/cpukit/libcsupport/src/stat.c index c2f2badf22..5e26f94322 100644 --- a/cpukit/libcsupport/src/stat.c +++ b/cpukit/libcsupport/src/stat.c @@ -59,7 +59,8 @@ int _STAT_NAME( if ( !buf ) rtems_set_errno_and_return_minus_one( EFAULT ); - status = rtems_filesystem_evaluate_path( path, 0, &loc, _STAT_FOLLOW_LINKS ); + status = rtems_filesystem_evaluate_path( path, strlen( path ), + 0, &loc, _STAT_FOLLOW_LINKS ); if ( status != 0 ) return -1; diff --git a/cpukit/libcsupport/src/unlink.c b/cpukit/libcsupport/src/unlink.c index a441d4d6ec..43b1db5705 100644 --- a/cpukit/libcsupport/src/unlink.c +++ b/cpukit/libcsupport/src/unlink.c @@ -24,41 +24,67 @@ int unlink( const char *path ) { + int parentpathlen; + const char *name; + rtems_filesystem_location_info_t parentloc; rtems_filesystem_location_info_t loc; + int i; int result; /* - * Get the node to be unlinked. + * Get the node to be unlinked. Find the parent path first. */ - - result = rtems_filesystem_evaluate_path( path, 0, &loc, false ); - if ( result != 0 ) - return -1; - - result = rtems_filesystem_evaluate_parent(RTEMS_LIBIO_PERMS_WRITE, &loc ); - if (result != 0 && errno != ENOTSUP) { - rtems_filesystem_freenode( &loc ); + + parentpathlen = rtems_filesystem_dirname ( path ); + + if ( parentpathlen == 0 ) + rtems_filesystem_get_start_loc( path, &i, &parentloc ); + else { + result = rtems_filesystem_evaluate_path( path, parentpathlen, + RTEMS_LIBIO_PERMS_WRITE, + &parentloc, + false ); + if ( result != 0 ) + return -1; + } + + /* + * Start from the parent to find the node that should be under it. + */ + + loc = parentloc; + name = path + parentpathlen; + name += rtems_filesystem_prefix_separators( name, strlen( name ) ); + + result = rtems_filesystem_evaluate_relative_path( name , strlen( name ), + 0, &loc, false ); + if ( result != 0 ) { + rtems_filesystem_freenode( &parentloc ); return -1; } - + if ( !loc.ops->node_type_h ) { rtems_filesystem_freenode( &loc ); + rtems_filesystem_freenode( &parentloc ); rtems_set_errno_and_return_minus_one( ENOTSUP ); } if ( (*loc.ops->node_type_h)( &loc ) == RTEMS_FILESYSTEM_DIRECTORY ) { rtems_filesystem_freenode( &loc ); + rtems_filesystem_freenode( &parentloc ); rtems_set_errno_and_return_minus_one( EISDIR ); } if ( !loc.ops->unlink_h ) { rtems_filesystem_freenode( &loc ); + rtems_filesystem_freenode( &parentloc ); rtems_set_errno_and_return_minus_one( ENOTSUP ); } - result = (*loc.ops->unlink_h)( &loc ); + result = (*loc.ops->unlink_h)( &parentloc, &loc ); rtems_filesystem_freenode( &loc ); + rtems_filesystem_freenode( &parentloc ); return result; } diff --git a/cpukit/libcsupport/src/unmount.c b/cpukit/libcsupport/src/unmount.c index e4ee7a74a4..774df9931d 100644 --- a/cpukit/libcsupport/src/unmount.c +++ b/cpukit/libcsupport/src/unmount.c @@ -113,7 +113,7 @@ int unmount( * The mount entry that is being refered to. */ - if ( rtems_filesystem_evaluate_path( path, 0x0, &loc, true ) ) + if ( rtems_filesystem_evaluate_path( path, strlen( path ), 0x0, &loc, true ) ) return -1; mt_entry = loc.mt_entry; diff --git a/cpukit/libcsupport/src/utime.c b/cpukit/libcsupport/src/utime.c index 5bd5060549..6cceea719f 100644 --- a/cpukit/libcsupport/src/utime.c +++ b/cpukit/libcsupport/src/utime.c @@ -30,7 +30,7 @@ int utime( rtems_filesystem_location_info_t temp_loc; int result; - if ( rtems_filesystem_evaluate_path( path, 0x00, &temp_loc, true ) ) + if ( rtems_filesystem_evaluate_path( path, strlen( path ), 0x00, &temp_loc, true ) ) return -1; if ( !temp_loc.ops->utime_h ){ |