diff options
Diffstat (limited to 'test/syscalls/linux/inotify.cc')
-rw-r--r-- | test/syscalls/linux/inotify.cc | 56 |
1 files changed, 42 insertions, 14 deletions
diff --git a/test/syscalls/linux/inotify.cc b/test/syscalls/linux/inotify.cc index 7384c27dc..182d676d5 100644 --- a/test/syscalls/linux/inotify.cc +++ b/test/syscalls/linux/inotify.cc @@ -48,26 +48,26 @@ constexpr int kBufSize = 1024; // C++-friendly version of struct inotify_event. struct Event { - int32_t wd; - uint32_t mask; - uint32_t cookie; - uint32_t len; + int32 wd; + uint32 mask; + uint32 cookie; + uint32 len; std::string name; - Event(uint32_t mask, int32_t wd, absl::string_view name, uint32_t cookie) + Event(uint32 mask, int32 wd, absl::string_view name, uint32 cookie) : wd(wd), mask(mask), cookie(cookie), len(name.size()), name(std::string(name)) {} - Event(uint32_t mask, int32_t wd, absl::string_view name) + Event(uint32 mask, int32 wd, absl::string_view name) : Event(mask, wd, name, 0) {} - Event(uint32_t mask, int32_t wd) : Event(mask, wd, "", 0) {} + Event(uint32 mask, int32 wd) : Event(mask, wd, "", 0) {} Event() : Event(0, 0, "", 0) {} }; // Prints the symbolic name for a struct inotify_event's 'mask' field. -std::string FlagString(uint32_t flags) { +std::string FlagString(uint32 flags) { std::vector<std::string> names; #define EMIT(target) \ @@ -320,7 +320,7 @@ PosixErrorOr<FileDescriptor> InotifyInit1(int flags) { } PosixErrorOr<int> InotifyAddWatch(int fd, const std::string& path, - uint32_t mask) { + uint32 mask) { int wd; EXPECT_THAT(wd = inotify_add_watch(fd, path.c_str(), mask), SyscallSucceeds()); @@ -647,7 +647,7 @@ TEST(Inotify, MoveGeneratesEvents) { Event(IN_MOVED_TO, root_wd, Basename(newpath), events[1].cookie)})); EXPECT_NE(events[0].cookie, 0); EXPECT_EQ(events[0].cookie, events[1].cookie); - uint32_t last_cookie = events[0].cookie; + uint32 last_cookie = events[0].cookie; // Test move from root -> root/dir1. newpath = NewTempAbsPathInDir(dir1.path()); @@ -841,7 +841,7 @@ TEST(Inotify, ConcurrentThreadsGeneratingEvents) { } auto test_thread = [&files]() { - uint32_t seed = time(nullptr); + uint32 seed = time(nullptr); for (int i = 0; i < 20; i++) { const TempPath& file = files[rand_r(&seed) % files.size()]; const FileDescriptor file_fd = @@ -960,7 +960,7 @@ TEST(Inotify, BlockingReadOnInotifyFd) { t.Join(); // Make sure the event we got back is sane. - uint32_t event_mask; + uint32 event_mask; memcpy(&event_mask, buf.data() + offsetof(struct inotify_event, mask), sizeof(event_mask)); EXPECT_EQ(event_mask, IN_ACCESS); @@ -977,7 +977,7 @@ TEST(Inotify, WatchOnRelativePath) { ASSERT_NO_ERRNO_AND_VALUE(Open(file1.path(), O_RDONLY)); // Change working directory to root. - const char* old_working_dir = get_current_dir_name(); + const FileDescriptor cwd = ASSERT_NO_ERRNO_AND_VALUE(Open(".", O_PATH)); EXPECT_THAT(chdir(root.path().c_str()), SyscallSucceeds()); // Add a watch on file1 with a relative path. @@ -997,7 +997,7 @@ TEST(Inotify, WatchOnRelativePath) { // continue to hold a reference, random save/restore tests can fail if a save // is triggered after "root" is unlinked; we can't save deleted fs objects // with active references. - EXPECT_THAT(chdir(old_working_dir), SyscallSucceeds()); + EXPECT_THAT(fchdir(cwd.get()), SyscallSucceeds()); } TEST(Inotify, ZeroLengthReadWriteDoesNotGenerateEvent) { @@ -1591,6 +1591,34 @@ TEST(Inotify, EpollNoDeadlock) { } } +TEST(Inotify, SpliceEvent) { + int pipes[2]; + ASSERT_THAT(pipe2(pipes, O_NONBLOCK), SyscallSucceeds()); + + const TempPath root = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir()); + const FileDescriptor fd = + ASSERT_NO_ERRNO_AND_VALUE(InotifyInit1(IN_NONBLOCK)); + const TempPath file1 = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFileWith( + root.path(), "some content", TempPath::kDefaultFileMode)); + + const FileDescriptor file1_fd = + ASSERT_NO_ERRNO_AND_VALUE(Open(file1.path(), O_RDONLY)); + const int watcher = ASSERT_NO_ERRNO_AND_VALUE( + InotifyAddWatch(fd.get(), file1.path(), IN_ALL_EVENTS)); + + char buf; + EXPECT_THAT(read(file1_fd.get(), &buf, 1), SyscallSucceeds()); + + EXPECT_THAT(splice(fd.get(), nullptr, pipes[1], nullptr, + sizeof(struct inotify_event) + 1, SPLICE_F_NONBLOCK), + SyscallSucceedsWithValue(sizeof(struct inotify_event))); + + const FileDescriptor read_fd(pipes[0]); + const std::vector<Event> events = + ASSERT_NO_ERRNO_AND_VALUE(DrainEvents(read_fd.get())); + ASSERT_THAT(events, Are({Event(IN_ACCESS, watcher)})); +} + } // namespace } // namespace testing } // namespace gvisor |