diff options
-rw-r--r-- | test/syscalls/linux/BUILD | 6 | ||||
-rw-r--r-- | test/syscalls/linux/chmod.cc | 1 | ||||
-rw-r--r-- | test/syscalls/linux/dup.cc | 18 | ||||
-rw-r--r-- | test/syscalls/linux/epoll.cc | 11 | ||||
-rw-r--r-- | test/syscalls/linux/eventfd.cc | 92 | ||||
-rw-r--r-- | test/syscalls/linux/fallocate.cc | 1 | ||||
-rw-r--r-- | test/syscalls/linux/fcntl.cc | 16 | ||||
-rw-r--r-- | test/syscalls/linux/getdents.cc | 22 | ||||
-rw-r--r-- | test/util/BUILD | 11 | ||||
-rw-r--r-- | test/util/eventfd_util.h | 43 |
10 files changed, 119 insertions, 102 deletions
diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD index 19884d55e..8cf83b311 100644 --- a/test/syscalls/linux/BUILD +++ b/test/syscalls/linux/BUILD @@ -481,6 +481,7 @@ cc_binary( srcs = ["dup.cc"], linkstatic = 1, deps = [ + "//test/util:eventfd_util", "//test/util:file_descriptor", "//test/util:posix_error", "//test/util:temp_path", @@ -497,6 +498,7 @@ cc_binary( linkstatic = 1, deps = [ "//test/util:epoll_util", + "//test/util:eventfd_util", "//test/util:file_descriptor", "//test/util:posix_error", "//test/util:test_main", @@ -511,6 +513,8 @@ cc_binary( srcs = ["eventfd.cc"], linkstatic = 1, deps = [ + "//test/util:epoll_util", + "//test/util:eventfd_util", "//test/util:test_main", "//test/util:test_util", "//test/util:thread_util", @@ -686,6 +690,7 @@ cc_binary( deps = [ ":socket_test_util", "//test/util:cleanup", + "//test/util:eventfd_util", "//test/util:multiprocess_util", "//test/util:posix_error", "//test/util:temp_path", @@ -817,6 +822,7 @@ cc_binary( srcs = ["getdents.cc"], linkstatic = 1, deps = [ + "//test/util:eventfd_util", "//test/util:file_descriptor", "//test/util:fs_util", "//test/util:posix_error", diff --git a/test/syscalls/linux/chmod.cc b/test/syscalls/linux/chmod.cc index b7fc17946..2f2ff3b7d 100644 --- a/test/syscalls/linux/chmod.cc +++ b/test/syscalls/linux/chmod.cc @@ -13,7 +13,6 @@ // limitations under the License. #include <fcntl.h> -#include <sys/eventfd.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> diff --git a/test/syscalls/linux/dup.cc b/test/syscalls/linux/dup.cc index fc11844fb..e8de2f4c4 100644 --- a/test/syscalls/linux/dup.cc +++ b/test/syscalls/linux/dup.cc @@ -13,10 +13,10 @@ // limitations under the License. #include <fcntl.h> -#include <sys/eventfd.h> #include <unistd.h> #include "gtest/gtest.h" +#include "test/util/eventfd_util.h" #include "test/util/file_descriptor.h" #include "test/util/posix_error.h" #include "test/util/temp_path.h" @@ -63,20 +63,14 @@ TEST(DupTest, Dup) { } TEST(DupTest, DupClearsCloExec) { - FileDescriptor nfd; - // Open an eventfd file descriptor with FD_CLOEXEC descriptor flag set. - int event_fd = 0; - ASSERT_THAT(event_fd = eventfd(0, EFD_CLOEXEC), SyscallSucceeds()); - FileDescriptor event_fd_closer(event_fd); - - EXPECT_THAT(fcntl(event_fd_closer.get(), F_GETFD), - SyscallSucceedsWithValue(FD_CLOEXEC)); + FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, EFD_CLOEXEC)); + EXPECT_THAT(fcntl(fd.get(), F_GETFD), SyscallSucceedsWithValue(FD_CLOEXEC)); // Duplicate the descriptor. Ensure that it doesn't have FD_CLOEXEC set. - nfd = ASSERT_NO_ERRNO_AND_VALUE(event_fd_closer.Dup()); - ASSERT_NE(event_fd_closer.get(), nfd.get()); - CheckSameFile(event_fd_closer, nfd); + FileDescriptor nfd = ASSERT_NO_ERRNO_AND_VALUE(fd.Dup()); + ASSERT_NE(fd.get(), nfd.get()); + CheckSameFile(fd, nfd); EXPECT_THAT(fcntl(nfd.get(), F_GETFD), SyscallSucceedsWithValue(0)); } diff --git a/test/syscalls/linux/epoll.cc b/test/syscalls/linux/epoll.cc index 46fba7b2d..7b1d83ad8 100644 --- a/test/syscalls/linux/epoll.cc +++ b/test/syscalls/linux/epoll.cc @@ -26,6 +26,7 @@ #include "gtest/gtest.h" #include "test/util/epoll_util.h" +#include "test/util/eventfd_util.h" #include "test/util/file_descriptor.h" #include "test/util/posix_error.h" #include "test/util/test_util.h" @@ -38,16 +39,6 @@ namespace { constexpr int kFDsPerEpoll = 3; constexpr uint64_t kMagicConstant = 0x0102030405060708; -// Returns a new eventfd. -PosixErrorOr<FileDescriptor> NewEventFD() { - int fd = eventfd(/* initval = */ 0, /* flags = */ 0); - MaybeSave(); - if (fd < 0) { - return PosixError(errno, "eventfd"); - } - return FileDescriptor(fd); -} - uint64_t ms_elapsed(const struct timespec* begin, const struct timespec* end) { return (end->tv_sec - begin->tv_sec) * 1000 + (end->tv_nsec - begin->tv_nsec) / 1000000; diff --git a/test/syscalls/linux/eventfd.cc b/test/syscalls/linux/eventfd.cc index ffcd20622..8111da30e 100644 --- a/test/syscalls/linux/eventfd.cc +++ b/test/syscalls/linux/eventfd.cc @@ -18,12 +18,13 @@ #include <stdlib.h> #include <string.h> #include <sys/epoll.h> -#include <sys/eventfd.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #include "gtest/gtest.h" +#include "test/util/epoll_util.h" +#include "test/util/eventfd_util.h" #include "test/util/test_util.h" #include "test/util/thread_util.h" @@ -33,21 +34,20 @@ namespace testing { namespace { TEST(EventfdTest, Nonblock) { - int efd; - ASSERT_THAT(efd = eventfd(0, EFD_NONBLOCK | EFD_SEMAPHORE), - SyscallSucceeds()); + FileDescriptor efd = + ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, EFD_NONBLOCK | EFD_SEMAPHORE)); uint64_t l; - ASSERT_THAT(read(efd, &l, sizeof(l)), SyscallFailsWithErrno(EAGAIN)); + ASSERT_THAT(read(efd.get(), &l, sizeof(l)), SyscallFailsWithErrno(EAGAIN)); l = 1; - ASSERT_THAT(write(efd, &l, sizeof(l)), SyscallSucceeds()); + ASSERT_THAT(write(efd.get(), &l, sizeof(l)), SyscallSucceeds()); l = 0; - ASSERT_THAT(read(efd, &l, sizeof(l)), SyscallSucceeds()); + ASSERT_THAT(read(efd.get(), &l, sizeof(l)), SyscallSucceeds()); EXPECT_EQ(l, 1); - ASSERT_THAT(read(efd, &l, sizeof(l)), SyscallFailsWithErrno(EAGAIN)); + ASSERT_THAT(read(efd.get(), &l, sizeof(l)), SyscallFailsWithErrno(EAGAIN)); } void* read_three_times(void* arg) { @@ -60,8 +60,8 @@ void* read_three_times(void* arg) { } TEST(EventfdTest, BlockingWrite) { - int efd; - ASSERT_THAT(efd = eventfd(0, EFD_SEMAPHORE), SyscallSucceeds()); + FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, EFD_SEMAPHORE)); + int efd = fd.get(); pthread_t p; ASSERT_THAT(pthread_create(&p, nullptr, read_three_times, @@ -82,58 +82,53 @@ TEST(EventfdTest, BlockingWrite) { } TEST(EventfdTest, SmallWrite) { - int efd; - ASSERT_THAT(efd = eventfd(0, EFD_NONBLOCK | EFD_SEMAPHORE), - SyscallSucceeds()); + FileDescriptor efd = + ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, EFD_NONBLOCK | EFD_SEMAPHORE)); uint64_t l = 16; - ASSERT_THAT(write(efd, &l, 4), SyscallFailsWithErrno(EINVAL)); + ASSERT_THAT(write(efd.get(), &l, 4), SyscallFailsWithErrno(EINVAL)); } TEST(EventfdTest, SmallRead) { - int efd; - ASSERT_THAT(efd = eventfd(0, EFD_NONBLOCK | EFD_SEMAPHORE), - SyscallSucceeds()); + FileDescriptor efd = + ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, EFD_NONBLOCK | EFD_SEMAPHORE)); uint64_t l = 1; - ASSERT_THAT(write(efd, &l, sizeof(l)), SyscallSucceeds()); + ASSERT_THAT(write(efd.get(), &l, sizeof(l)), SyscallSucceeds()); l = 0; - ASSERT_THAT(read(efd, &l, 4), SyscallFailsWithErrno(EINVAL)); + ASSERT_THAT(read(efd.get(), &l, 4), SyscallFailsWithErrno(EINVAL)); } TEST(EventfdTest, BigWrite) { - int efd; - ASSERT_THAT(efd = eventfd(0, EFD_NONBLOCK | EFD_SEMAPHORE), - SyscallSucceeds()); + FileDescriptor efd = + ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, EFD_NONBLOCK | EFD_SEMAPHORE)); uint64_t big[16]; big[0] = 16; - ASSERT_THAT(write(efd, big, sizeof(big)), SyscallSucceeds()); + ASSERT_THAT(write(efd.get(), big, sizeof(big)), SyscallSucceeds()); } TEST(EventfdTest, BigRead) { - int efd; - ASSERT_THAT(efd = eventfd(0, EFD_NONBLOCK | EFD_SEMAPHORE), - SyscallSucceeds()); + FileDescriptor efd = + ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, EFD_NONBLOCK | EFD_SEMAPHORE)); uint64_t l = 1; - ASSERT_THAT(write(efd, &l, sizeof(l)), SyscallSucceeds()); + ASSERT_THAT(write(efd.get(), &l, sizeof(l)), SyscallSucceeds()); uint64_t big[16]; - ASSERT_THAT(read(efd, big, sizeof(big)), SyscallSucceeds()); + ASSERT_THAT(read(efd.get(), big, sizeof(big)), SyscallSucceeds()); EXPECT_EQ(big[0], 1); } TEST(EventfdTest, BigWriteBigRead) { - int efd; - ASSERT_THAT(efd = eventfd(0, EFD_NONBLOCK | EFD_SEMAPHORE), - SyscallSucceeds()); + FileDescriptor efd = + ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, EFD_NONBLOCK | EFD_SEMAPHORE)); uint64_t l[16]; l[0] = 16; - ASSERT_THAT(write(efd, l, sizeof(l)), SyscallSucceeds()); - ASSERT_THAT(read(efd, l, sizeof(l)), SyscallSucceeds()); + ASSERT_THAT(write(efd.get(), l, sizeof(l)), SyscallSucceeds()); + ASSERT_THAT(read(efd.get(), l, sizeof(l)), SyscallSucceeds()); EXPECT_EQ(l[0], 1); } @@ -142,44 +137,39 @@ TEST(EventfdTest, NotifyNonZero_NoRandomSave) { // Waits will time out at 10 seconds. constexpr int kEpollTimeoutMs = 10000; // Create an eventfd descriptor. - int efd; - ASSERT_THAT(efd = eventfd(7, EFD_SEMAPHORE | EFD_NONBLOCK), - SyscallSucceeds()); + FileDescriptor efd = + ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(7, EFD_NONBLOCK | EFD_SEMAPHORE)); // Create an epoll fd to listen to efd. - int epollfd; - ASSERT_THAT(epollfd = epoll_create1(0), SyscallSucceeds()); + FileDescriptor epollfd = ASSERT_NO_ERRNO_AND_VALUE(NewEpollFD()); // Add efd to epoll. - struct epoll_event add_ev; - add_ev.events = EPOLLIN | EPOLLET; - add_ev.data.fd = efd; - ASSERT_THAT(epoll_ctl(epollfd, EPOLL_CTL_ADD, efd, &add_ev), - SyscallSucceeds()); + ASSERT_NO_ERRNO( + RegisterEpollFD(epollfd.get(), efd.get(), EPOLLIN | EPOLLET, efd.get())); // Use epoll to get a value from efd. struct epoll_event out_ev; - int wait_out = epoll_wait(epollfd, &out_ev, 1, kEpollTimeoutMs); + int wait_out = epoll_wait(epollfd.get(), &out_ev, 1, kEpollTimeoutMs); EXPECT_EQ(wait_out, 1); - EXPECT_EQ(efd, out_ev.data.fd); + EXPECT_EQ(efd.get(), out_ev.data.fd); uint64_t val = 0; - ASSERT_THAT(read(efd, &val, sizeof(val)), SyscallSucceeds()); + ASSERT_THAT(read(efd.get(), &val, sizeof(val)), SyscallSucceeds()); EXPECT_EQ(val, 1); // Start a thread that, after this thread blocks on epoll_wait, will write to // efd. This is racy -- it's possible that this write will happen after // epoll_wait times out. - ScopedThread t([efd] { + ScopedThread t([&efd] { sleep(5); uint64_t val = 1; - write(efd, &val, sizeof(val)); + write(efd.get(), &val, sizeof(val)); }); // epoll_wait should return once the thread writes. - wait_out = epoll_wait(epollfd, &out_ev, 1, kEpollTimeoutMs); + wait_out = epoll_wait(epollfd.get(), &out_ev, 1, kEpollTimeoutMs); EXPECT_EQ(wait_out, 1); - EXPECT_EQ(efd, out_ev.data.fd); + EXPECT_EQ(efd.get(), out_ev.data.fd); val = 0; - ASSERT_THAT(read(efd, &val, sizeof(val)), SyscallSucceeds()); + ASSERT_THAT(read(efd.get(), &val, sizeof(val)), SyscallSucceeds()); EXPECT_EQ(val, 1); } diff --git a/test/syscalls/linux/fallocate.cc b/test/syscalls/linux/fallocate.cc index 53aedd4e4..e51538734 100644 --- a/test/syscalls/linux/fallocate.cc +++ b/test/syscalls/linux/fallocate.cc @@ -13,7 +13,6 @@ // limitations under the License. #include <fcntl.h> -#include <sys/eventfd.h> #include <unistd.h> #include "gtest/gtest.h" diff --git a/test/syscalls/linux/fcntl.cc b/test/syscalls/linux/fcntl.cc index 355334bfa..32a90a163 100644 --- a/test/syscalls/linux/fcntl.cc +++ b/test/syscalls/linux/fcntl.cc @@ -14,7 +14,6 @@ #include <fcntl.h> #include <signal.h> -#include <sys/eventfd.h> #include <syscall.h> #include <unistd.h> @@ -27,6 +26,7 @@ #include "absl/time/time.h" #include "test/syscalls/linux/socket_test_util.h" #include "test/util/cleanup.h" +#include "test/util/eventfd_util.h" #include "test/util/multiprocess_util.h" #include "test/util/posix_error.h" #include "test/util/temp_path.h" @@ -112,17 +112,9 @@ PosixErrorOr<Cleanup> SubprocessLock(std::string const& path, bool for_write, return std::move(cleanup); } -PosixErrorOr<FileDescriptor> Eventfd(int count, int flags) { - int efd = eventfd(count, flags); - if (efd < 0) { - return PosixError(errno, "Eventfd"); - } - return FileDescriptor(efd); -} - TEST(FcntlTest, SetCloExec) { // Open an eventfd file descriptor with FD_CLOEXEC descriptor flag not set. - FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Eventfd(0, 0)); + FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, 0)); ASSERT_THAT(fcntl(fd.get(), F_GETFD), SyscallSucceedsWithValue(0)); // Set the FD_CLOEXEC flag. @@ -132,7 +124,7 @@ TEST(FcntlTest, SetCloExec) { TEST(FcntlTest, ClearCloExec) { // Open an eventfd file descriptor with FD_CLOEXEC descriptor flag set. - FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Eventfd(0, EFD_CLOEXEC)); + FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, EFD_CLOEXEC)); ASSERT_THAT(fcntl(fd.get(), F_GETFD), SyscallSucceedsWithValue(FD_CLOEXEC)); // Clear the FD_CLOEXEC flag. @@ -142,7 +134,7 @@ TEST(FcntlTest, ClearCloExec) { TEST(FcntlTest, IndependentDescriptorFlags) { // Open an eventfd file descriptor with FD_CLOEXEC descriptor flag not set. - FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Eventfd(0, 0)); + FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, 0)); ASSERT_THAT(fcntl(fd.get(), F_GETFD), SyscallSucceedsWithValue(0)); // Duplicate the descriptor. Ensure that it also doesn't have FD_CLOEXEC. diff --git a/test/syscalls/linux/getdents.cc b/test/syscalls/linux/getdents.cc index 5db580aa0..526925599 100644 --- a/test/syscalls/linux/getdents.cc +++ b/test/syscalls/linux/getdents.cc @@ -19,13 +19,13 @@ #include <stdint.h> #include <stdio.h> #include <string.h> -#include <sys/eventfd.h> #include <sys/mman.h> #include <sys/types.h> #include <syscall.h> #include <unistd.h> #include <map> #include <string> +#include <unordered_map> #include <unordered_set> #include <utility> @@ -33,6 +33,7 @@ #include "gtest/gtest.h" #include "absl/strings/numbers.h" #include "absl/strings/str_cat.h" +#include "test/util/eventfd_util.h" #include "test/util/file_descriptor.h" #include "test/util/fs_util.h" #include "test/util/posix_error.h" @@ -368,16 +369,11 @@ TYPED_TEST(GetdentsTest, PartialBuffer) { // getdents iterates correctly despite mutation of /proc/self/fd. TYPED_TEST(GetdentsTest, ProcSelfFd) { constexpr size_t kNfds = 10; - std::unordered_set<int> fds; - std::vector<FileDescriptor> fd_closers; - fd_closers.reserve(fds.size()); - for (int fd : fds) { - fd_closers.emplace_back(fd); - } + std::unordered_map<int, FileDescriptor> fds; + fds.reserve(kNfds); for (size_t i = 0; i < kNfds; i++) { - int fd; - ASSERT_THAT(fd = eventfd(0, 0), SyscallSucceeds()); - fds.insert(fd); + FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(NewEventFD()); + fds.emplace(fd.get(), std::move(fd)); } const FileDescriptor proc_self_fd = @@ -401,11 +397,7 @@ TYPED_TEST(GetdentsTest, ProcSelfFd) { if (!absl::SimpleAtoi(d->d_name, &dfd)) continue; EXPECT_TRUE(prev_fds.insert(dfd).second) << "Repeated observation of /proc/self/fd/" << dfd; - auto it = fds.find(dfd); - if (it != fds.end()) { - fds.erase(it); - EXPECT_THAT(close(dfd), SyscallSucceeds()); - } + fds.erase(dfd); } } diff --git a/test/util/BUILD b/test/util/BUILD index 6316fec6e..f2e563507 100644 --- a/test/util/BUILD +++ b/test/util/BUILD @@ -19,6 +19,17 @@ cc_library( ) cc_library( + name = "eventfd_util", + testonly = 1, + hdrs = ["eventfd_util.h"], + deps = [ + ":file_descriptor", + ":posix_error", + ":save_util", + ], +) + +cc_library( name = "file_descriptor", testonly = 1, hdrs = ["file_descriptor.h"], diff --git a/test/util/eventfd_util.h b/test/util/eventfd_util.h new file mode 100644 index 000000000..1fdb07d3b --- /dev/null +++ b/test/util/eventfd_util.h @@ -0,0 +1,43 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef GVISOR_TEST_UTIL_EVENTFD_UTIL_H_ +#define GVISOR_TEST_UTIL_EVENTFD_UTIL_H_ + +#include <sys/eventfd.h> + +#include <cerrno> + +#include "test/util/file_descriptor.h" +#include "test/util/posix_error.h" +#include "test/util/save_util.h" + +namespace gvisor { +namespace testing { + +// Returns a new eventfd with the given initial value and flags. +inline PosixErrorOr<FileDescriptor> NewEventFD(unsigned int initval = 0, + int flags = 0) { + int fd = eventfd(initval, flags); + MaybeSave(); + if (fd < 0) { + return PosixError(errno, "eventfd"); + } + return FileDescriptor(fd); +} + +} // namespace testing +} // namespace gvisor + +#endif // GVISOR_TEST_UTIL_EVENTFD_UTIL_H_ |