about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2005-07-18 02:51:43 +0000
committerRoland McGrath <roland@gnu.org>2005-07-18 02:51:43 +0000
commit06d321f70e2810122e1a3a5a9ab4777ad2292840 (patch)
tree319bec55bcdf43fb8fba11b4571acd5d73640432
parentd122043d22b001cff2d2457bd03c82fdadf5de1d (diff)
downloadglibc-06d321f70e2810122e1a3a5a9ab4777ad2292840.tar.gz
glibc-06d321f70e2810122e1a3a5a9ab4777ad2292840.tar.xz
glibc-06d321f70e2810122e1a3a5a9ab4777ad2292840.zip
2005-05-06 Jakub Jelinek <jakub@redhat.com>
	[BZ #934]
	* posix/regex_internal.h: Include bits/libc-lock.h or define dummy
	__libc_lock_* macros if not _LIBC.
	(struct re_dfa_t): Add lock.
	* posix/regcomp.c (re_compile_internal): Add __libc_lock_init.
	* posix/regexec.c (regexec, re_search_stub): Add locking.
-rw-r--r--posix/regcomp.c2
-rw-r--r--posix/regex_internal.h9
-rw-r--r--posix/regexec.c14
3 files changed, 24 insertions, 1 deletions
diff --git a/posix/regcomp.c b/posix/regcomp.c
index 72bf187b14..2100bb5420 100644
--- a/posix/regcomp.c
+++ b/posix/regcomp.c
@@ -779,6 +779,8 @@ re_compile_internal (preg, pattern, length, syntax)
     }
   preg->used = sizeof (re_dfa_t);
 
+  __libc_lock_init (dfa->lock);
+
   err = init_dfa (dfa, length);
   if (BE (err != REG_NOERROR, 0))
     {
diff --git a/posix/regex_internal.h b/posix/regex_internal.h
index 18865a7266..e48627766f 100644
--- a/posix/regex_internal.h
+++ b/posix/regex_internal.h
@@ -39,6 +39,14 @@
 #if defined HAVE_WCTYPE_H || defined _LIBC
 # include <wctype.h>
 #endif /* HAVE_WCTYPE_H || _LIBC */
+#if defined _LIBC
+# include <bits/libc-lock.h>
+#else
+# define __libc_lock_define(CLASS,NAME)
+# define __libc_lock_init(NAME) do { } while (0)
+# define __libc_lock_lock(NAME) do { } while (0)
+# define __libc_lock_unlock(NAME) do { } while (0)
+#endif
 
 /* In case that the system doesn't have isblank().  */
 #if !defined _LIBC && !defined HAVE_ISBLANK && !defined isblank
@@ -650,6 +658,7 @@ struct re_dfa_t
 #ifdef DEBUG
   char* re_str;
 #endif
+  __libc_lock_define (, lock)
 };
 
 #ifndef RE_NO_INTERNAL_PROTOTYPES
diff --git a/posix/regexec.c b/posix/regexec.c
index 91b48dd4a2..021fcf4060 100644
--- a/posix/regexec.c
+++ b/posix/regexec.c
@@ -219,6 +219,7 @@ regexec (preg, string, nmatch, pmatch, eflags)
 {
   reg_errcode_t err;
   int start, length;
+  re_dfa_t *dfa = (re_dfa_t *)preg->buffer;
 
   if (eflags & ~(REG_NOTBOL | REG_NOTEOL | REG_STARTEND))
     return REG_BADPAT;
@@ -233,12 +234,15 @@ regexec (preg, string, nmatch, pmatch, eflags)
       start = 0;
       length = strlen (string);
     }
+
+  __libc_lock_lock (dfa->lock);
   if (preg->no_sub)
     err = re_search_internal (preg, string, length, start, length - start,
 			      length, 0, NULL, eflags);
   else
     err = re_search_internal (preg, string, length, start, length - start,
 			      length, nmatch, pmatch, eflags);
+  __libc_lock_unlock (dfa->lock);
   return err != REG_NOERROR;
 }
 
@@ -402,6 +406,7 @@ re_search_stub (bufp, string, length, start, range, stop, regs, ret_len)
   regmatch_t *pmatch;
   int nregs, rval;
   int eflags = 0;
+  re_dfa_t *dfa = (re_dfa_t *)bufp->buffer;
 
   /* Check for out-of-range.  */
   if (BE (start < 0 || start > length, 0))
@@ -411,6 +416,8 @@ re_search_stub (bufp, string, length, start, range, stop, regs, ret_len)
   else if (BE (start + range < 0, 0))
     range = -start;
 
+  __libc_lock_lock (dfa->lock);
+
   eflags |= (bufp->not_bol) ? REG_NOTBOL : 0;
   eflags |= (bufp->not_eol) ? REG_NOTEOL : 0;
 
@@ -439,7 +446,10 @@ re_search_stub (bufp, string, length, start, range, stop, regs, ret_len)
     nregs = bufp->re_nsub + 1;
   pmatch = re_malloc (regmatch_t, nregs);
   if (BE (pmatch == NULL, 0))
-    return -2;
+    {
+      rval = -2;
+      goto out;
+    }
 
   result = re_search_internal (bufp, string, length, start, range, stop,
 			       nregs, pmatch, eflags);
@@ -469,6 +479,8 @@ re_search_stub (bufp, string, length, start, range, stop, regs, ret_len)
 	rval = pmatch[0].rm_so;
     }
   re_free (pmatch);
+ out:
+  __libc_lock_unlock (dfa->lock);
   return rval;
 }