diff options
author | Brian Geffon <bgeffon@google.com> | 2018-12-10 14:41:40 -0800 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-12-10 14:42:34 -0800 |
commit | d3bc79bc8438206ac6a14fde4eaa288fc07eee82 (patch) | |
tree | e820398591bfd1503456e877fa0c2bdd0f994959 /test/util/signal_util.cc | |
parent | 833edbd10b49db1f934dcb2495dcb41c1310eea4 (diff) |
Open source system call tests.
PiperOrigin-RevId: 224886231
Change-Id: I0fccb4d994601739d8b16b1d4e6b31f40297fb22
Diffstat (limited to 'test/util/signal_util.cc')
-rw-r--r-- | test/util/signal_util.cc | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/test/util/signal_util.cc b/test/util/signal_util.cc new file mode 100644 index 000000000..3e2df32a6 --- /dev/null +++ b/test/util/signal_util.cc @@ -0,0 +1,103 @@ +// Copyright 2018 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. + +#include "test/util/signal_util.h" + +#include <signal.h> +#include <ostream> + +#include "gtest/gtest.h" +#include "test/util/cleanup.h" +#include "test/util/posix_error.h" +#include "test/util/test_util.h" + +namespace { + +struct Range { + int start; + int end; +}; + +// Format a Range as "start-end" or "start" for single value Ranges. +static ::std::ostream& operator<<(::std::ostream& os, const Range& range) { + if (range.end > range.start) { + return os << range.start << '-' << range.end; + } + + return os << range.start; +} + +} // namespace + +// Format a sigset_t as a comma separated list of numeric ranges. +// Empty sigset: [] +// Full sigset: [1-31,34-64] +::std::ostream& operator<<(::std::ostream& os, const sigset_t& sigset) { + const char* delim = ""; + Range range = {0, 0}; + + os << '['; + + for (int sig = 1; sig <= gvisor::testing::kMaxSignal; ++sig) { + if (sigismember(&sigset, sig)) { + if (range.start) { + range.end = sig; + } else { + range.start = sig; + range.end = sig; + } + } else if (range.start) { + os << delim << range; + delim = ","; + range.start = 0; + range.end = 0; + } + } + + if (range.start) { + os << delim << range; + } + + return os << ']'; +} + +namespace gvisor { +namespace testing { + +PosixErrorOr<Cleanup> ScopedSigaction(int sig, struct sigaction const& sa) { + struct sigaction old_sa; + int rc = sigaction(sig, &sa, &old_sa); + MaybeSave(); + if (rc < 0) { + return PosixError(errno, "sigaction failed"); + } + return Cleanup([sig, old_sa] { + EXPECT_THAT(sigaction(sig, &old_sa, nullptr), SyscallSucceeds()); + }); +} + +PosixErrorOr<Cleanup> ScopedSignalMask(int how, sigset_t const& set) { + sigset_t old; + int rc = sigprocmask(how, &set, &old); + MaybeSave(); + if (rc < 0) { + return PosixError(errno, "sigprocmask failed"); + } + return Cleanup([old] { + EXPECT_THAT(sigprocmask(SIG_SETMASK, &old, nullptr), SyscallSucceeds()); + }); +} + +} // namespace testing +} // namespace gvisor |