summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2022-12-19 18:47:35 +0100
committerAndreas Kling <kling@serenityos.org>2023-01-01 10:09:02 +0100
commit8d781d0216d92d48712422ff748e04b946f9da70 (patch)
tree02406d7f13375d06f19a2cfac2f8ee828be072d0
parent42b011b571404fa9a8956a541da08f452046a4bf (diff)
downloadserenity-8d781d0216d92d48712422ff748e04b946f9da70.zip
Kernel+Tests: Make sys$rmdir() fail with EINVAL if basename is "."
Dr. POSIX says that we should reject attempts to rmdir() the file named "." so this patch does exactly that. We also add a test. This solves a FIXME from January 2019. :^)
-rw-r--r--Kernel/FileSystem/VirtualFileSystem.cpp7
-rw-r--r--Tests/LibC/TestIo.cpp20
2 files changed, 26 insertions, 1 deletions
diff --git a/Kernel/FileSystem/VirtualFileSystem.cpp b/Kernel/FileSystem/VirtualFileSystem.cpp
index 7fe25d71e1..8dbf04b207 100644
--- a/Kernel/FileSystem/VirtualFileSystem.cpp
+++ b/Kernel/FileSystem/VirtualFileSystem.cpp
@@ -841,7 +841,12 @@ ErrorOr<void> VirtualFileSystem::rmdir(Credentials const& credentials, StringVie
auto custody = TRY(resolve_path(credentials, path, base, &parent_custody));
auto& inode = custody->inode();
- // FIXME: We should return EINVAL if the last component of the path is "."
+ auto last_component = KLexicalPath::basename(path);
+
+ // [EINVAL] The path argument contains a last component that is dot.
+ if (last_component == "."sv)
+ return EINVAL;
+
// FIXME: We should return ENOTEMPTY if the last component of the path is ".."
if (!inode.is_directory())
diff --git a/Tests/LibC/TestIo.cpp b/Tests/LibC/TestIo.cpp
index b7404df0a2..1a0fd2bdcc 100644
--- a/Tests/LibC/TestIo.cpp
+++ b/Tests/LibC/TestIo.cpp
@@ -317,6 +317,26 @@ TEST_CASE(tmpfs_massive_file)
EXPECT_EQ(rc, 0);
}
+TEST_CASE(rmdir_dot)
+{
+ int rc = mkdir("/home/anon/rmdir-test-1", 0700);
+ EXPECT_EQ(rc, 0);
+
+ rc = rmdir("/home/anon/rmdir-test-1/.");
+ EXPECT_NE(rc, 0);
+ EXPECT_EQ(errno, EINVAL);
+
+ rc = chdir("/home/anon/rmdir-test-1");
+ EXPECT_EQ(rc, 0);
+
+ rc = rmdir(".");
+ VERIFY(rc != 0);
+ EXPECT_EQ(errno, EINVAL);
+
+ rc = rmdir("/home/anon/rmdir-test-1");
+ EXPECT_EQ(rc, 0);
+}
+
TEST_CASE(rmdir_while_inside_dir)
{
int rc = mkdir("/home/anon/testdir", 0700);