diff options
author | Pedro Alves <pedro@palves.net> | 2021-06-15 10:40:37 +0100 |
---|---|---|
committer | Pedro Alves <pedro@palves.net> | 2021-06-15 12:00:11 +0100 |
commit | c73fc9439a0de4978500f1fd948e0dc35ba6610e (patch) | |
tree | c83253e89a8b56d5a2ee572453202993120f63da | |
parent | 5e9f71e1cd39d0c71f23442c1d977633451a9f42 (diff) | |
download | gdb-c73fc9439a0de4978500f1fd948e0dc35ba6610e.zip gdb-c73fc9439a0de4978500f1fd948e0dc35ba6610e.tar.gz gdb-c73fc9439a0de4978500f1fd948e0dc35ba6610e.tar.bz2 |
Add a unit test for scoped_ignore_sigpipeusers/palves/scoped_ignore_signal
gdb/ChangeLog:
yyyy-mm-dd Pedro Alves <pedro@palves.net>
* Makefile.in (SELFTESTS_SRCS): Add
unittests/scoped_ignore_signal-selftests.c.
* unittests/scoped_ignore_signal-selftests.c: New.
Change-Id: Idce24aa9432a3f1eb7065bc9aa030b1d0d7dcad5
-rw-r--r-- | gdb/Makefile.in | 1 | ||||
-rw-r--r-- | gdb/unittests/scoped_ignore_signal-selftests.c | 125 |
2 files changed, 126 insertions, 0 deletions
diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 881ebde..1bc9788 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -461,6 +461,7 @@ SELFTESTS_SRCS = \ unittests/mkdir-recursive-selftests.c \ unittests/rsp-low-selftests.c \ unittests/scoped_fd-selftests.c \ + unittests/scoped_ignore_signal-selftests.c \ unittests/scoped_mmap-selftests.c \ unittests/scoped_restore-selftests.c \ unittests/search-memory-selftests.c \ diff --git a/gdb/unittests/scoped_ignore_signal-selftests.c b/gdb/unittests/scoped_ignore_signal-selftests.c new file mode 100644 index 0000000..f727b46 --- /dev/null +++ b/gdb/unittests/scoped_ignore_signal-selftests.c @@ -0,0 +1,125 @@ +/* Self tests for scoped_ignored_signal for GDB, the GNU debugger. + + Copyright (C) 2021 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "defs.h" +#include "gdbsupport/scoped_ignore_signal.h" +#include "gdbsupport/selftest.h" +#include "gdbsupport/scope-exit.h" +#include <unistd.h> +#include <signal.h> + +namespace selftests { +namespace scoped_ignore_sig { + +#ifdef SIGPIPE + +/* True if the SIGPIPE handler ran. */ +static sig_atomic_t got_sigpipe = 0; + +/* SIGPIPE handler for testing. */ + +static void +handle_sigpipe (int) +{ + got_sigpipe = 1; +} + +/* Test scoped_ignore_sigpipe. */ + +static void +test_sigpipe () +{ + auto *osig = signal (SIGPIPE, handle_sigpipe); + SCOPE_EXIT { signal (SIGPIPE, osig); }; + +#ifdef HAVE_SIGPROCMASK + /* Make sure SIGPIPE isn't blocked. */ + sigset_t set, old_state; + sigemptyset (&set); + sigaddset (&set, SIGPIPE); + sigprocmask (SIG_UNBLOCK, &set, &old_state); + SCOPE_EXIT { sigprocmask (SIG_SETMASK, &old_state, nullptr); }; +#endif + + /* Create pipe, and close read end so that writes to the pipe fail + with EPIPE. */ + + int fd[2]; + char c = 0xff; + int r; + + r = pipe (fd); + SELF_CHECK (r == 0); + + close (fd[0]); SCOPE_EXIT { close (fd[1]); }; + + /* Check that writing to the pipe results in EPIPE. EXPECT_SIG + indicates whether a SIGPIPE signal is expected. */ + auto check_pipe_write = [&] (bool expect_sig) + { + got_sigpipe = 0; + errno = 0; + + r = write (fd[1], &c, 1); + SELF_CHECK (r == -1 && errno == EPIPE + && got_sigpipe == expect_sig); + }; + + /* Check that without a scoped_ignore_sigpipe in scope we indeed get + a SIGPIPE signal. */ + check_pipe_write (true); + + /* Now check that with a scoped_ignore_sigpipe in scope, SIGPIPE is + ignored/blocked. */ + { + scoped_ignore_sigpipe ignore1; + + check_pipe_write (false); + + /* Check that scoped_ignore_sigpipe nests correctly. */ + { + scoped_ignore_sigpipe ignore2; + + check_pipe_write (false); + } + + /* If nesting works correctly, this write results in no + SIGPIPE. */ + check_pipe_write (false); + } + + /* No scoped_ignore_sigpipe is is scope anymore, so this should + result in a SIGPIPE signal. */ + check_pipe_write (true); +} + +#endif /* SIGPIPE */ + +} /* namespace scoped_ignore_sig */ +} /* namespace selftests */ + +void _initialize_scoped_ignore_signal_selftests (); +void +_initialize_scoped_ignore_signal_selftests () +{ +#ifdef SIGPIPE + selftests::register_test ("scoped_ignore_sigpipe", + selftests::scoped_ignore_sig::test_sigpipe); +#endif +} |