Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/littlefs-project/littlefs.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lfs.c
diff options
context:
space:
mode:
authorChristopher Haster <chaster@utexas.edu>2018-04-22 15:26:31 +0300
committerChristopher Haster <chaster@utexas.edu>2018-04-22 15:26:31 +0300
commit015b86bc51fddbd9d0e7c68e02015f8fd12c5839 (patch)
tree94d56c181b5e271b02ca8be8c6fb0fc6e6545334 /lfs.c
parent9637b9606965d40692724e9a5a742e8e87d6c602 (diff)
Fixed issue with trailing dots in file pathsfix-trailing-dots
Paths such as the following were causing issues: /tea/hottea/. /tea/hottea/.. Unfortunately the existing structure for path lookup didn't make it very easy to introduce proper handling in this case without duplicating the entire skip logic for paths. So the lfs_dir_find function had to be restructured a bit. One odd side-effect of this is that now lfs_dir_find includes the initial fetch operation. This kinda breaks the fetch -> op pattern of the dir functions, but does come with a nice code size reduction.
Diffstat (limited to 'lfs.c')
-rw-r--r--lfs.c100
1 files changed, 30 insertions, 70 deletions
diff --git a/lfs.c b/lfs.c
index 3aef9fc..490a508 100644
--- a/lfs.c
+++ b/lfs.c
@@ -783,26 +783,19 @@ static int lfs_dir_find(lfs_t *lfs, lfs_dir_t *dir,
lfs_entry_t *entry, const char **path) {
const char *pathname = *path;
size_t pathlen;
+ entry->d.type = LFS_TYPE_DIR;
+ entry->d.elen = sizeof(entry->d) - 4;
+ entry->d.alen = 0;
+ entry->d.nlen = 0;
+ entry->d.u.dir[0] = lfs->root[0];
+ entry->d.u.dir[1] = lfs->root[1];
while (true) {
- nextname:
+nextname:
// skip slashes
pathname += strspn(pathname, "/");
pathlen = strcspn(pathname, "/");
- // special case for root dir
- if (pathname[0] == '\0') {
- *entry = (lfs_entry_t){
- .d.type = LFS_TYPE_DIR,
- .d.elen = sizeof(entry->d) - 4,
- .d.alen = 0,
- .d.nlen = 0,
- .d.u.dir[0] = lfs->root[0],
- .d.u.dir[1] = lfs->root[1],
- };
- return 0;
- }
-
// skip '.' and root '..'
if ((pathlen == 1 && memcmp(pathname, ".", 1) == 0) ||
(pathlen == 2 && memcmp(pathname, "..", 2) == 0)) {
@@ -834,10 +827,25 @@ static int lfs_dir_find(lfs_t *lfs, lfs_dir_t *dir,
suffix += sufflen;
}
+ // found path
+ if (pathname[0] == '\0') {
+ return 0;
+ }
+
// update what we've found
*path = pathname;
- // find path
+ // continue on if we hit a directory
+ if (entry->d.type != LFS_TYPE_DIR) {
+ return LFS_ERR_NOTDIR;
+ }
+
+ int err = lfs_dir_fetch(lfs, dir, entry->d.u.dir);
+ if (err) {
+ return err;
+ }
+
+ // find entry matching name
while (true) {
int err = lfs_dir_next(lfs, dir, entry);
if (err) {
@@ -873,21 +881,8 @@ static int lfs_dir_find(lfs_t *lfs, lfs_dir_t *dir,
entry->d.type &= ~0x80;
}
+ // to next name
pathname += pathlen;
- pathname += strspn(pathname, "/");
- if (pathname[0] == '\0') {
- return 0;
- }
-
- // continue on if we hit a directory
- if (entry->d.type != LFS_TYPE_DIR) {
- return LFS_ERR_NOTDIR;
- }
-
- int err = lfs_dir_fetch(lfs, dir, entry->d.u.dir);
- if (err) {
- return err;
- }
}
}
@@ -904,13 +899,8 @@ int lfs_mkdir(lfs_t *lfs, const char *path) {
// fetch parent directory
lfs_dir_t cwd;
- int err = lfs_dir_fetch(lfs, &cwd, lfs->root);
- if (err) {
- return err;
- }
-
lfs_entry_t entry;
- err = lfs_dir_find(lfs, &cwd, &entry, &path);
+ int err = lfs_dir_find(lfs, &cwd, &entry, &path);
if (err != LFS_ERR_NOENT || strchr(path, '/') != NULL) {
return err ? err : LFS_ERR_EXIST;
}
@@ -954,13 +944,8 @@ int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path) {
dir->pair[0] = lfs->root[0];
dir->pair[1] = lfs->root[1];
- int err = lfs_dir_fetch(lfs, dir, dir->pair);
- if (err) {
- return err;
- }
-
lfs_entry_t entry;
- err = lfs_dir_find(lfs, dir, &entry, &path);
+ int err = lfs_dir_find(lfs, dir, &entry, &path);
if (err) {
return err;
} else if (entry.d.type != LFS_TYPE_DIR) {
@@ -1302,13 +1287,8 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
// allocate entry for file if it doesn't exist
lfs_dir_t cwd;
- int err = lfs_dir_fetch(lfs, &cwd, lfs->root);
- if (err) {
- return err;
- }
-
lfs_entry_t entry;
- err = lfs_dir_find(lfs, &cwd, &entry, &path);
+ int err = lfs_dir_find(lfs, &cwd, &entry, &path);
if (err && (err != LFS_ERR_NOENT || strchr(path, '/') != NULL)) {
return err;
}
@@ -1814,13 +1794,8 @@ lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file) {
/// General fs operations ///
int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info) {
lfs_dir_t cwd;
- int err = lfs_dir_fetch(lfs, &cwd, lfs->root);
- if (err) {
- return err;
- }
-
lfs_entry_t entry;
- err = lfs_dir_find(lfs, &cwd, &entry, &path);
+ int err = lfs_dir_find(lfs, &cwd, &entry, &path);
if (err) {
return err;
}
@@ -1855,13 +1830,8 @@ int lfs_remove(lfs_t *lfs, const char *path) {
}
lfs_dir_t cwd;
- int err = lfs_dir_fetch(lfs, &cwd, lfs->root);
- if (err) {
- return err;
- }
-
lfs_entry_t entry;
- err = lfs_dir_find(lfs, &cwd, &entry, &path);
+ int err = lfs_dir_find(lfs, &cwd, &entry, &path);
if (err) {
return err;
}
@@ -1916,24 +1886,14 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
// find old entry
lfs_dir_t oldcwd;
- int err = lfs_dir_fetch(lfs, &oldcwd, lfs->root);
- if (err) {
- return err;
- }
-
lfs_entry_t oldentry;
- err = lfs_dir_find(lfs, &oldcwd, &oldentry, &oldpath);
+ int err = lfs_dir_find(lfs, &oldcwd, &oldentry, &oldpath);
if (err) {
return err;
}
// allocate new entry
lfs_dir_t newcwd;
- err = lfs_dir_fetch(lfs, &newcwd, lfs->root);
- if (err) {
- return err;
- }
-
lfs_entry_t preventry;
err = lfs_dir_find(lfs, &newcwd, &preventry, &newpath);
if (err && (err != LFS_ERR_NOENT || strchr(newpath, '/') != NULL)) {