mirror of
https://github.com/apache/nuttx.git
synced 2026-08-17 01:23:01 +08:00
fs: resolve a trailing lone '.' path component
inode_nextname() already skipped a '.' segment mid-path (e.g. "./foo"), but only checked for a '/' right after it -- a path ending in a bare '.' (e.g. "/foo/.", or "." itself once AT_FDCWD resolution prepends $PWD) fell through and was looked up as a literal child named ".", which no real node is ever named, failing with ENOENT. This broke every "operate on the current directory" idiom relative paths rely on: bare `ls`, `stat .`, `cd .`, etc., all failed outright even though the equivalent absolute path worked fine. Found while testing the Toybox port's interactive REPL, but this is generic VFS path resolution, not Toybox-specific. Signed-off-by: Alan C. Assis <acassis@gmail.com> Assisted-by: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
committed by
Xiang Xiao
parent
3cbf6f2168
commit
c1891e07c9
@@ -558,15 +558,32 @@ FAR const char *inode_nextname(FAR const char *name)
|
|||||||
name++;
|
name++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skip single '.' path segment, but not '..' */
|
/* Skip single '.' path segment, but not '..'. This includes a lone
|
||||||
|
* trailing '.' as the final path component (e.g. "/foo/."), which
|
||||||
|
* refers to "foo" itself the same way "/foo/./" would -- without this,
|
||||||
|
* a trailing '.' is instead treated as a literal child name to look up
|
||||||
|
* under "foo" and fails to resolve, since no real node is ever named
|
||||||
|
* ".", rather than resolving to the node the search already reached.
|
||||||
|
*/
|
||||||
|
|
||||||
if (*name == '.' && *(name + 1) == '/')
|
if (*name == '.' && (*(name + 1) == '/' || *(name + 1) == '\0'))
|
||||||
{
|
{
|
||||||
/* If there is a '/' after '.',
|
if (*(name + 1) == '/')
|
||||||
* continue searching from the next character
|
{
|
||||||
*/
|
/* If there is a '/' after '.',
|
||||||
|
* continue searching from the next character
|
||||||
|
*/
|
||||||
|
|
||||||
name = inode_nextname(name);
|
name = inode_nextname(name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Lone trailing '.': point past it, at the terminating NUL,
|
||||||
|
* the same as if the path had ended one character earlier.
|
||||||
|
*/
|
||||||
|
|
||||||
|
name++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return name;
|
return name;
|
||||||
|
|||||||
Reference in New Issue
Block a user