sigrepeat.c revision 1.12 1 1.1 christos /* This testcase is part of GDB, the GNU debugger.
2 1.1 christos
3 1.11 christos Copyright 2004-2024 Free Software Foundation, Inc.
4 1.1 christos
5 1.1 christos This program is free software; you can redistribute it and/or modify
6 1.1 christos it under the terms of the GNU General Public License as published by
7 1.1 christos the Free Software Foundation; either version 3 of the License, or
8 1.1 christos (at your option) any later version.
9 1.1 christos
10 1.1 christos This program is distributed in the hope that it will be useful,
11 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
12 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 1.1 christos GNU General Public License for more details.
14 1.1 christos
15 1.1 christos You should have received a copy of the GNU General Public License
16 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>.
17 1.1 christos
18 1.1 christos */
19 1.1 christos
20 1.1 christos #include <stdio.h>
21 1.1 christos #include <stdlib.h>
22 1.1 christos #include <string.h>
23 1.1 christos #include <signal.h>
24 1.1 christos #include <sys/time.h>
25 1.1 christos
26 1.1 christos static volatile int done[2];
27 1.1 christos static volatile int repeats[2];
28 1.1 christos static int itimer[2] = { ITIMER_REAL, ITIMER_VIRTUAL };
29 1.1 christos static int alarm[2] = { SIGALRM, SIGVTALRM };
30 1.1 christos
31 1.1 christos static void
32 1.1 christos handler (int sig)
33 1.1 christos {
34 1.1 christos int sigi;
35 1.1 christos switch (sig)
36 1.1 christos {
37 1.1 christos case SIGALRM: sigi = 0; break;
38 1.1 christos case SIGVTALRM: sigi = 1; break;
39 1.1 christos default: abort ();
40 1.1 christos }
41 1.1 christos if (repeats[sigi]++ > 3)
42 1.1 christos {
43 1.1 christos /* Hit with enough signals, cancel everything and get out. */
44 1.1 christos {
45 1.1 christos struct itimerval itime;
46 1.1 christos memset (&itime, 0, sizeof (itime));
47 1.1 christos setitimer (itimer[sigi], &itime, NULL);
48 1.1 christos }
49 1.1 christos {
50 1.1 christos struct sigaction action;
51 1.1 christos memset (&action, 0, sizeof (action));
52 1.1 christos action.sa_handler = SIG_IGN;
53 1.1 christos sigaction (sig, &action, NULL);
54 1.1 christos }
55 1.1 christos done[sigi] = 1;
56 1.1 christos return;
57 1.1 christos }
58 1.1 christos /* Set up a nested virtual timer. */
59 1.1 christos while (1)
60 1.1 christos {
61 1.1 christos /* Wait until a signal has become pending, that way when this
62 1.12 christos handler returns it will be immediately delivered leading to
63 1.1 christos back-to-back signals. */
64 1.1 christos sigset_t set;
65 1.1 christos sigemptyset (&set);
66 1.1 christos if (sigpending (&set) < 0)
67 1.1 christos {
68 1.1 christos perror ("sigrepeat");
69 1.1 christos abort ();
70 1.1 christos }
71 1.1 christos if (sigismember (&set, sig))
72 1.1 christos break;
73 1.1 christos }
74 1.1 christos } /* handler */
75 1.1 christos
76 1.1 christos int
77 1.1 christos main ()
78 1.1 christos {
79 1.1 christos int i;
80 1.1 christos /* Set up the signal handler. */
81 1.1 christos for (i = 0; i < 2; i++)
82 1.1 christos {
83 1.1 christos struct sigaction action;
84 1.1 christos memset (&action, 0, sizeof (action));
85 1.1 christos action.sa_handler = handler;
86 1.1 christos sigaction (alarm[i], &action, NULL);
87 1.1 christos }
88 1.1 christos
89 1.1 christos /* Set up a rapidly repeating timers. A timer, rather than SIGSEGV,
90 1.1 christos is used as after a timer handler returns the interrupted code can
91 1.1 christos safely resume. The intent is for the program to swamp GDB with a
92 1.1 christos backlog of pending signals. */
93 1.1 christos for (i = 0; i < 2; i++)
94 1.1 christos {
95 1.1 christos struct itimerval itime;
96 1.1 christos memset (&itime, 0, sizeof (itime));
97 1.1 christos itime.it_interval.tv_usec = 1;
98 1.1 christos itime.it_value.tv_usec = 250 * 1000;
99 1.1 christos setitimer (itimer[i], &itime, NULL);
100 1.1 christos }
101 1.1 christos
102 1.1 christos /* Wait. */
103 1.1 christos while (!done[0] && !done[1]); /* infinite loop */
104 1.1 christos return 0;
105 1.1 christos }
106