Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
paths: Fixed/doc trailing slash/dot POSIX incompatibilities
- lfs_mkdir now accepts trailing slashes: - before: lfs_mkdir("a/") => LFS_ERR_NOENT - after: lfs_mkdir("a/") => 0 - lfs_stat, lfs_getattr, etc, now reject trailing slashes if the file is not a directory: - before: lfs_stat("reg_a/") => 0 - after: lfs_stat("reg_a/") => LFS_ERR_NOTDIR Note trailing slashes are accepted if the file is a directory: - before: lfs_stat("dir_a/") => 0 - after: lfs_stat("dir_a/") => 0 - lfs_file_open now returns LFS_ERR_NOTDIR if the file exists but the path contains trailing slashes: - before: lfs_file_open("reg_a/") => LFS_ERR_NOENT - after: lfs_file_open("reg_a/") => LFS_ERR_NOTDIR To make these work, the internal lfs_dir_find API required some interesting changes: - lfs_dir_find no longer sets id=0x3ff on not finding a parent entry in the path. Instead, lfs_path_islast can be used to determine if the modified path references a parent entry or child entry based on the remainder of the path string. Note this is only necessary for functions that create new entries (lfs_mkdir, lfs_rename, lfs_file_open). - Trailing slashes mean we can no longer rely on the modified path being NULL-terminated. lfs_path_namelen provides an alternative to strlen that stops at slash or NULL. - lfs_path_isdir also tells you if the modified path must reference a dir (contains trailing slashes). I considered handling this entirely in lfs_dir_find, but the behavior of entry-creating functions is too nuanced. At least lfs_dir_find returns LFS_ERR_NOTDIR if the file exists on disk. Like strlen, lfs_path_namelen/islast/isdir are all O(n) where n is the name length. This isn't great, but if you're using filenames large enough for this to actually matter... uh... open an issue on GitHub and we might improve this in the future. --- There are a couple POSIX incompatibilities that I think are not worth fixing: - Root modifications return EINVAL instead of EBUSY: - littlefs: remove("/") => EINVAL - POSIX: remove("/") => EBUSY Reason: This would be the only use of EBUSY in the system. - We accept modifications of directories with trailing dots: - littlefs: remove("a/.") => 0 - POSIX: remove("a/.") => EBUSY Reason: Not worth implementing. - We do not check for existence of directories followed by dotdots: - littlefs: stat("a/missing/..") => 0 - POSIX: stat("a/missing/..") => ENOENT Reason: Difficult to implement non-recursively. - We accept modifications of directories with trailing dotdots: - littlefs: rename("a/b/..", "c") => 0 - POSIX: rename("a/b/..", "c") => EBUSY Reason: Not worth implementing. These are at least now documented in tests/test_paths.toml, which isn't the greatest location, but it's at least something until a better document is created. Note that these don't really belong in SPEC.md because path parsing is a function of the driver and has no impact on disk.
- Loading branch information