Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 130701790bf2d95e902edf16031ff596 > files > 163

autofs-5.0.1-0.rc2.164.el5_8.src.rpm

diff --git a/CHANGELOG b/CHANGELOG
index 04d8159..4163c43 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -27,6 +27,7 @@
   occurance).
 - allow additional common LDAP attributes in map dn.
 - deal with changed semantics of mkdir in 2.6.19.
+- fix macro table locking.
 
 1/9/2006 autofs-5.0.1 rc2
 -------------------------
diff --git a/include/macros.h b/include/macros.h
index 96fda3b..a73a4a7 100644
--- a/include/macros.h
+++ b/include/macros.h
@@ -29,6 +29,8 @@ void macro_init(void);
 int macro_is_systemvar(const char *str, int len);
 int macro_global_addvar(const char *str, int len, const char *value);
 int macro_parse_globalvar(const char *define);
+void macro_lock(void);
+void macro_unlock(void);
 struct substvar *
 macro_addvar(struct substvar *table, const char *str, int len, const char *value);
 void macro_global_removevar(const char *str, int len);
diff --git a/lib/macros.c b/lib/macros.c
index a8703c8..936ae06 100644
--- a/lib/macros.c
+++ b/lib/macros.c
@@ -38,6 +38,7 @@ static struct substvar
 static struct substvar *system_table = &sv_osvers;
 
 static pthread_mutex_t table_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t macro_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 void dump_table(struct substvar *table)
 {
@@ -76,7 +77,7 @@ void macro_init(void)
 
 int macro_is_systemvar(const char *str, int len)
 {
-	struct substvar *sv = system_table;
+	struct substvar *sv;
 	int found = 0;
 	int status;
 
@@ -84,6 +85,8 @@ int macro_is_systemvar(const char *str, 
 	if (status)
 		fatal(status);
 
+	sv = system_table;
+
 	while (sv) {
 		if (!strncmp(str, sv->def, len) && sv->def[len] == '\0') {
 			found = 1;
@@ -101,13 +104,15 @@ int macro_is_systemvar(const char *str, 
 
 int macro_global_addvar(const char *str, int len, const char *value)
 {
-	struct substvar *sv = system_table;
+	struct substvar *sv;
 	int status, ret = 0;
 
 	status = pthread_mutex_lock(&table_mutex);
 	if (status)
 		fatal(status);
 
+	sv = system_table;
+
 	while (sv) {
 		if (!strncmp(str, sv->def, len) && sv->def[len] == '\0')
 			break;
@@ -184,15 +189,24 @@ int macro_parse_globalvar(const char *de
 	return macro_global_addvar(buf, strlen(buf), value);
 }
 
-struct substvar *
-macro_addvar(struct substvar *table, const char *str, int len, const char *value)
+void macro_lock(void)
 {
-	struct substvar *lv = table;
-	int status;
+	int status = pthread_mutex_lock(&macro_mutex);
+	if (status)
+		fatal(status);
+}
 
-	status = pthread_mutex_lock(&table_mutex);
+void macro_unlock(void)
+{
+	int status = pthread_mutex_unlock(&macro_mutex);
 	if (status)
 		fatal(status);
+}
+
+struct substvar *
+macro_addvar(struct substvar *table, const char *str, int len, const char *value)
+{
+	struct substvar *lv = table;
 
 	while (lv) {
 		if (!strncmp(str, lv->def, len) && lv->def[len] == '\0')
@@ -240,9 +254,6 @@ macro_addvar(struct substvar *table, con
 		lv = new;
 	}
 done:
-	status = pthread_mutex_unlock(&table_mutex);
-	if (status)
-		fatal(status);
 
 	return lv;
 }
@@ -290,11 +301,6 @@ macro_removevar(struct substvar *table, 
 {
 	struct substvar *list, *lv;
 	struct substvar *last = NULL;
-	int status;
-
-	status = pthread_mutex_lock(&table_mutex);
-	if (status)
-		fatal(status);
 
 	lv = list = table;
 
@@ -317,26 +323,21 @@ macro_removevar(struct substvar *table, 
 		free(lv);
 	}
 
-	status = pthread_mutex_unlock(&table_mutex);
-	if (status)
-		fatal(status);
-
 	return list;
 }
 
 void macro_free_global_table(void)
 {
-	struct substvar *sv = system_table;
+	struct substvar *sv;
 	struct substvar *next;
 	int status;
 
-	if (!sv)
-		return;
-
 	status = pthread_mutex_lock(&table_mutex);
 	if (status)
 		fatal(status);
 
+	sv = system_table;
+
 	while (sv) {
 		if (sv->readonly) {
 			sv = sv->next;
@@ -351,6 +352,8 @@ void macro_free_global_table(void)
 		sv = next;
 	}
 
+	system_table = &sv_osvers;
+
 	status = pthread_mutex_unlock(&table_mutex);
 	if (status)
 		fatal(status);
@@ -362,15 +365,10 @@ void macro_free_table(struct substvar *t
 {
 	struct substvar *lv = table;
 	struct substvar *next;
-	int status;
 
 	if (!lv)
 		return;
 
-	status = pthread_mutex_lock(&table_mutex);
-	if (status)
-		fatal(status);
-
 	while (lv) {
 		next = lv->next;
 		if (lv->def)
@@ -381,10 +379,6 @@ void macro_free_table(struct substvar *t
 		lv = next;
 	}
 
-	status = pthread_mutex_unlock(&table_mutex);
-	if (status)
-		fatal(status);
-
 	return;
 }
 
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index ed374ec..9f9bf54 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -68,7 +68,9 @@ static struct parse_context default_cont
 /* Free all storage associated with this context */
 static void kill_context(struct parse_context *ctxt)
 {
+	macro_lock();
 	macro_free_table(ctxt->subst);
+	macro_unlock();
 	if (ctxt->optstr)
 		free(ctxt->optstr);
 	if (ctxt->macros)
@@ -267,9 +269,13 @@ int parse_init(int argc, const char *con
 				else
 					val = "";
 
+				macro_lock();
+
 				ctxt->subst = macro_addvar(ctxt->subst,
 							def, strlen(def), val);
 
+				macro_unlock();
+
 				/* we use 5 for the "-D", "=", "," and the null */
 				if (ctxt->macros) {
 					len = strlen(ctxt->macros) + strlen(def) + strlen(val);
@@ -914,11 +920,17 @@ int parse_mount(struct autofs_point *ap,
 		return 1;
 	}
 
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
+	macro_lock();
+
 	ctxt->subst = addstdenv(ctxt->subst);
 
 	mapent_len = expandsunent(mapent, NULL, name, ctxt->subst, slashify);
 	if (mapent_len == 0) {
 		error(ap->logopt, MODPREFIX "failed to expand map entry");
+		ctxt->subst = removestdenv(ctxt->subst);
+		macro_unlock();
+		pthread_setcancelstate(cur_state, NULL);
 		return 1;
 	}
 
@@ -926,6 +938,9 @@ int parse_mount(struct autofs_point *ap,
 	if (!pmapent) {	
 		char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
 		error(ap->logopt, MODPREFIX "alloca: %s", estr);
+		ctxt->subst = removestdenv(ctxt->subst);
+		macro_unlock();
+		pthread_setcancelstate(cur_state, NULL);
 		return 1;
 	}
 	pmapent[mapent_len] = '\0';
@@ -933,6 +948,9 @@ int parse_mount(struct autofs_point *ap,
 	expandsunent(mapent, pmapent, name, ctxt->subst, slashify);
 	ctxt->subst = removestdenv(ctxt->subst);
 
+	macro_unlock();
+	pthread_setcancelstate(cur_state, NULL);
+
 	debug(ap->logopt, MODPREFIX "expanded entry: %s", pmapent);
 
 	options = strdup(ctxt->optstr ? ctxt->optstr : "");