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.
137 lines
3.8 KiB
137 lines
3.8 KiB
/*
|
|
* Copyright (C) 2009 iptelorg GmbH
|
|
*
|
|
* 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
|
|
*
|
|
*/
|
|
|
|
#include <malloc.h> /* hook prototypes */
|
|
|
|
#include "../../mem/shm_mem.h"
|
|
#include "shm_regex.h"
|
|
|
|
typedef void *(malloc_hook_t) (size_t, const void *);
|
|
typedef void *(realloc_hook_t) (void *, size_t, const void *);
|
|
typedef void (free_hook_t) (void *, const void *);
|
|
|
|
/* The memory hooks are overwritten before calling regcomp(), regfree(),
|
|
* and regexec(), and shared memory function are called
|
|
* from the hooks instead of libc malloc/realloc/free.
|
|
*/
|
|
|
|
static void *shm_malloc_hook(size_t size, const void *caller)
|
|
{
|
|
return shm_malloc (size);
|
|
}
|
|
|
|
static void *shm_realloc_hook(void *p, size_t size, const void *caller)
|
|
{
|
|
return shm_realloc (p, size);
|
|
}
|
|
|
|
static void shm_free_hook(void *ptr, const void *caller)
|
|
{
|
|
if (ptr) shm_free (ptr);
|
|
}
|
|
|
|
#define replace_malloc_hooks() \
|
|
do { \
|
|
orig_malloc_hook = __malloc_hook; \
|
|
orig_realloc_hook = __realloc_hook; \
|
|
orig_free_hook = __free_hook; \
|
|
__malloc_hook = shm_malloc_hook; \
|
|
__realloc_hook = shm_realloc_hook; \
|
|
__free_hook = shm_free_hook; \
|
|
} while (0)
|
|
|
|
#define restore_malloc_hooks() \
|
|
do { \
|
|
__malloc_hook = orig_malloc_hook; \
|
|
__realloc_hook = orig_realloc_hook; \
|
|
__free_hook = orig_free_hook; \
|
|
} while (0)
|
|
|
|
int shm_regcomp(shm_regex_t *preg, const char *regex, int cflags)
|
|
{
|
|
malloc_hook_t *orig_malloc_hook;
|
|
realloc_hook_t *orig_realloc_hook;
|
|
free_hook_t *orig_free_hook;
|
|
int ret;
|
|
|
|
if(!lock_init(&preg->lock)) {
|
|
return REG_EEND;
|
|
}
|
|
replace_malloc_hooks();
|
|
ret = regcomp(&preg->regexp, regex, cflags);
|
|
restore_malloc_hooks();
|
|
|
|
if(ret) lock_destroy(&preg->lock);
|
|
|
|
return ret;
|
|
}
|
|
|
|
void shm_regfree(shm_regex_t *preg)
|
|
{
|
|
malloc_hook_t *orig_malloc_hook;
|
|
realloc_hook_t *orig_realloc_hook;
|
|
free_hook_t *orig_free_hook;
|
|
lock_destroy(&preg->lock);
|
|
replace_malloc_hooks();
|
|
regfree(&preg->regexp);
|
|
restore_malloc_hooks();
|
|
}
|
|
|
|
int shm_regexec(shm_regex_t *preg, const char *string, size_t nmatch,
|
|
regmatch_t pmatch[], int eflags)
|
|
{
|
|
malloc_hook_t *orig_malloc_hook;
|
|
realloc_hook_t *orig_realloc_hook;
|
|
free_hook_t *orig_free_hook;
|
|
int ret;
|
|
|
|
/* regexec() allocates some memory for the pattern buffer
|
|
* when it is successfully called for the first time, therefore
|
|
* shared memory is required also here.
|
|
* The drawback is that shared memory allocation is also used
|
|
* needlessly for allocating the temporary space for
|
|
* the elements of pmatch. -- Does not happen if pmatch and
|
|
* nmatch are 0.
|
|
* It is safe to call regexec() concurrently without locking,
|
|
* because regexec() has its own locks.
|
|
* (Miklos)
|
|
*
|
|
* Those locks, however, don't work with shm and multi-core hardware
|
|
* causing a dead-lock. Tested with glibc 2.3.6. (skeller)
|
|
*/
|
|
|
|
lock_get(&preg->lock);
|
|
replace_malloc_hooks();
|
|
ret = regexec(&preg->regexp, string, nmatch,
|
|
pmatch, eflags);
|
|
restore_malloc_hooks();
|
|
lock_release(&preg->lock);
|
|
|
|
return ret;
|
|
}
|
|
|
|
size_t shm_regerror(int errcode, const shm_regex_t *preg, char *errbuf,
|
|
size_t errbuf_size)
|
|
{
|
|
return regerror(errcode, &preg->regexp, errbuf, errbuf_size);
|
|
}
|
|
|