summaryrefslogtreecommitdiff
path: root/Kernel/FileSystem/VirtualFileSystem.cpp
diff options
context:
space:
mode:
authorMax Wipfli <mail@maxwipfli.ch>2021-07-11 13:46:05 +0200
committerGunnar Beutner <gunnar@beutner.name>2021-07-11 14:59:57 +0200
commit29d53cbee2cb153a50d63e12311c70209d8e7c05 (patch)
tree290b02c338ca2fe37f1345d73e9b739a9eacf2f5 /Kernel/FileSystem/VirtualFileSystem.cpp
parent25e850ebb1ca4c1326fda8b8ee36251c5d91ceaf (diff)
downloadserenity-29d53cbee2cb153a50d63e12311c70209d8e7c05.zip
Kernel: Return correct error numbers for the mkdir syscall
Previously, VirtualFileSystem::mkdir() would always return ENOENT if no parent custody was returned by resolve_path(). This is incorrect when e.g. the user has no search permission in a component of the path prefix (=> EACCES), or if on component of the path prefix is a file (=> ENOTDIR). This patch fixes that behavior.
Diffstat (limited to 'Kernel/FileSystem/VirtualFileSystem.cpp')
-rw-r--r--Kernel/FileSystem/VirtualFileSystem.cpp14
1 files changed, 9 insertions, 5 deletions
diff --git a/Kernel/FileSystem/VirtualFileSystem.cpp b/Kernel/FileSystem/VirtualFileSystem.cpp
index a82398090b..dea72217e5 100644
--- a/Kernel/FileSystem/VirtualFileSystem.cpp
+++ b/Kernel/FileSystem/VirtualFileSystem.cpp
@@ -388,16 +388,20 @@ KResult VirtualFileSystem::mkdir(StringView path, mode_t mode, Custody& base)
// path component (the one being created) that is allowed not to
// exist, POSIX allows mkdir'ed path to have trailing slashes.
// Let's handle that case by trimming any trailing slashes.
- while (path.length() > 1 && path.ends_with("/"))
- path = path.substring_view(0, path.length() - 1);
+ path = path.trim("/"sv, TrimMode::Right);
+ if (path.is_empty()) {
+ // NOTE: This means the path was a series of slashes, which resolves to "/".
+ path = "/";
+ }
RefPtr<Custody> parent_custody;
- if (auto result = resolve_path(path, base, &parent_custody); !result.is_error())
+ auto result = resolve_path(path, base, &parent_custody);
+ if (!result.is_error())
return EEXIST;
else if (!parent_custody)
- return ENOENT;
- else if (result.error() != -ENOENT)
return result.error();
+ // NOTE: If resolve_path fails with a non-null parent custody, the error should be ENOENT.
+ VERIFY(result.error() == -ENOENT);
auto& parent_inode = parent_custody->inode();
auto current_process = Process::current();