Browse Source

Merge commit 'origin/ser_core_cvs'

* commit 'origin/ser_core_cvs':
  Wrapper functions for regcomp, regexec, regfree, and regerror using shared
  make: minor optimizations
  make: fail if make version < 3.80
  make: workaround for make 3.80
  make: workaround for backwards compat. with make 3.80
  dns: fix selecting neg. cname entry
Andrei Pelinescu-Onciul 16 years ago
parent
commit
583ea36b97
11 changed files with 296 additions and 47 deletions
  1. 1 1
      INSTALL
  2. 31 13
      Makefile
  3. 22 22
      Makefile.defs
  4. 9 2
      Makefile.rules
  5. 5 2
      dns_cache.c
  6. 1 1
      lib/Makefile
  7. 16 6
      lib/README
  8. 14 0
      lib/shm_regex/Makefile
  9. 23 0
      lib/shm_regex/README
  10. 129 0
      lib/shm_regex/shm_regex.c
  11. 45 0
      lib/shm_regex/shm_regex.h

+ 1 - 1
INSTALL

@@ -53,7 +53,7 @@ Requirements:
 - bison or yacc (Berkley yacc)
 - flex
 - GNU make (on Linux this is the standard "make", on *BSD and Solaris is
- called "gmake") version >= 3.79.
+ called "gmake") version >= 3.80 (recommended 3.81).
 - sed and tr (used in the makefiles)
 - GNU tar ("gtar" on Solaris) and gzip if you want "make tar" to work
 - GNU install, BSD install or Solaris install if you want "make

+ 31 - 13
Makefile

@@ -56,8 +56,21 @@
 #              added cfg-defs, new target that only rebuilds config.mak
 #  2009-03-10  replaced DEFS with C_DEFS (DEFS are now used only for
 #              "temporary" defines inside modules or libs) (andrei)
+#  2009-04-02  workaround for export not supported in gnu make 3.80
+#               target specific variables: use mk_params for each
+#               $(MAKE) invocation (andrei)
 #
 
+# check make version
+# required 3.80, recommended 3.81
+req_ver=3.80
+# the check below works for version number of the type x.yy or x.yy.z*
+# (from the GNU Make Cookbook)
+ifeq (,$(filter $(req_ver),$(firstword $(sort $(MAKE_VERSION) $(req_ver)))))
+$(error make version $(MAKE_VERSION) not supported, use at least $(req_ver))
+endif
+
+
 auto_gen=lex.yy.c cfg.tab.c #lexx, yacc etc
 auto_gen_others=cfg.tab.h  # auto generated, non-c
 
@@ -197,7 +210,7 @@ endif
 # status of the modules
 # the rest is excluded because it depends on external libraries
 #
-static_modules=
+static_modules:=
 
 ALLDEP=config.mak Makefile Makefile.sources Makefile.rules
 
@@ -235,7 +248,7 @@ static_modules_path=$(addprefix modules/, $(static_modules))
 extra_sources=$(wildcard $(addsuffix /*.c, $(static_modules_path)))
 extra_objs=$(extra_sources:.c=.o)
 
-static_defs= $(foreach  mod, $(static_modules), \
+static_defs:= $(foreach  mod, $(static_modules), \
 		-DSTATIC_$(shell echo $(mod) | tr [:lower:] [:upper:]) )
 
 override extra_defs+=$(static_defs) $(EXTRA_DEFS)
@@ -262,7 +275,7 @@ endif # ifneq($(group_include),)
 endif # ifneq($(modules_configured),1)
 modules_names=$(shell echo $(modules)| \
 				sed -e 's/modules\/\([^/ ]*\)\/*/\1.so/g' )
-modules_basenames=$(shell echo $(modules)| \
+modules_basenames:=$(shell echo $(modules)| \
 				sed -e 's/modules\/\([^/ ]*\)\/*/\1/g' )
 #modules_names=$(patsubst modules/%, %.so, $(modules))
 #modules_full_path=$(join  $(modules), $(addprefix /, $(modules_names)))
@@ -381,7 +394,8 @@ modules: modules.lst
 		if [ -n "$$r" -a -r "$$r/Makefile" ]; then \
 			echo  "" ; \
 			echo  "" ; \
-			if  $(MAKE) -C $$r || [ ${err_fail} != 1 ] ; then \
+			if  $(MAKE) -C $$r $(mk_params) || [ ${err_fail} != 1 ] ; \
+			then\
 				:; \
 			else \
 				exit 1; \
@@ -395,7 +409,7 @@ $(extra_objs):
 		if [ -n "$$r" -a -r "$$r/Makefile"  ]; then \
 			echo  "" ; \
 			echo  "Making static module $r" ; \
-			if $(MAKE) -C $$r static ; then  \
+			if $(MAKE) -C $$r static $(mk_params) ; then  \
 				:; \
 			else \
 				exit 1; \
@@ -409,7 +423,8 @@ utils:
 		if [ -n "$$r" ]; then \
 			echo  "" ; \
 			echo  "" ; \
-			if  $(MAKE) -C $$r || [ ${err_fail} != 1 ] ; then \
+			if  $(MAKE) -C $$r $(mk_params) || [ ${err_fail} != 1 ] ; \
+			then \
 				:; \
 			else \
 				exit 1; \
@@ -466,7 +481,7 @@ tar:
 .PHONY: bin
 bin:
 	mkdir -p tmp/ser/usr/local
-	$(MAKE) install basedir=tmp/ser 
+	$(MAKE) install basedir=tmp/ser $(mk_params)
 	$(TAR) -C tmp/ser/ -zcf ../$(NAME)-$(RELEASE)_$(OS)_$(ARCH).tar.gz .
 	rm -rf tmp/ser
 
@@ -484,7 +499,7 @@ deb:
 sunpkg:
 	mkdir -p tmp/ser
 	mkdir -p tmp/ser_sun_pkg
-	$(MAKE) install basedir=tmp/ser prefix=/usr/local
+	$(MAKE) install basedir=tmp/ser prefix=/usr/local $(mk_params)
 	(cd pkg/solaris; \
 	pkgmk -r ../../tmp/ser/usr/local -o -d ../../tmp/ser_sun_pkg/ -v "$(RELEASE)" ;\
 	cd ../..)
@@ -501,7 +516,7 @@ modules-doc: modules.lst
 		if [ -n "$$r" ]; then \
 			echo  "" ; \
 			echo  "" ; \
-			$(MAKE) -C $$r/doc $(doc_format) ; \
+			$(MAKE) -C $$r/doc $(doc_format)  $(mk_params); \
 		fi ; \
 	done 
 
@@ -514,7 +529,8 @@ README: modules.lst
 		if [ -n "$$r" ]; then \
 			echo  "" ; \
 			echo  "" ; \
-			if  $(MAKE) -C $$r README || [ ${err_fail} != 1 ] ; then \
+			if  $(MAKE) -C $$r README $(mk_params) || \
+				[ ${err_fail} != 1 ] ; then \
 				:; \
 			else \
 				exit 1; \
@@ -531,7 +547,8 @@ man: modules.lst
 		if [ -n "$$r" ]; then \
 			echo  "" ; \
 			echo  "" ; \
-			if  $(MAKE) -C $$r man || [ ${err_fail} != 1 ] ; then \
+			if  $(MAKE) -C $$r man $(mk_params) || [ ${err_fail} != 1 ] ; \
+			then \
 				:; \
 			else \
 				exit 1; \
@@ -540,7 +557,7 @@ man: modules.lst
 	done; true
 
 .PHONY: install
-install: export compile_for_install=yes
+install: mk_params="compile_for_install=yes"
 install: install-bin install-modules install-cfg \
 	install-doc install-man install-utils install-share
 
@@ -636,7 +653,8 @@ install-modules: modules.lst $(modules_prefix)/$(modules_dir)
 		if [ -n "$$r" -a -r "$$r/Makefile" ]; then \
 			echo  "" ; \
 			echo  "" ; \
-			if  $(MAKE) -C $$r install || [ ${err_fail} != 1 ] ; then \
+			if  $(MAKE) -C $$r install $(mk_params) || \
+				[ ${err_fail} != 1 ] ; then \
 				:; \
 			else \
 				exit 1; \

+ 22 - 22
Makefile.defs

@@ -110,8 +110,8 @@ EXTRAVERSION = -dev23-make
 
 SER_VER = $(shell expr $(VERSION) \* 1000000 + $(PATCHLEVEL) \* 1000 + \
 			$(SUBLEVEL) )
-RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
-OS = $(shell uname -s | sed -e s/SunOS/solaris/ -e s/CYGWIN.*/cygwin/ \
+RELEASE:=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
+OS := $(shell uname -s | sed -e s/SunOS/solaris/ -e s/CYGWIN.*/cygwin/ \
 		 | tr "[A-Z]" "[a-z]")
 
 ifeq ($(OS),solaris)
@@ -138,9 +138,9 @@ ifeq ($(ARCH),sparc)
 	endif
 endif
 
-OSREL = $(shell uname -r)
+OSREL := $(shell uname -r)
 # numerical version (good for comparisons: A.B.C => A*1000000+B*1000+C)
-OSREL_N= $(shell echo $(OSREL) | sed -e 's/^[^0-9]*//' \
+OSREL_N:= $(shell echo $(OSREL) | sed -e 's/^[^0-9]*//' \
 		-e 's/^\([0-9][0-9]*\(\.[0-9][0-9]*\)*\).*$$/\1/g' | \
 		(IFS=. read A B C D; R=0; \
 		[ -n "$$A" ] && R=`expr $$R \* 1000 + $$A` && \
@@ -271,7 +271,7 @@ ifeq ($(CC),)
 	CC=gcc
 endif
 LD= $(CC)
-CC_LONGVER=$(shell if  $(CC) -v 2>/dev/null; then \
+CC_LONGVER:=$(shell if  $(CC) -v 2>/dev/null; then \
 						$(CC) -v 2>&1 ;\
 					else \
 						$(CC) -V 2>&1 ; \
@@ -282,14 +282,14 @@ MKTAGS=ctags -R .
 
 ifneq (,$(findstring gcc, $(CC_LONGVER)))
 	CC_NAME=gcc
-	CC_VER=$(word 1,$(CC)) $(shell $(CC) - --version|head -n 1|cut -d" " -f 3|\
-				 sed -e 's/^.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/'\
+	CC_VER:=$(word 1,$(CC)) $(shell $(CC) - --version|head -n 1|cut -d" " -f 3\
+				|sed -e 's/^.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/'\
 				 	 -e 's/^[^0-9].*\([0-9][0-9]*\.[0-9][0-9]*\).*/\1/')
 	# sed with POSIX.1 regex doesn't support |, + or ? 
         # (darwin, solaris ...) => this complicated expression
 	MKDEP=$(CC) -MM 
 	#transform gcc version into 2.9x or 3.0
-	CC_SHORTVER=$(shell echo "$(CC_VER)" | cut -d" " -f 2| \
+	CC_SHORTVER:=$(shell echo "$(CC_VER)" | cut -d" " -f 2| \
 				 sed -e 's/[^0-9]*-\(.*\)/\1/'| \
 				 sed -e 's/2\.9.*/2.9x/' -e 's/3\.[0-3]\..*/3.0/' -e \
 				 	's/3\.[0-3]/3.0/' -e 's/3\.[4-9]\..*/3.4/' -e \
@@ -299,7 +299,7 @@ endif
 
 ifneq (, $(findstring Sun, $(CC_LONGVER)))
 	CC_NAME=suncc
-	CC_SHORTVER=$(shell echo "$(CC_LONGVER)"|head -n 1| \
+	CC_SHORTVER:=$(shell echo "$(CC_LONGVER)"|head -n 1| \
 					sed -e 's/.*\([0-9]\.[0-9]\).*/\1/g' )
 	CC_VER=$(CC) $(CC_SHORTVER)
 	MKDEP=$(CC) -xM1 
@@ -308,9 +308,9 @@ endif
 ifneq (, $(findstring Intel(R) C++ Compiler, $(CC_LONGVER)))
 	# very nice: gcc compatible
 	CC_NAME=icc
-	CC_FULLVER=$(shell echo "$(CC_LONGVER)"|head -n 1| \
+	CC_FULLVER:=$(shell echo "$(CC_LONGVER)"|head -n 1| \
 					sed -e 's/.*Version \([0-9]\.[0-9]\.[0-9]*\).*/\1/g' )
-	CC_SHORTVER=$(shell echo "$(CC_FULLVER)" | cut -d. -f1,2 )
+	CC_SHORTVER:=$(shell echo "$(CC_FULLVER)" | cut -d. -f1,2 )
 	CC_VER=$(CC) $(CC_FULLVER)
 	MKDEP=$(CC) -MM 
 endif
@@ -533,18 +533,18 @@ endif
 # find ld & as name (gnu or solaris)
 ifeq ($(OS), solaris)
 ifeq ($(CC_NAME), gcc)
-		LDGCC=$(shell $(CC) -v 2>&1 | grep with-ld| \
+		LDGCC:=$(shell $(CC) -v 2>&1 | grep with-ld| \
 				   sed -e 's/.*--with-ld=\([^ ][^ ]*\).*/\1/' )
-		ASGCC=$(shell $(CC) -v 2>&1 | grep with-as| \
+		ASGCC:=$(shell $(CC) -v 2>&1 | grep with-as| \
 				   sed -e 's/.*--with-as=\([^ ][^ ]*\).*/\1/' )
-		LDPATH=$(shell  if [ -z "$(LDGCC)" ] ; then echo "ld" ;\
+		LDPATH:=$(shell  if [ -z "$(LDGCC)" ] ; then echo "ld" ;\
 						else \
 						if $(LDGCC) -V 2>/dev/null 1>/dev/null; then \
 							echo $(LDGCC); \
 						else echo "ld" ; \
 						fi\
 						fi)
-		ASPATH=$(shell  if [ -z "$(ASGCC)" ] ; then echo "as" ;\
+		ASPATH:=$(shell  if [ -z "$(ASGCC)" ] ; then echo "as" ;\
 						else \
 						if $(ASGCC) -V 2>/dev/null 1>/dev/null; then \
 							echo $(ASGCC); \
@@ -552,7 +552,7 @@ ifeq ($(CC_NAME), gcc)
 						fi\
 						fi)
 							
-		LDTYPE=$(shell if $(LDPATH) -V 1>/dev/null  2>/dev/null; then \
+		LDTYPE:=$(shell if $(LDPATH) -V 1>/dev/null  2>/dev/null; then \
 							if $(LDPATH) -V 2>&1|grep GNU >/dev/null; \
 							then echo gnu; \
 							else \
@@ -563,13 +563,13 @@ ifeq ($(CC_NAME), gcc)
 							fi \
 							fi \
 						fi)
-		ASTYPE=$(shell if $(ASPATH) -V 1>/dev/null  2>/dev/null </dev/null; \
+		ASTYPE:=$(shell if $(ASPATH) -V 1>/dev/null  2>/dev/null </dev/null; \
 						then \
-							if $(ASPATH) -V 2>&1 </dev/null |grep GNU >/dev/null; \
-							then echo gnu; \
+							if $(ASPATH) -V 2>&1 </dev/null | \
+								grep GNU >/dev/null; then echo gnu; \
 							else \
-							if $(ASPATH) -V 2>&1 </dev/null |grep Sun >/dev/null;\
-							then echo solaris; \
+							if $(ASPATH) -V 2>&1 </dev/null | \
+								grep Sun >/dev/null; then echo solaris; \
 							else \
 								echo unknown ; \
 							fi \
@@ -1544,7 +1544,7 @@ ifeq ($(OS), openbsd)
 	# no sched_yield on openbsd unless linking with c_r (not recommended)
 	# unfortunately pthread is needed for sigwait
 	LIBS= -lpthread
-	OPENBSD_IS_AOUT= $(shell echo "$(OSREL)" | \
+	OPENBSD_IS_AOUT:= $(shell echo "$(OSREL)" | \
 				sed -e 's/^3\.[0-3][^0-9]*$$/yes/' |sed -e 's/^[0-2]\..*/yes/')
 # exception: on sparc openbsd 3.2 is elf and not aout
 ifeq ($(OSREL), 3.2)

+ 9 - 2
Makefile.rules

@@ -65,7 +65,7 @@ ALLDEP+=makecfg.lst
 # on some ser libs)
 
 ifneq	($(SER_LIBS),)
-# abspath & realpath don't seem to work on darwin
+# abspath & realpath don't work on make <= 3.80
 SER_LIBS_DIRS:=$(dir $(SER_LIBS))
 ifneq	(,$(filter install install% %install, $(MAKECMDGOALS)))
 lib_compile_for_install=yes
@@ -79,7 +79,14 @@ ifneq	($(LD_RPATH),)
 ifneq	(,$(filter install install% %install, $(MAKECMDGOALS)))
 SER_RPATH_LST:=$(lib_target)
 else
-SER_RPATH_LST:=$(realpath $(dir $(SER_LIBS)))
+# realpath is not supported in make 3.80 or older
+ifeq (,$(filter-out 3.80 3.80.%,$(MAKE_VERSION)))
+fullpath=$(shell cd $(1); pwd)
+else
+fullpath=$(realpath $(1))
+endif
+
+SER_RPATH_LST:=$(call fullpath,$(dir $(SER_LIBS)))
 endif
 ifneq	($(strip $(SER_RPATH_LST)),)
 SER_RPATH:=$(addprefix $(LD_RPATH),$(SER_RPATH_LST))

+ 5 - 2
dns_cache.c

@@ -584,8 +584,11 @@ again:
 #endif
 #endif
 			return e;
-		}else if ((e->type==T_CNAME) && (e->name_len==name->len) &&
-			(strncasecmp(e->name, name->s, e->name_len)==0)){
+		}else if ((e->type==T_CNAME) && !((e->rr_lst==0) || e->err_flags) &&
+					(e->name_len==name->len) &&
+					(strncasecmp(e->name, name->s, e->name_len)==0)){
+			/*if CNAME matches and CNAME is entry is not a neg. cache entry
+			  (could be produced by a specific CNAME lookup)*/
 			e->last_used=now;
 #ifdef DNS_LU_LST
 			/* add it at the end */

+ 1 - 1
lib/Makefile

@@ -7,7 +7,7 @@
 #
 
 
-SUBDIRS=binrpc cds xcap presence
+SUBDIRS=binrpc cds xcap presence shm_regex
 
 .PHONY: subdirs $(SUBDIRS) 
 

+ 16 - 6
lib/README

@@ -24,6 +24,9 @@ xcap - Common XCAP operations and structures (XCAP authorization documents
        requires external libraries: libxml2, libcurl3 (nonSER version)
        requires internal libraries: cds
 
+shm_regex - Wrapper functions for regcomp, regexec, regfree and regerror
+	    using shared memory. See 'man regex' for details.
+
 Used by modules: pa, rls, dialog, rpa
 
 trie - Common digit trie implementation for prefix matching, used by
@@ -32,23 +35,24 @@ trie - Common digit trie implementation for prefix matching, used by
 Usage:
 -----
 
-All libraries can be compiled "with ser" or "without ser". Compilation
-without ser may be useful for debugging purposes or for example for 
+All libraries except shm_regex can be compiled "with ser" or "without ser".
+Compilation without ser may be useful for debugging purposes or for example for 
 searching for memory leaks with some tool like valgrind.
+shm_regex library can be compiled only with ser.
 
 Compilation with ser:
 --------------------
 
 Compilation and installation of these libraries is NOT DONE by running
-main ser makefile now - it MUST be done MANUALLY. For this purpose
-is there Makefile.ser. To compile and install libraries simply run
+main ser makefile now - it MUST be done MANUALLY. To compile and install
+libraries simply run
 
-   make -f Makefile.ser install
+   make install
 
 in lib directory. You can select destination directory like in the case
 of ser, for example:
 
-   make -f Makefile.ser install prefix="/my/ser/directory"
+   make install prefix="/my/ser/directory"
    
 AFTER COMPILATION of libraries you can COMPILE MODULES using this 
 libraries like PA, RLS or dialog.
@@ -64,6 +68,12 @@ you should set LD_LIBRARY_PATH=/usr/local/lib/ser. In the case of
 nonstandard installation, you can use something like 
 LD_LIBRARY_PATH=/my/ser/directory/lib/ser.
 
+Compilation without ser:
+--------------------
+Use the alternate makefile, Makefile.noser:
+
+   make -f Makefile.noser install
+
 Documentation
 -------------
 Documentation for all libraries is (or will be) in 

+ 14 - 0
lib/shm_regex/Makefile

@@ -0,0 +1,14 @@
+#
+# makefile for shm_regex
+#
+
+include ../../Makefile.defs
+auto_gen=
+NAME:=ser_shm_regex
+MAJOR_VER=0
+MINOR_VER=1
+BUGFIX_VER=0
+LIBS=
+
+include ../../Makefile.libs
+

+ 23 - 0
lib/shm_regex/README

@@ -0,0 +1,23 @@
+$Id$
+
+Wrapper functions for regcomp, regexec, regfree, and regerror using shared
+memory allocators instead of libc malloc/realloc/free. The original functions
+are prefixed with "shm_".
+
+The regular expression compiled with shm_regcomp() can be used with shm_regexec()
+simultaneously by multiple processes without locking, because regexec has its own
+internal locks. It can be later on freed with shm_regfree() when the expression
+is no longer used. Note however that
+
+1) shm_regexec allocates shared memory for the pattern buffer when it is successfully
+called for the first time.
+
+2) shm_regexec temporary allocates and deallocates memory for storing the registers
+for the pmatch array runtime if nmatch and pmatch parameters are not 0. This is
+done also in shared memory, therefore use the shared memory wrappers for
+regular expression based search-and-replace only if really necessary.
+
+See 'man regex' for the usage and parameters of the functions.
+
+Supported only with GNU C library.
+

+ 129 - 0
lib/shm_regex/shm_regex.c

@@ -0,0 +1,129 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2009 iptelorg GmbH
+ *
+ * This file is part of ser, a free SIP server.
+ *
+ * ser 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
+ *
+ * For a license to use the ser software under conditions
+ * other than those described here, or to purchase support for this
+ * software, please contact iptel.org by e-mail at the following addresses:
+ *    [email protected]
+ *
+ * ser 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * History
+ * -------
+ *  2009-04-03	Initial version (Miklos)
+ */
+
+#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(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;
+
+	replace_malloc_hooks();
+	ret = regcomp(preg, regex, cflags);
+	restore_malloc_hooks();
+
+	return ret;
+}
+
+void shm_regfree(regex_t *preg)
+{
+	malloc_hook_t	*orig_malloc_hook;
+	realloc_hook_t	*orig_realloc_hook;
+	free_hook_t	*orig_free_hook;
+
+	replace_malloc_hooks();
+	regfree(preg);
+	restore_malloc_hooks();
+}
+
+int shm_regexec(const 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)
+	 */
+	replace_malloc_hooks();
+	ret = regexec(preg, string, nmatch,
+			pmatch, eflags);
+	restore_malloc_hooks();
+	
+	return ret;
+}
+

+ 45 - 0
lib/shm_regex/shm_regex.h

@@ -0,0 +1,45 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2009 iptelorg GmbH
+ *
+ * This file is part of ser, a free SIP server.
+ *
+ * ser 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
+ *
+ * For a license to use the ser software under conditions
+ * other than those described here, or to purchase support for this
+ * software, please contact iptel.org by e-mail at the following addresses:
+ *    [email protected]
+ *
+ * ser 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * History
+ * -------
+ *  2009-04-03	Initial version (Miklos)
+ */
+
+#ifndef _SHM_REGEX_H
+#define _SHM_REGEX_H
+
+#include <sys/types.h>
+#include <regex.h>
+
+int shm_regcomp(regex_t *preg, const char *regex, int cflags);
+void shm_regfree(regex_t *preg);
+int shm_regexec(const regex_t *preg, const char *string, size_t nmatch,
+                   regmatch_t pmatch[], int eflags);
+
+#define shm_regerror	regerror
+
+#endif /* _SHM_REGEX_H */