tools/gencromfs.c and fs/cromfs: More corrections to directory traversal logic. Still some bugs.

This commit is contained in:
Gregory Nutt
2018-03-20 14:30:05 -06:00
parent 22484386ee
commit aeeee54921
2 changed files with 36 additions and 25 deletions
+16 -7
View File
@@ -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
View File
@@ -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;
} }
} }