signal_handler.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /* $Id$ */
  2. /*
  3. * Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  4. * Copyright (c) 2013-2018 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  5. *
  6. * The Tcpreplay Suite of tools is free software: you can redistribute it
  7. * and/or modify it under the terms of the GNU General Public License as
  8. * published by the Free Software Foundation, either version 3 of the
  9. * License, or with the authors permission any later version.
  10. *
  11. * The Tcpreplay Suite is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with the Tcpreplay Suite. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "config.h"
  20. #include "defines.h"
  21. #include "common.h"
  22. #include <stdlib.h>
  23. #include <signal.h>
  24. #include <sys/time.h>
  25. #include <stdio.h>
  26. #include <sys/types.h>
  27. #include <unistd.h>
  28. #include <string.h>
  29. #include <errno.h>
  30. #include "tcpreplay.h"
  31. #include "tcpreplay_api.h"
  32. #include "signal_handler.h"
  33. struct timeval suspend_time;
  34. static struct timeval suspend_start;
  35. static struct timeval suspend_end;
  36. static void suspend_handler(int signo);
  37. static void continue_handler(int signo);
  38. static void abort_handler(int signo);
  39. extern tcpreplay_t *ctx;
  40. /***************************************************************
  41. * This code is for pausing/restarting tcpreplay using SIGUSR1 *
  42. * for abort code on SIGINT *
  43. ***************************************************************/
  44. /**
  45. * \brief init_signal_handlers
  46. *
  47. * Initialize signal handlers to be used in tcpreplay.
  48. */
  49. void
  50. init_signal_handlers()
  51. {
  52. signal(SIGUSR1, suspend_handler);
  53. signal(SIGCONT, continue_handler);
  54. signal(SIGINT, abort_handler);
  55. reset_suspend_time();
  56. }
  57. /**
  58. * \brief reset_suspend_time
  59. *
  60. * Reset time values for suspend signal.
  61. */
  62. void
  63. reset_suspend_time()
  64. {
  65. timerclear(&suspend_time);
  66. timerclear(&suspend_start);
  67. timerclear(&suspend_end);
  68. }
  69. /**
  70. * \brief suspend signal handler
  71. *
  72. * Signal handler for signal SIGUSR1. SIGSTOP cannot be
  73. * caught, so SIGUSR1 is caught and it throws SIGSTOP.
  74. */
  75. static void
  76. suspend_handler(int signo)
  77. {
  78. if (signo != SIGUSR1) {
  79. warnx("suspend_handler() got the wrong signal: %d", signo);
  80. return;
  81. }
  82. if (gettimeofday(&suspend_start, NULL) < 0)
  83. errx(-1, "gettimeofday(): %s", strerror(errno));
  84. kill(getpid(), SIGSTOP);
  85. }
  86. /**
  87. * \brief continue_handler
  88. *
  89. * Signal handler for continue signal.
  90. */
  91. static void
  92. continue_handler(int signo)
  93. {
  94. struct timeval suspend_delta;
  95. if (signo != SIGCONT) {
  96. warnx("continue_handler() got the wrong signal: %d", signo);
  97. return;
  98. }
  99. if (gettimeofday(&suspend_end, NULL) < 0)
  100. errx(-1, "gettimeofday(): %s", strerror(errno));
  101. timersub(&suspend_end, &suspend_start, &suspend_delta);
  102. timeradd(&suspend_time, &suspend_delta, &suspend_time);
  103. }
  104. /**
  105. * \brief abort handler
  106. *
  107. * Signal handler for Ctrl-C
  108. */
  109. static void
  110. abort_handler(int signo)
  111. {
  112. if (signo == SIGINT && ctx) {
  113. notice(" User interrupt...");
  114. ctx->abort = true;
  115. tcpreplay_abort(ctx);
  116. }
  117. }