signal_handler.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /* $Id$ */
  2. /*
  3. * Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  4. * Copyright (c) 2013-2022 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 "signal_handler.h"
  20. #include "defines.h"
  21. #include "config.h"
  22. #include "common.h"
  23. #include "tcpreplay_api.h"
  24. #include <errno.h>
  25. #include <signal.h>
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include <sys/time.h>
  30. #include <unistd.h>
  31. struct timeval suspend_time;
  32. static struct timeval suspend_start;
  33. static struct timeval suspend_end;
  34. static void suspend_handler(int signo);
  35. static void continue_handler(int signo);
  36. static void abort_handler(int signo);
  37. extern tcpreplay_t *ctx;
  38. /***************************************************************
  39. * This code is for pausing/restarting tcpreplay using SIGUSR1 *
  40. * for abort code on SIGINT *
  41. ***************************************************************/
  42. /**
  43. * \brief init_signal_handlers
  44. *
  45. * Initialize signal handlers to be used in tcpreplay.
  46. */
  47. void
  48. init_signal_handlers()
  49. {
  50. signal(SIGUSR1, suspend_handler);
  51. signal(SIGCONT, continue_handler);
  52. signal(SIGINT, abort_handler);
  53. reset_suspend_time();
  54. }
  55. /**
  56. * \brief reset_suspend_time
  57. *
  58. * Reset time values for suspend signal.
  59. */
  60. void
  61. reset_suspend_time()
  62. {
  63. timerclear(&suspend_time);
  64. timerclear(&suspend_start);
  65. timerclear(&suspend_end);
  66. }
  67. /**
  68. * \brief suspend signal handler
  69. *
  70. * Signal handler for signal SIGUSR1. SIGSTOP cannot be
  71. * caught, so SIGUSR1 is caught and it throws SIGSTOP.
  72. */
  73. static void
  74. suspend_handler(int signo)
  75. {
  76. if (signo != SIGUSR1) {
  77. warnx("suspend_handler() got the wrong signal: %d", signo);
  78. return;
  79. }
  80. if (gettimeofday(&suspend_start, NULL) < 0)
  81. errx(-1, "gettimeofday(): %s", strerror(errno));
  82. kill(getpid(), SIGSTOP);
  83. }
  84. /**
  85. * \brief continue_handler
  86. *
  87. * Signal handler for continue signal.
  88. */
  89. static void
  90. continue_handler(int signo)
  91. {
  92. struct timeval suspend_delta;
  93. if (signo != SIGCONT) {
  94. warnx("continue_handler() got the wrong signal: %d", signo);
  95. return;
  96. }
  97. if (gettimeofday(&suspend_end, NULL) < 0)
  98. errx(-1, "gettimeofday(): %s", strerror(errno));
  99. timersub(&suspend_end, &suspend_start, &suspend_delta);
  100. timeradd(&suspend_time, &suspend_delta, &suspend_time);
  101. }
  102. /**
  103. * \brief abort handler
  104. *
  105. * Signal handler for Ctrl-C
  106. */
  107. static void
  108. abort_handler(int signo)
  109. {
  110. if (signo == SIGINT && ctx) {
  111. notice(" User interrupt...");
  112. ctx->abort = true;
  113. tcpreplay_abort(ctx);
  114. }
  115. }