forked from appneta/tcpreplay
-
Notifications
You must be signed in to change notification settings - Fork 0
/
signal_handler.c
132 lines (115 loc) · 3.24 KB
/
signal_handler.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/* $Id$ */
/*
* Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
* Copyright (c) 2013-2022 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
*
* The Tcpreplay Suite of tools 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 with the authors permission any later version.
*
* The Tcpreplay Suite 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 the Tcpreplay Suite. If not, see <http://www.gnu.org/licenses/>.
*/
#include "signal_handler.h"
#include "defines.h"
#include "config.h"
#include "common.h"
#include "tcpreplay_api.h"
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>
struct timeval suspend_time;
static struct timeval suspend_start;
static struct timeval suspend_end;
static void suspend_handler(int signo);
static void continue_handler(int signo);
static void abort_handler(int signo);
extern tcpreplay_t *ctx;
/***************************************************************
* This code is for pausing/restarting tcpreplay using SIGUSR1 *
* for abort code on SIGINT *
***************************************************************/
/**
* \brief init_signal_handlers
*
* Initialize signal handlers to be used in tcpreplay.
*/
void
init_signal_handlers()
{
signal(SIGUSR1, suspend_handler);
signal(SIGCONT, continue_handler);
signal(SIGINT, abort_handler);
reset_suspend_time();
}
/**
* \brief reset_suspend_time
*
* Reset time values for suspend signal.
*/
void
reset_suspend_time()
{
timerclear(&suspend_time);
timerclear(&suspend_start);
timerclear(&suspend_end);
}
/**
* \brief suspend signal handler
*
* Signal handler for signal SIGUSR1. SIGSTOP cannot be
* caught, so SIGUSR1 is caught and it throws SIGSTOP.
*/
static void
suspend_handler(int signo)
{
if (signo != SIGUSR1) {
warnx("suspend_handler() got the wrong signal: %d", signo);
return;
}
if (gettimeofday(&suspend_start, NULL) < 0)
errx(-1, "gettimeofday(): %s", strerror(errno));
kill(getpid(), SIGSTOP);
}
/**
* \brief continue_handler
*
* Signal handler for continue signal.
*/
static void
continue_handler(int signo)
{
struct timeval suspend_delta;
if (signo != SIGCONT) {
warnx("continue_handler() got the wrong signal: %d", signo);
return;
}
if (gettimeofday(&suspend_end, NULL) < 0)
errx(-1, "gettimeofday(): %s", strerror(errno));
timersub(&suspend_end, &suspend_start, &suspend_delta);
timeradd(&suspend_time, &suspend_delta, &suspend_time);
}
/**
* \brief abort handler
*
* Signal handler for Ctrl-C
*/
static void
abort_handler(int signo)
{
if (signo == SIGINT && ctx) {
notice(" User interrupt...");
ctx->abort = true;
tcpreplay_abort(ctx);
}
}