Added some corner-case tests, fixed related bugs/POSIX nuances

POSIX is notoriously full of subtle and confusing nuances. Not through
any fault of POSIX, but as a result of trying to describe a complex
system with simple and easy to use operations.

Corner cases fixed here:

- rename("dir", "file") => ENOTDIR

  This is the main surprise to me, and a mistake on my part. I thought
  EISDIR would be appropriate for any renames with mismatched types,
  since both involve a directory. It would be simpler code-wise, and
  avoid ambiguity around if "file" is not a dir, or some other file
  exists in the file's path. But I guess ENOTDIR makes more sense if you
  think of the destination as the target being operated on.

- remove("/") => EINVAL
- rename("/", "x") => EINVAL
- rename("x", "/") => ENOTEMPTY
- open("/") => EISDIR

  It's a bit difficult to lookup what error codes around root operations
  should be, since they mostly end up as EPERM on modern systems, but
  this doesn't really make sense for littlefs.

  The solution chosen here is to prefer directory-related errors (EISDIR,
  ENOTEMPTY) when possible, and fall back to EINVAL when the only issue
  is that the target is the root directory.

Also I tweaked lfsr_mtree_pathlookup a bit so mid=0 indicates the target
is the root and mid=-1 indicates the target can't be created (because of
a missing directory). I think using mid=0 for the latter is a leftover
from when mid=-1 was a bit of a mess...
This commit is contained in:
Christopher Haster
2023-12-01 00:31:19 -06:00
parent abbd2d6c3f
commit 939dd2145a
3 changed files with 540 additions and 34 deletions
+2 -4
View File
@@ -281,16 +281,14 @@ code = '''
}
// try to make root, which doesn't make sense
err = lfsr_mkdir(&lfs, "/");
assert(err == LFS_ERR_EXIST || err == LFS_ERR_INVAL);
lfsr_mkdir(&lfs, "/") => LFS_ERR_EXIST;
// make a directory
err = lfsr_mkdir(&lfs, "ardvark");
assert(!err || (TEST_PLS && err == LFS_ERR_EXIST));
// try to make root, which doesn't make sense
err = lfsr_mkdir(&lfs, "/");
assert(err == LFS_ERR_EXIST || err == LFS_ERR_INVAL);
lfsr_mkdir(&lfs, "/") => LFS_ERR_EXIST;
// remount?
if (REMOUNT) {