diff options
author | Andrei Vagin <avagin@gmail.com> | 2021-07-24 17:09:33 -0700 |
---|---|---|
committer | Howard Zhang <howard.zhang@arm.com> | 2021-07-27 13:16:02 +0800 |
commit | 68cf8cc9a244041f859dc484abe551b8e018ad05 (patch) | |
tree | e9569356c85c073668ffe0c8335c75ea34d9b711 /test/syscalls | |
parent | c8d252466fbe9709f51766cd9862fd9958b00798 (diff) |
Don't create an extra fd bitmap to allocate a new fd.
Diffstat (limited to 'test/syscalls')
-rw-r--r-- | test/syscalls/linux/BUILD | 1 | ||||
-rw-r--r-- | test/syscalls/linux/dup.cc | 38 |
2 files changed, 39 insertions, 0 deletions
diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD index 2bf685524..1bbcd8abb 100644 --- a/test/syscalls/linux/BUILD +++ b/test/syscalls/linux/BUILD @@ -583,6 +583,7 @@ cc_binary( deps = [ "//test/util:eventfd_util", "//test/util:file_descriptor", + "@com_google_absl//absl/memory", gtest, "//test/util:fs_util", "//test/util:posix_error", 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 <fcntl.h> +#include <sys/resource.h> #include <unistd.h> #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<std::unique_ptr<FileDescriptor>> fds; + int prev = fd.get(); + for (int i = 0; i < kFDLimit; i++) { + int d = dup(fd.get()); + if (d == -1) { + break; + } + std::unique_ptr<FileDescriptor> f = absl::make_unique<FileDescriptor>(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)); |