diff options
author | gVisor bot <gvisor-bot@google.com> | 2021-01-28 12:22:00 -0800 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-01-28 12:24:37 -0800 |
commit | d8c330254a7df21cb5edac3440b62a512fcc8d2d (patch) | |
tree | 7c37b273cca0389da1375c7984cbd5fd21c01952 /test/syscalls/linux/link.cc | |
parent | 449c155bc00aa36522f80f816b18e9a9521e1fe6 (diff) |
Add O_PATH support in vfs2
PiperOrigin-RevId: 354367665
Diffstat (limited to 'test/syscalls/linux/link.cc')
-rw-r--r-- | test/syscalls/linux/link.cc | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/test/syscalls/linux/link.cc b/test/syscalls/linux/link.cc index 544681168..4f9ca1a65 100644 --- a/test/syscalls/linux/link.cc +++ b/test/syscalls/linux/link.cc @@ -50,6 +50,8 @@ bool IsSameFile(const std::string& f1, const std::string& f2) { return stat1.st_dev == stat2.st_dev && stat1.st_ino == stat2.st_ino; } +// TODO(b/178640646): Add test for linkat with AT_EMPTY_PATH + TEST(LinkTest, CanCreateLinkFile) { auto oldfile = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); const std::string newname = NewTempAbsPath(); @@ -235,6 +237,59 @@ TEST(LinkTest, AbsPathsWithNonDirFDs) { SyscallSucceeds()); } +TEST(LinkTest, NewDirFDWithOpath) { + SKIP_IF(IsRunningWithVFS1()); + auto oldfile = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); + const std::string newname_parent = NewTempAbsPath(); + const std::string newname_base = "child"; + const std::string newname = JoinPath(newname_parent, newname_base); + + // Create newname_parent directory, and get an FD. + EXPECT_THAT(mkdir(newname_parent.c_str(), 0777), SyscallSucceeds()); + const FileDescriptor newname_parent_fd = + ASSERT_NO_ERRNO_AND_VALUE(Open(newname_parent, O_DIRECTORY | O_PATH)); + + // Link newname to oldfile, using newname_parent_fd. + EXPECT_THAT(linkat(AT_FDCWD, oldfile.path().c_str(), newname_parent_fd.get(), + newname.c_str(), 0), + SyscallSucceeds()); + + EXPECT_TRUE(IsSameFile(oldfile.path(), newname)); +} + +TEST(LinkTest, RelPathsNonDirFDsWithOpath) { + SKIP_IF(IsRunningWithVFS1()); + auto oldfile = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); + + // Create a file that will be passed as the directory fd for old/new names. + TempPath path = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); + FileDescriptor file_fd = ASSERT_NO_ERRNO_AND_VALUE(Open(path.path(), O_PATH)); + + // Using file_fd as olddirfd will fail. + EXPECT_THAT(linkat(file_fd.get(), "foo", AT_FDCWD, "bar", 0), + SyscallFailsWithErrno(ENOTDIR)); + + // Using file_fd as newdirfd will fail. + EXPECT_THAT(linkat(AT_FDCWD, oldfile.path().c_str(), file_fd.get(), "bar", 0), + SyscallFailsWithErrno(ENOTDIR)); +} + +TEST(LinkTest, AbsPathsNonDirFDsWithOpath) { + SKIP_IF(IsRunningWithVFS1()); + + auto oldfile = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); + const std::string newname = NewTempAbsPath(); + + // Create a file that will be passed as the directory fd for old/new names. + TempPath path = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); + FileDescriptor file_fd = ASSERT_NO_ERRNO_AND_VALUE(Open(path.path(), O_PATH)); + + // Using file_fd as the dirfds is OK as long as paths are absolute. + EXPECT_THAT(linkat(file_fd.get(), oldfile.path().c_str(), file_fd.get(), + newname.c_str(), 0), + SyscallSucceeds()); +} + TEST(LinkTest, LinkDoesNotFollowSymlinks) { // Create oldfile, and oldsymlink which points to it. auto oldfile = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); |