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]