mirror of
https://github.com/apache/nuttx.git
synced 2026-06-01 16:59:28 +08:00
tools/gencromfs.c and fs/cromfs: More corrections to directory traversal logic. Still some bugs.
This commit is contained in:
+16
-7
@@ -104,6 +104,7 @@ static FAR void *cromfs_offset2addr(FAR const struct cromfs_volume_s *fs,
|
|||||||
static uint32_t cromfs_addr2offset(FAR const struct cromfs_volume_s *fs,
|
static uint32_t cromfs_addr2offset(FAR const struct cromfs_volume_s *fs,
|
||||||
FAR const void *addr);
|
FAR const void *addr);
|
||||||
static int cromfs_foreach_node(FAR const struct cromfs_volume_s *fs,
|
static int cromfs_foreach_node(FAR const struct cromfs_volume_s *fs,
|
||||||
|
FAR const struct cromfs_node_s *node,
|
||||||
cromfs_foreach_t callback, FAR void *arg);
|
cromfs_foreach_t callback, FAR void *arg);
|
||||||
static uint16_t cromfs_seglen(FAR const char *relpath);
|
static uint16_t cromfs_seglen(FAR const char *relpath);
|
||||||
static int cromfs_comparenode(FAR const struct cromfs_volume_s *fs,
|
static int cromfs_comparenode(FAR const struct cromfs_volume_s *fs,
|
||||||
@@ -256,12 +257,15 @@ static uint32_t cromfs_addr2offset(FAR const struct cromfs_volume_s *fs,
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int cromfs_foreach_node(FAR const struct cromfs_volume_s *fs,
|
static int cromfs_foreach_node(FAR const struct cromfs_volume_s *fs,
|
||||||
|
FAR const struct cromfs_node_s *node,
|
||||||
cromfs_foreach_t callback, FAR void *arg)
|
cromfs_foreach_t callback, FAR void *arg)
|
||||||
{
|
{
|
||||||
FAR const struct cromfs_node_s *node;
|
|
||||||
int ret = OK;
|
int ret = OK;
|
||||||
|
|
||||||
node = (FAR const struct cromfs_node_s *)cromfs_offset2addr(fs, fs->cv_root);
|
/* Traverse all entries in this directory (i.e., following the 'peer'
|
||||||
|
* links).
|
||||||
|
*/
|
||||||
|
|
||||||
while (node != NULL)
|
while (node != NULL)
|
||||||
{
|
{
|
||||||
ret = callback(fs, node, arg);
|
ret = callback(fs, node, arg);
|
||||||
@@ -351,7 +355,7 @@ static int cromfs_comparenode(FAR const struct cromfs_volume_s *fs,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A specal cas is if the path ends in "/". In this case I suppose
|
/* A special case is if the path ends in "/". In this case I suppose
|
||||||
* we need to interpret the as matching as long as it is a directory?
|
* we need to interpret the as matching as long as it is a directory?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -391,7 +395,7 @@ static int cromfs_comparenode(FAR const struct cromfs_volume_s *fs,
|
|||||||
|
|
||||||
/* Then recurse */
|
/* Then recurse */
|
||||||
|
|
||||||
return cromfs_foreach_node(fs, cromfs_comparenode, cpnode);
|
return cromfs_foreach_node(fs, node, cromfs_comparenode, cpnode);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -408,14 +412,19 @@ static int cromfs_findnode(FAR const struct cromfs_volume_s *fs,
|
|||||||
FAR const char *relpath)
|
FAR const char *relpath)
|
||||||
{
|
{
|
||||||
struct cromfs_comparenode_s cpnode;
|
struct cromfs_comparenode_s cpnode;
|
||||||
|
FAR const struct cromfs_node_s *root;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
/* Get the root node */
|
||||||
|
|
||||||
|
root = (FAR const struct cromfs_node_s *)
|
||||||
|
cromfs_offset2addr(fs, fs->cv_root);
|
||||||
|
|
||||||
/* NULL or empty string refers to the root node */
|
/* NULL or empty string refers to the root node */
|
||||||
|
|
||||||
if (relpath == NULL || relpath[0] == '\0')
|
if (relpath == NULL || relpath[0] == '\0')
|
||||||
{
|
{
|
||||||
*node = (FAR const struct cromfs_node_s *)
|
*node = root;
|
||||||
cromfs_offset2addr(fs, fs->cv_root);
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -433,7 +442,7 @@ static int cromfs_findnode(FAR const struct cromfs_volume_s *fs,
|
|||||||
cpnode.segment = relpath;
|
cpnode.segment = relpath;
|
||||||
cpnode.seglen = (uint16_t)cromfs_seglen(relpath);
|
cpnode.seglen = (uint16_t)cromfs_seglen(relpath);
|
||||||
|
|
||||||
ret = cromfs_foreach_node(fs, cromfs_comparenode, &cpnode);
|
ret = cromfs_foreach_node(fs, root, cromfs_comparenode, &cpnode);
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
{
|
{
|
||||||
return OK;
|
return OK;
|
||||||
|
|||||||
+18
-16
@@ -260,7 +260,7 @@ static void gen_directory(const char *path, const char *name, mode_t mode,
|
|||||||
bool lastentry);
|
bool lastentry);
|
||||||
static void gen_file(const char *path, const char *name, mode_t mode,
|
static void gen_file(const char *path, const char *name, mode_t mode,
|
||||||
bool lastentry);
|
bool lastentry);
|
||||||
static void process_direntry(const char *dirpath, struct dirent *direntry,
|
static void process_direntry(const char *dirpath, const char *name,
|
||||||
bool lastentry);
|
bool lastentry);
|
||||||
static void traverse_directory(const char *dirpath);
|
static void traverse_directory(const char *dirpath);
|
||||||
|
|
||||||
@@ -1079,14 +1079,14 @@ static void gen_file(const char *path, const char *name, mode_t mode,
|
|||||||
append_tmpfile(g_tmpstream, outstream);
|
append_tmpfile(g_tmpstream, outstream);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_direntry(const char *dirpath, struct dirent *direntry,
|
static void process_direntry(const char *dirpath, const char *name,
|
||||||
bool lastentry)
|
bool lastentry)
|
||||||
{
|
{
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
char *path;
|
char *path;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
asprintf(&path, "%s/%s", dirpath, direntry->d_name);
|
asprintf(&path, "%s/%s", dirpath, name);
|
||||||
|
|
||||||
ret = stat(path, &buf);
|
ret = stat(path, &buf);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@@ -1109,11 +1109,11 @@ static void process_direntry(const char *dirpath, struct dirent *direntry,
|
|||||||
|
|
||||||
else if (S_ISDIR(buf.st_mode))
|
else if (S_ISDIR(buf.st_mode))
|
||||||
{
|
{
|
||||||
gen_directory(path, direntry->d_name, buf.st_mode, lastentry);
|
gen_directory(path, name, buf.st_mode, lastentry);
|
||||||
}
|
}
|
||||||
else if (S_ISREG(buf.st_mode))
|
else if (S_ISREG(buf.st_mode))
|
||||||
{
|
{
|
||||||
gen_file(path, direntry->d_name, buf.st_mode, lastentry);
|
gen_file(path, name, buf.st_mode, lastentry);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1127,7 +1127,7 @@ static void traverse_directory(const char *dirpath)
|
|||||||
{
|
{
|
||||||
DIR *dirp;
|
DIR *dirp;
|
||||||
struct dirent *direntry;
|
struct dirent *direntry;
|
||||||
struct dirent *nextentry;
|
char name[NAME_MAX + 1];
|
||||||
|
|
||||||
/* Open the directory */
|
/* Open the directory */
|
||||||
|
|
||||||
@@ -1144,25 +1144,27 @@ static void traverse_directory(const char *dirpath)
|
|||||||
direntry = readdir(dirp);
|
direntry = readdir(dirp);
|
||||||
while (direntry != NULL)
|
while (direntry != NULL)
|
||||||
{
|
{
|
||||||
/* Get the next entry so that we can anticipate the end of the
|
/* Preserve the name from the directory entry. The return value
|
||||||
* directory.
|
* from readdir() only persists until the next time that readdir()
|
||||||
|
* is called (alternatively, use readdir_r).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
nextentry = readdir(dirp);
|
strncpy(name, direntry->d_name, NAME_MAX + 1);
|
||||||
|
|
||||||
|
/* Get the next entry in advance so that we can anticipate the end of
|
||||||
|
* the directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
direntry = readdir(dirp);
|
||||||
|
|
||||||
/* Skip the '.' and '..' hard links */
|
/* Skip the '.' and '..' hard links */
|
||||||
|
|
||||||
if (strcmp(direntry->d_name, ".") != 0 &&
|
if (strcmp(name, ".") != 0 && strcmp(name, "..") != 0)
|
||||||
strcmp(direntry->d_name, "..") != 0)
|
|
||||||
{
|
{
|
||||||
/* Process the directory entry */
|
/* Process the directory entry */
|
||||||
|
|
||||||
process_direntry(dirpath, direntry, nextentry == NULL);
|
process_direntry(dirpath, name, direntry == NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skip to the next entry */
|
|
||||||
|
|
||||||
direntry = nextentry;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user