summaryrefslogtreecommitdiffhomepage
path: root/test/syscalls/linux/inotify.cc
diff options
context:
space:
mode:
Diffstat (limited to 'test/syscalls/linux/inotify.cc')
-rw-r--r--test/syscalls/linux/inotify.cc56
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