mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Refactor out NewEventFD to a test utility.
PiperOrigin-RevId: 231404512 Change-Id: I31efcc23a0c4a48ef6fbba3ca07415d79290f55c
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/eventfd.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,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,
|
||||
|
||||
@@ -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_
|
||||
Reference in New Issue
Block a user