mirror of https://github.com/sipwise/kamailio.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
172 lines
4.1 KiB
172 lines
4.1 KiB
/*
|
|
* Copyright (C) 2001-2003 FhG Fokus
|
|
*
|
|
* This file is part of Kamailio, a free SIP server.
|
|
*
|
|
* Kamailio 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 2 of the License, or
|
|
* (at your option) any later version
|
|
*
|
|
* Kamailio 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 this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*
|
|
*/
|
|
|
|
/*!
|
|
* \file
|
|
* \brief Exec module:: Kill
|
|
* \ingroup exec
|
|
* Module: \ref exec
|
|
*
|
|
* in this file, we implement the ability to send a kill signal to
|
|
* a child after some time; its a quick ugly hack, for example kill
|
|
* is sent without any knowledge whether the kid is still alive
|
|
*
|
|
* also, it was never compiled without FAST_LOCK -- nothing will
|
|
* work if you turn it off
|
|
*
|
|
* there is also an ugly s/HACK
|
|
*
|
|
* and last but not least -- we don't know the child pid (we use popen)
|
|
* so we cannot close anyway
|
|
*
|
|
* From the README:
|
|
* (There is kill.c but it is not used along with the current mechanisms based on popen. Besides that kill.c is ugly).
|
|
*/
|
|
|
|
|
|
#include <errno.h>
|
|
#include <sys/types.h>
|
|
#include <signal.h>
|
|
|
|
#include "../../mem/shm_mem.h"
|
|
#include "../../dprint.h"
|
|
#include "../../timer.h"
|
|
#include "../../locking.h"
|
|
|
|
#include "kill.h"
|
|
|
|
|
|
static gen_lock_t *kill_lock=NULL;
|
|
|
|
|
|
static struct timer_list kill_list;
|
|
|
|
|
|
|
|
#define lock() lock_get(kill_lock)
|
|
|
|
#define unlock() lock_release(kill_lock)
|
|
|
|
|
|
|
|
/* copy and paste from TM -- might consider putting in better
|
|
in some utils part of core
|
|
*/
|
|
static void timer_routine(unsigned int ticks , void * attr)
|
|
{
|
|
struct timer_link *tl, *tmp_tl, *end, *ret;
|
|
int killr;
|
|
|
|
/* check if it worth entering the lock */
|
|
if (kill_list.first_tl.next_tl==&kill_list.last_tl
|
|
|| kill_list.first_tl.next_tl->time_out > ticks )
|
|
return;
|
|
|
|
lock();
|
|
end = &kill_list.last_tl;
|
|
tl = kill_list.first_tl.next_tl;
|
|
while( tl!=end && tl->time_out <= ticks ) {
|
|
tl=tl->next_tl;
|
|
}
|
|
|
|
/* nothing to delete found */
|
|
if (tl->prev_tl==&kill_list.first_tl) {
|
|
unlock();
|
|
return;
|
|
}
|
|
/* the detached list begins with current beginning */
|
|
ret = kill_list.first_tl.next_tl;
|
|
/* and we mark the end of the split list */
|
|
tl->prev_tl->next_tl = 0;
|
|
/* the shortened list starts from where we suspended */
|
|
kill_list.first_tl.next_tl = tl;
|
|
tl->prev_tl = & kill_list.first_tl;
|
|
unlock();
|
|
|
|
/* process the list now */
|
|
while (ret) {
|
|
tmp_tl=ret->next_tl;
|
|
ret->next_tl=ret->prev_tl=0;
|
|
if (ret->time_out>0) {
|
|
killr=kill(ret->pid, SIGTERM );
|
|
LM_DBG("child process (%d) kill status: %d\n", ret->pid, killr );
|
|
}
|
|
shm_free(ret);
|
|
ret=tmp_tl;
|
|
}
|
|
}
|
|
|
|
int schedule_to_kill( int pid )
|
|
{
|
|
struct timer_link *tl;
|
|
tl=shm_malloc( sizeof(struct timer_link) );
|
|
if (tl==0) {
|
|
LM_ERR("no shmem\n");
|
|
return -1;
|
|
}
|
|
memset(tl, 0, sizeof(struct timer_link) );
|
|
lock();
|
|
tl->pid=pid;
|
|
tl->time_out=get_ticks()+time_to_kill;
|
|
tl->prev_tl=kill_list.last_tl.prev_tl;
|
|
tl->next_tl=&kill_list.last_tl;
|
|
kill_list.last_tl.prev_tl=tl;
|
|
tl->prev_tl->next_tl=tl;
|
|
unlock();
|
|
return 1;
|
|
}
|
|
|
|
int initialize_kill(void)
|
|
{
|
|
/* if disabled ... */
|
|
if (time_to_kill==0) return 1;
|
|
if ((register_timer( timer_routine,
|
|
0 /* param */, 1 /* period */)<0)) {
|
|
LM_ERR("no exec timer registered\n");
|
|
return -1;
|
|
}
|
|
kill_list.first_tl.next_tl=&kill_list.last_tl;
|
|
kill_list.last_tl.prev_tl=&kill_list.first_tl;
|
|
kill_list.first_tl.prev_tl=
|
|
kill_list.last_tl.next_tl = 0;
|
|
kill_list.last_tl.time_out=-1;
|
|
kill_lock=lock_alloc();
|
|
if (kill_lock==0) {
|
|
LM_ERR("no shm mem for mutex\n");
|
|
return -1;
|
|
}
|
|
lock_init(kill_lock);
|
|
LM_DBG("kill initialized\n");
|
|
return 1;
|
|
}
|
|
|
|
void destroy_kill(void)
|
|
{
|
|
/* if disabled ... */
|
|
if (time_to_kill==0)
|
|
return;
|
|
if (kill_lock) {
|
|
lock_destroy(kill_lock);
|
|
lock_dealloc(kill_lock);
|
|
}
|
|
return;
|
|
}
|