kill.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /*
  2. *
  3. * $Id$
  4. *
  5. * in this file, we implement the ability to send a kill signal to
  6. * a child after some time; its a quick ugly hack, for example kill
  7. * is sent without any knowledge whether the kid is still alive
  8. *
  9. * also, it was never compiled without FAST_LOCK -- nothing will
  10. * work if you turn it off
  11. *
  12. * there is also an ugly s/HACK
  13. *
  14. * and last but not least -- we don't know the child pid (we use popen)
  15. * so we cannot close anyway
  16. *
  17. * Copyright (C) 2001-2003 FhG Fokus
  18. *
  19. * This file is part of ser, a free SIP server.
  20. *
  21. * ser is free software; you can redistribute it and/or modify
  22. * it under the terms of the GNU General Public License as published by
  23. * the Free Software Foundation; either version 2 of the License, or
  24. * (at your option) any later version
  25. *
  26. * For a license to use the ser software under conditions
  27. * other than those described here, or to purchase support for this
  28. * software, please contact iptel.org by e-mail at the following addresses:
  29. * [email protected]
  30. *
  31. * ser is distributed in the hope that it will be useful,
  32. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  33. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  34. * GNU General Public License for more details.
  35. *
  36. * You should have received a copy of the GNU General Public License
  37. * along with this program; if not, write to the Free Software
  38. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  39. */
  40. /*
  41. * History:
  42. * --------
  43. * 2003-03-11 changed to the new locking scheme: locking.h (andrei)
  44. */
  45. #include <errno.h>
  46. #include <sys/types.h>
  47. #include <signal.h>
  48. #include "../../mem/shm_mem.h"
  49. #include "../../dprint.h"
  50. #include "../../timer.h"
  51. #include "../../locking.h"
  52. #include "kill.h"
  53. static gen_lock_t *kill_lock;
  54. static struct timer_list kill_list;
  55. #define lock() lock_get(kill_lock)
  56. #define unlock() lock_release(kill_lock)
  57. /* copy and paste from TM -- might consider putting in better
  58. in some utils part of core
  59. */
  60. static void timer_routine(unsigned int ticks , void * attr)
  61. {
  62. struct timer_link *tl, *tmp_tl, *end, *ret;
  63. int killr;
  64. /* check if it worth entering the lock */
  65. if (kill_list.first_tl.next_tl==&kill_list.last_tl
  66. || kill_list.first_tl.next_tl->time_out > ticks )
  67. return;
  68. lock();
  69. end = &kill_list.last_tl;
  70. tl = kill_list.first_tl.next_tl;
  71. while( tl!=end && tl->time_out <= ticks ) {
  72. tl=tl->next_tl;
  73. }
  74. /* nothing to delete found */
  75. if (tl->prev_tl==&kill_list.first_tl) {
  76. unlock();
  77. return;
  78. }
  79. /* the detached list begins with current beginning */
  80. ret = kill_list.first_tl.next_tl;
  81. /* and we mark the end of the split list */
  82. tl->prev_tl->next_tl = 0;
  83. /* the shortened list starts from where we suspended */
  84. kill_list.first_tl.next_tl = tl;
  85. tl->prev_tl = & kill_list.first_tl;
  86. unlock();
  87. /* process the list now */
  88. while (ret) {
  89. tmp_tl=ret->next_tl;
  90. ret->next_tl=ret->prev_tl=0;
  91. if (ret->time_out>0) {
  92. killr=kill(ret->pid, SIGTERM );
  93. DBG("DEBUG: child process (%d) kill status: %d\n",
  94. ret->pid, killr );
  95. }
  96. shm_free(ret);
  97. ret=tmp_tl;
  98. }
  99. }
  100. int schedule_to_kill( int pid )
  101. {
  102. struct timer_link *tl;
  103. tl=shm_malloc( sizeof(struct timer_link) );
  104. if (tl==0) {
  105. LOG(L_ERR, "ERROR: schedule_to_kill: no shmem\n");
  106. return -1;
  107. }
  108. memset(tl, 0, sizeof(struct timer_link) );
  109. lock();
  110. tl->pid=pid;
  111. tl->time_out=get_ticks()+time_to_kill;
  112. tl->prev_tl=kill_list.last_tl.prev_tl;
  113. tl->next_tl=&kill_list.last_tl;
  114. kill_list.last_tl.prev_tl=tl;
  115. tl->prev_tl->next_tl=tl;
  116. unlock();
  117. return 1;
  118. }
  119. int initialize_kill()
  120. {
  121. /* if disabled ... */
  122. if (time_to_kill==0) return 1;
  123. if ((register_timer( timer_routine,
  124. 0 /* param */, 1 /* period */)<0)) {
  125. LOG(L_ERR, "ERROR: kill_initialize: no exec timer registered\n");
  126. return -1;
  127. }
  128. kill_list.first_tl.next_tl=&kill_list.last_tl;
  129. kill_list.last_tl.prev_tl=&kill_list.first_tl;
  130. kill_list.first_tl.prev_tl=
  131. kill_list.last_tl.next_tl = 0;
  132. kill_list.last_tl.time_out=-1;
  133. kill_lock=lock_alloc();
  134. if (kill_lock==0) {
  135. LOG(L_ERR, "ERROR: initialize_kill: no mem for mutex\n");
  136. return -1;
  137. }
  138. lock_init(kill_lock);
  139. DBG("DEBUG: kill initialized\n");
  140. return 1;
  141. }
  142. void destroy_kill()
  143. {
  144. /* if disabled ... */
  145. if (time_to_kill==0)
  146. return;
  147. if (kill_lock){
  148. lock_destroy(kill_lock);
  149. lock_dealloc(kill_lock);
  150. }
  151. return;
  152. }