From 68cf8cc9a244041f859dc484abe551b8e018ad05 Mon Sep 17 00:00:00 2001 From: Andrei Vagin Date: Sat, 24 Jul 2021 17:09:33 -0700 Subject: Don't create an extra fd bitmap to allocate a new fd. --- test/syscalls/linux/dup.cc | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'test/syscalls/linux/dup.cc') diff --git a/test/syscalls/linux/dup.cc b/test/syscalls/linux/dup.cc index ba4e13fb9..fca0880a6 100644 --- a/test/syscalls/linux/dup.cc +++ b/test/syscalls/linux/dup.cc @@ -13,9 +13,11 @@ // limitations under the License. #include +#include #include #include "gtest/gtest.h" +#include "absl/memory/memory.h" #include "test/util/eventfd_util.h" #include "test/util/file_descriptor.h" #include "test/util/fs_util.h" @@ -98,6 +100,42 @@ TEST(DupTest, Dup2) { ASSERT_NO_ERRNO(CheckSameFile(fd, nfd2)); } +TEST(DupTest, Rlimit) { + constexpr int kFDLimit = 101; + auto f = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); + FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(f.path(), O_RDONLY)); + + struct rlimit rl = {}; + EXPECT_THAT(getrlimit(RLIMIT_NOFILE, &rl), SyscallSucceeds()); + + // Lower the rlimit first, as it may be equal to /proc/sys/fs/nr_open, in + // which case even users with CAP_SYS_RESOURCE can't raise it. + rl.rlim_cur = kFDLimit * 2; + ASSERT_THAT(setrlimit(RLIMIT_NOFILE, &rl), SyscallSucceeds()); + + FileDescriptor aboveLimitFD = + ASSERT_NO_ERRNO_AND_VALUE(Dup2(fd, kFDLimit * 2 - 1)); + + rl.rlim_cur = kFDLimit; + ASSERT_THAT(setrlimit(RLIMIT_NOFILE, &rl), SyscallSucceeds()); + ASSERT_THAT(dup3(fd.get(), kFDLimit, 0), SyscallFails()); + + std::vector> fds; + int prev = fd.get(); + for (int i = 0; i < kFDLimit; i++) { + int d = dup(fd.get()); + if (d == -1) { + break; + } + std::unique_ptr f = absl::make_unique(d); + EXPECT_LT(d, kFDLimit); + EXPECT_GT(d, prev); + prev = d; + fds.push_back(std::move(f)); + } + EXPECT_EQ(fds.size(), kFDLimit - fd.get() - 1); +} + TEST(DupTest, Dup2SameFD) { auto f = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(f.path(), O_RDONLY)); -- cgit v1.2.3