-
Notifications
You must be signed in to change notification settings - Fork 119
/
rtsigs_waiter.c
109 lines (100 loc) · 3.2 KB
/
rtsigs_waiter.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*
* ch12/rtsigs_waiter.c
* ***************************************************************
* This program is part of the source code released for the book
* "Hands-on System Programming with Linux"
* (c) Author: Kaiwan N Billimoria
* Publisher: Packt
*
* From: Ch 12 : Signaling Part II
****************************************************************
* Brief Description:
* Aim: to test how realtime signals are delivered after being unblocked.
* We have a process trap 3 RT signals of varying priorities; we then
* arrange for the RT sigs to be *blocked* when the handler runs (by calling
* sigfillset before the sigaction).
*
* Useful to use the shell script 'bombard_sigrt.sh' to literally bombard
* the process with multiple realtime signals repeatedly.
*
* We find that the first RT sig sent is delivered immediately and processed;
* as we deliberately have the handler running for a while, the remaining
* RT sigs that have been sent are not lost, rather, they are *queued* for
* delivery. Once the previous handler is done, the next RT sig in the Q is
* delivered and processed. A key point: the delivery of RT signals from the
* queue is in *priority order* - first the lower-numbered RT sigs to higher-
* numbered RT sigs.
*
* For details, please refer the book, Ch 12.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <sys/file.h>
#include "../common.h"
#define MAX 10
static volatile sig_atomic_t s=0, t=0;
/*
* stack(): return the current value of the stack pointer register.
* The trick/hack: on x86 CPU's, the ABI tells us that the return
* value is always in the accumulator (EAX/RAX); so we just initialize
* it to the stack pointer (using inline assembly)!
*/
void *stack(void)
{
if (__WORDSIZE == 32) {
__asm__("movl %esp, %eax");
} else if (__WORDSIZE == 64) {
__asm__("movq %rsp, %rax");
}
/* Accumulator holds the return value */
}
/*
* Strictly speaking, should not use fprintf here as it's not
* async-signal safe; indeed, it sometimes does not work well!
*/
#undef SHOW_MASKED
/*#define SHOW_MASKED*/
static void rt_sighdlr(int signum)
{
#ifdef SHOW_MASKED
if (show_blocked_signals() < 0)
WARN("sigprocmask -query- failed\n");
#endif
fprintf(stderr, "\nsighdlr: signal %d,", signum);
if ((signum == SIGRTMAX-5) ||
(signum == SIGRTMIN+5) ||
(signum == SIGRTMAX)) {
s ++; t ++;
if (s >= MAX)
s = 1;
fprintf(stderr, " s=%d ; total=%d; stack %p :", s, t, stack());
//DELAY_LOOP('o', 8);
DELAY_LOOP_SILENT(8);
fprintf(stderr, "*");
}
}
int main(void)
{
struct sigaction act;
printf("Trapping the three realtime signals\n");
memset(&act, 0, sizeof(act));
act.sa_handler = rt_sighdlr;
act.sa_flags = SA_RESTART;
/* Set sigmask to all 1's, thus masking all signals
while this handler runs */
sigfillset(&act.sa_mask);
if (sigaction(SIGRTMAX-5, &act, 0) == -1)
FATAL("sigaction %s failed\n", "SIGRTMAX-5");
if (sigaction(SIGRTMIN+5, &act, 0) == -1)
FATAL("sigaction %s failed\n", "SIGRTMIN+5");
if (sigaction(SIGRTMAX, &act, 0) == -1)
FATAL("sigaction %s failed\n", "SIGRTMAX");
printf("Process awaiting signals ...\n");
while (1)
(void)pause();
exit(EXIT_SUCCESS);
}
/* vi: ts=8 */