diff options
Diffstat (limited to 'test/syscalls/linux/select.cc')
-rw-r--r-- | test/syscalls/linux/select.cc | 168 |
1 files changed, 0 insertions, 168 deletions
diff --git a/test/syscalls/linux/select.cc b/test/syscalls/linux/select.cc deleted file mode 100644 index 88c010aec..000000000 --- a/test/syscalls/linux/select.cc +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright 2018 The gVisor Authors. -// -// 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. - -#include <fcntl.h> -#include <sys/resource.h> -#include <sys/select.h> -#include <sys/time.h> -#include <climits> -#include <csignal> -#include <cstdio> - -#include "gtest/gtest.h" -#include "gtest/gtest.h" -#include "absl/time/time.h" -#include "test/syscalls/linux/base_poll_test.h" -#include "test/util/file_descriptor.h" -#include "test/util/multiprocess_util.h" -#include "test/util/posix_error.h" -#include "test/util/rlimit_util.h" -#include "test/util/temp_path.h" -#include "test/util/test_util.h" - -namespace gvisor { -namespace testing { -namespace { - -class SelectTest : public BasePollTest { - protected: - void SetUp() override { BasePollTest::SetUp(); } - void TearDown() override { BasePollTest::TearDown(); } -}; - -// See that when there are no FD sets, select behaves like sleep. -TEST_F(SelectTest, NullFds) { - struct timeval timeout = absl::ToTimeval(absl::Milliseconds(10)); - ASSERT_THAT(select(0, nullptr, nullptr, nullptr, &timeout), - SyscallSucceeds()); - EXPECT_EQ(timeout.tv_sec, 0); - EXPECT_EQ(timeout.tv_usec, 0); - - timeout = absl::ToTimeval(absl::Milliseconds(10)); - ASSERT_THAT(select(1, nullptr, nullptr, nullptr, &timeout), - SyscallSucceeds()); - EXPECT_EQ(timeout.tv_sec, 0); - EXPECT_EQ(timeout.tv_usec, 0); -} - -TEST_F(SelectTest, NegativeNfds) { - EXPECT_THAT(select(-1, nullptr, nullptr, nullptr, nullptr), - SyscallFailsWithErrno(EINVAL)); - EXPECT_THAT(select(-100000, nullptr, nullptr, nullptr, nullptr), - SyscallFailsWithErrno(EINVAL)); - EXPECT_THAT(select(INT_MIN, nullptr, nullptr, nullptr, nullptr), - SyscallFailsWithErrno(EINVAL)); -} - -TEST_F(SelectTest, ClosedFds) { - auto temp_file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); - FileDescriptor fd = - ASSERT_NO_ERRNO_AND_VALUE(Open(temp_file.path(), O_RDONLY)); - - // We can't rely on a file descriptor being closed in a multi threaded - // application so fork to get a clean process. - EXPECT_THAT(InForkedProcess([&] { - int fd_num = fd.get(); - fd.reset(); - - fd_set read_set; - FD_ZERO(&read_set); - FD_SET(fd_num, &read_set); - - struct timeval timeout = - absl::ToTimeval(absl::Milliseconds(10)); - TEST_PCHECK(select(fd_num + 1, &read_set, nullptr, nullptr, - &timeout) != 0); - TEST_PCHECK(errno == EBADF); - }), - IsPosixErrorOkAndHolds(0)); -} - -TEST_F(SelectTest, ZeroTimeout) { - struct timeval timeout = {}; - EXPECT_THAT(select(1, nullptr, nullptr, nullptr, &timeout), - SyscallSucceeds()); - // Ignore timeout as its value is now undefined. -} - -// If random S/R interrupts the select, SIGALRM may be delivered before select -// restarts, causing the select to hang forever. -TEST_F(SelectTest, NoTimeout_NoRandomSave) { - // When there's no timeout, select may never return so set a timer. - SetTimer(absl::Milliseconds(100)); - // See that we get interrupted by the timer. - ASSERT_THAT(select(1, nullptr, nullptr, nullptr, nullptr), - SyscallFailsWithErrno(EINTR)); - EXPECT_TRUE(TimerFired()); -} - -TEST_F(SelectTest, InvalidTimeoutNegative) { - struct timeval timeout = absl::ToTimeval(absl::Microseconds(-1)); - EXPECT_THAT(select(1, nullptr, nullptr, nullptr, &timeout), - SyscallFailsWithErrno(EINVAL)); - // Ignore timeout as its value is now undefined. -} - -// Verify that a signal interrupts select. -// -// If random S/R interrupts the select, SIGALRM may be delivered before select -// restarts, causing the select to hang forever. -TEST_F(SelectTest, InterruptedBySignal_NoRandomSave) { - absl::Duration duration(absl::Seconds(5)); - struct timeval timeout = absl::ToTimeval(duration); - SetTimer(absl::Milliseconds(100)); - ASSERT_FALSE(TimerFired()); - ASSERT_THAT(select(1, nullptr, nullptr, nullptr, &timeout), - SyscallFailsWithErrno(EINTR)); - EXPECT_TRUE(TimerFired()); - // Ignore timeout as its value is now undefined. -} - -TEST_F(SelectTest, IgnoreBitsAboveNfds) { - // fd_set is a bit array with at least FD_SETSIZE bits. Test that bits - // corresponding to file descriptors above nfds are ignored. - fd_set read_set; - FD_ZERO(&read_set); - constexpr int kNfds = 1; - for (int fd = kNfds; fd < FD_SETSIZE; fd++) { - FD_SET(fd, &read_set); - } - // Pass a zero timeout so that select returns immediately. - struct timeval timeout = {}; - EXPECT_THAT(select(kNfds, &read_set, nullptr, nullptr, &timeout), - SyscallSucceedsWithValue(0)); -} - -// This test illustrates Linux's behavior of 'select' calls passing after -// setrlimit RLIMIT_NOFILE is called. In particular, versions of sshd rely on -// this behavior. -TEST_F(SelectTest, SetrlimitCallNOFILE) { - fd_set read_set; - FD_ZERO(&read_set); - timeval timeout = {}; - const FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE( - Open(NewTempAbsPath(), O_RDONLY | O_CREAT, S_IRUSR)); - - Cleanup reset_rlimit = - ASSERT_NO_ERRNO_AND_VALUE(ScopedSetSoftRlimit(RLIMIT_NOFILE, 0)); - - FD_SET(fd.get(), &read_set); - // this call with zero timeout should return immediately - EXPECT_THAT(select(fd.get() + 1, &read_set, nullptr, nullptr, &timeout), - SyscallSucceeds()); -} - -} // namespace -} // namespace testing -} // namespace gvisor |