summaryrefslogtreecommitdiffhomepage
path: root/test/syscalls/linux/symlink.cc
diff options
context:
space:
mode:
Diffstat (limited to 'test/syscalls/linux/symlink.cc')
-rw-r--r--test/syscalls/linux/symlink.cc30
1 files changed, 30 insertions, 0 deletions
diff --git a/test/syscalls/linux/symlink.cc b/test/syscalls/linux/symlink.cc
index 4d9eba7f0..ea219a091 100644
--- a/test/syscalls/linux/symlink.cc
+++ b/test/syscalls/linux/symlink.cc
@@ -269,6 +269,36 @@ TEST(SymlinkTest, SymlinkAtDegradedPermissions_NoRandomSave) {
EXPECT_THAT(close(dirfd), SyscallSucceeds());
}
+TEST(SymlinkTest, SymlinkAtDirWithOpath) {
+ SKIP_IF(IsRunningWithVFS1());
+ auto dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir());
+ const std::string filepath = NewTempAbsPathInDir(dir.path());
+ const std::string base = std::string(Basename(filepath));
+ FileDescriptor dirfd =
+ ASSERT_NO_ERRNO_AND_VALUE(Open(dir.path().c_str(), O_DIRECTORY | O_PATH));
+
+ EXPECT_THAT(symlinkat("/dangling", dirfd.get(), base.c_str()),
+ SyscallSucceeds());
+}
+
+TEST(SymlinkTest, ReadlinkAtDirWithOpath) {
+ SKIP_IF(IsRunningWithVFS1());
+ auto dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir());
+ const std::string filepath = NewTempAbsPathInDir(dir.path());
+ const std::string base = std::string(Basename(filepath));
+ ASSERT_THAT(symlink("/dangling", filepath.c_str()), SyscallSucceeds());
+
+ FileDescriptor dirfd =
+ ASSERT_NO_ERRNO_AND_VALUE(Open(dir.path().c_str(), O_DIRECTORY | O_PATH));
+
+ std::vector<char> buf(1024);
+ int linksize;
+ EXPECT_THAT(
+ linksize = readlinkat(dirfd.get(), base.c_str(), buf.data(), 1024),
+ SyscallSucceeds());
+ EXPECT_EQ(0, strncmp("/dangling", buf.data(), linksize));
+}
+
TEST(SymlinkTest, ReadlinkAtDegradedPermissions_NoRandomSave) {
// Drop capabilities that allow us to override file and directory permissions.
ASSERT_NO_ERRNO(SetCapability(CAP_DAC_OVERRIDE, false));