jingfei195887 opened a new pull request, #21752:
URL: https://github.com/apache/nuttx/pull/21752

   ## Summary
   
   POSIX error handling fixes for symlink(), unlink(), rmdir() and readlink()
   on the pseudo file system.
   
   - **fs/vfs: reject an empty symlink target.** `symlink("", path)` created a
     link to "", which POSIX rejects with ENOENT. Any `inode_find()` failure
     for path2 was also taken as "path2 does not exist"; only -ENOENT now leads
     to creating the link.
   - **fs/vfs: return EEXIST for symlink() over a link.** path2 was looked up
     with the final link followed, so a dangling link at path2 was replaced
     instead of failing with EEXIST.
   - **fs/vfs: return EISDIR from unlink() of a directory.** `nx_unlink()`
     removed an empty pseudo directory as if it were a file. POSIX does not
     allow unlink() of a directory; `remove()` already falls back to
     `rmdir()` on EISDIR.
   - **fs/vfs: return EINVAL from rmdir() of "dir/.".** The lookup collapses
     ".", so `rmdir("dir/.")` removed dir. POSIX requires EINVAL when the last
     component is dot.
   - **fs/vfs: do not NUL-terminate readlink() output.** When the target did
     not fit, the last byte of the buffer was a NUL instead of the next byte of
     the target, although readlink() returned bufsize.
   
   ## Impact
   
   `unlink()` of an empty pseudo directory now fails with EISDIR; `rmdir()`,
   `remove()` and `rm -r` still remove it. Pseudo files, drivers and links
   are unlinked as before.
   
   ## Testing
   
   Host: Ubuntu x86_64, gcc (Ubuntu 13.1.0-8ubuntu1~22.04) 13.1.0, master 
72c45233a0 (rebased onto 72c45233a0; no
   new commit touches these files), `sim:nsh` with `CONFIG_FS_LINKS`. A small
   test program:
   
   | call | master | this PR |
   |---|---|---|
   | `symlink("", "/l")` | 0 | -1, ENOENT |
   | `symlink("/etc", "/l")` with `/l` a dangling link | 0 | -1, EEXIST |
   | `unlink("/d")` of an empty pseudo directory | 0, `/d` removed | -1, 
EISDIR, `/d` kept |
   | `rmdir("/tmp/d/.")` | 0, `/tmp/d` removed | -1, EINVAL, `/tmp/d` kept |
   | `readlink()` of `/etc/group` into 4 bytes | 4, "/et\\0" | 4, "/etc" |
   
   With `CONFIG_PSEUDOFS_FILE`, `unlink()` of a pseudo file and of a link,
   and `remove()` of a pseudo directory, succeed on both master and this PR.
   
   - `./tools/checkpatch.sh -g master..HEAD`: all checks pass.
   - Make and CMake builds pass; `ostest` exits with status 0.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

  • [PR] fs/vfs: POSIX error hand... jingfei195887 (via GitHub) via commits

Reply via email to