mirror of
https://github.com/eledio-devices/thirdparty-littlefs.git
synced 2025-11-01 00:38:29 +01:00
Picked up path corner case fixes
This commit is contained in:
75
lfs.c
75
lfs.c
@@ -1273,21 +1273,19 @@ static int32_t lfs_dir_get(lfs_t *lfs, lfs_mdir_t *dir,
|
||||
}
|
||||
|
||||
static int32_t lfs_dir_lookup(lfs_t *lfs, lfs_mdir_t *dir, const char **path) {
|
||||
lfs_block_t pair[2] = {lfs->root[0], lfs->root[1]};
|
||||
// we reduce path to a single name if we can find it
|
||||
const char *name = *path;
|
||||
lfs_size_t namelen;
|
||||
int32_t tag;
|
||||
*path = NULL;
|
||||
|
||||
// default to root dir
|
||||
int32_t tag = LFS_MKTAG(LFS_TYPE_DIR, 0x3ff, 0);
|
||||
lfs_block_t pair[2] = {lfs->root[0], lfs->root[1]};
|
||||
|
||||
while (true) {
|
||||
nextname:
|
||||
nextname:
|
||||
// skip slashes
|
||||
name += strspn(name, "/");
|
||||
namelen = strcspn(name, "/");
|
||||
|
||||
if (name[0] == '\0') {
|
||||
// special case for root dir
|
||||
return LFS_MKTAG(LFS_TYPE_DIR, 0x3ff, 0);
|
||||
}
|
||||
lfs_size_t namelen = strcspn(name, "/");
|
||||
|
||||
// skip '.' and root '..'
|
||||
if ((namelen == 1 && memcmp(name, ".", 1) == 0) ||
|
||||
@@ -1320,10 +1318,31 @@ static int32_t lfs_dir_lookup(lfs_t *lfs, lfs_mdir_t *dir, const char **path) {
|
||||
suffix += sufflen;
|
||||
}
|
||||
|
||||
// update what we've found
|
||||
*path = name;
|
||||
// found path
|
||||
if (name[0] == '\0') {
|
||||
return tag;
|
||||
}
|
||||
|
||||
// find path
|
||||
// update what we've found if path is only a name
|
||||
if (strchr(name, '/') == NULL) {
|
||||
*path = name;
|
||||
}
|
||||
|
||||
// only continue if we hit a directory
|
||||
if (lfs_tagtype(tag) != LFS_TYPE_DIR) {
|
||||
return LFS_ERR_NOTDIR;
|
||||
}
|
||||
|
||||
// grab the entry data
|
||||
if (lfs_tagid(tag) != 0x3ff) {
|
||||
int32_t res = lfs_dir_get(lfs, dir, 0x7c3ff000,
|
||||
LFS_MKTAG(LFS_TYPE_STRUCT, lfs_tagid(tag), 8), pair);
|
||||
if (res < 0) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
// find entry matching name
|
||||
while (true) {
|
||||
tag = lfs_dir_find(lfs, dir, pair, 0x7c000fff,
|
||||
LFS_MKTAG(LFS_TYPE_NAME, 0, namelen), name);
|
||||
@@ -1337,6 +1356,7 @@ static int32_t lfs_dir_lookup(lfs_t *lfs, lfs_mdir_t *dir, const char **path) {
|
||||
}
|
||||
|
||||
if (!dir->split) {
|
||||
// couldn't find it
|
||||
return LFS_ERR_NOENT;
|
||||
}
|
||||
|
||||
@@ -1344,26 +1364,8 @@ static int32_t lfs_dir_lookup(lfs_t *lfs, lfs_mdir_t *dir, const char **path) {
|
||||
pair[1] = dir->tail[1];
|
||||
}
|
||||
|
||||
// to next name
|
||||
name += namelen;
|
||||
name += strspn(name, "/");
|
||||
if (name[0] == '\0') {
|
||||
return tag;
|
||||
}
|
||||
|
||||
// don't continue on if we didn't hit a directory
|
||||
// TODO update with what's on master?
|
||||
if (lfs_tagtype(tag) != LFS_TYPE_DIR) {
|
||||
return LFS_ERR_NOTDIR;
|
||||
}
|
||||
|
||||
// TODO optimize grab for inline files and like?
|
||||
// TODO would this mean more code?
|
||||
// grab the entry data
|
||||
int32_t res = lfs_dir_get(lfs, dir, 0x7c3ff000,
|
||||
LFS_MKTAG(LFS_TYPE_STRUCT, lfs_tagid(tag), 8), pair);
|
||||
if (res < 0) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1408,11 +1410,8 @@ int lfs_mkdir(lfs_t *lfs, const char *path) {
|
||||
|
||||
lfs_mdir_t cwd;
|
||||
int32_t res = lfs_dir_lookup(lfs, &cwd, &path);
|
||||
if (res != LFS_ERR_NOENT || strchr(path, '/') != NULL) {
|
||||
if (res >= 0) {
|
||||
return LFS_ERR_EXIST;
|
||||
}
|
||||
return res;
|
||||
if (res != LFS_ERR_NOENT || !path) {
|
||||
return (res < 0) ? res : LFS_ERR_EXIST;
|
||||
}
|
||||
|
||||
// check that name fits
|
||||
@@ -1806,7 +1805,7 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
|
||||
// allocate entry for file if it doesn't exist
|
||||
lfs_mdir_t cwd;
|
||||
int32_t tag = lfs_dir_lookup(lfs, &cwd, &path);
|
||||
if (tag < 0 && (tag != LFS_ERR_NOENT || strchr(path, '/') != NULL)) {
|
||||
if (tag < 0 && (tag != LFS_ERR_NOENT || !path)) {
|
||||
return tag;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user