Browse Source

setenv.c: further code shrink

    text           data     bss     dec     hex filename
-    672              0       4     676     2a4 libc/stdlib/setenv.o
+    546              0       4     550     226 libc/stdlib/setenv.o
Denis Vlasenko 16 years ago
parent
commit
308bd3f798
1 changed files with 26 additions and 36 deletions
  1. 26 36
      libc/stdlib/setenv.c

+ 26 - 36
libc/stdlib/setenv.c

@@ -46,17 +46,14 @@ static char **last_environ;
    is then placed in the environment, while the argument of `putenv'
    is then placed in the environment, while the argument of `putenv'
    must be used directly.  This is all complicated by the fact that we try
    must be used directly.  This is all complicated by the fact that we try
    to reuse values once generated for a `setenv' call since we can never
    to reuse values once generated for a `setenv' call since we can never
-   free the strings.  */
+   free the strings. [in uclibc, we do not]  */
-int __add_to_environ(const char *name, const char *value,
+static int __add_to_environ(const char *name, const char *value,
-		char *combined, int replace) attribute_hidden;
+ 		int replace)
-int __add_to_environ(const char *name, const char *value,
-		char *combined, int replace)
 {
 {
 	register char **ep;
 	register char **ep;
 	register size_t size;
 	register size_t size;
 	/* name may come from putenv() and thus may contain "=VAL" part */
 	/* name may come from putenv() and thus may contain "=VAL" part */
 	const size_t namelen = strchrnul(name, '=') - name;
 	const size_t namelen = strchrnul(name, '=') - name;
-	const size_t vallen = value != NULL ? strlen(value) + 1 : 0;
 	int rv = -1;
 	int rv = -1;
 
 
 	__UCLIBC_MUTEX_LOCK(mylock);
 	__UCLIBC_MUTEX_LOCK(mylock);
@@ -89,38 +86,30 @@ int __add_to_environ(const char *name, const char *value,
 		}
 		}
 		last_environ = __environ = new_environ;
 		last_environ = __environ = new_environ;
 
 
-		if (combined != NULL) {
+		ep = &new_environ[size];
-			/* If the whole "VAR=VAL" is given, add it.  */
+		/* Ensure env is NULL terminated in case malloc below fails */
-			/* We must not add the string to the search tree
+		ep[0] = NULL;
-			 * since it belongs to the user.
+		ep[1] = NULL;
-			 * [glibc comment, uclibc doesnt track ptrs]  */
+		replace = 1;
-			new_environ[size] = combined;
+	}
-		} else {
+
-			/* Build new "VAR=VAL" string.  */
+	if (replace) {
-			new_environ[size] = malloc(namelen + 1 + vallen);
+		char *var_val = (char*) name;
-			if (new_environ[size] == NULL) {
+
-				__set_errno(ENOMEM);
+		/* Build VAR=VAL if we called by setenv, not putenv.  */
-				goto DONE;
+		if (value != NULL) {
-			}
+			const size_t vallen = strlen(value) + 1;
-			memcpy(new_environ[size], name, namelen);
-			new_environ[size][namelen] = '=';
-			memcpy(&new_environ[size][namelen + 1], value, vallen);
-		}
-		new_environ[size + 1] = NULL;
 
 
-	} else if (replace) {
+			var_val = malloc(namelen + 1 + vallen);
-		/* Build the name if needed.  */
+			if (var_val == NULL) {
-		if (combined == NULL) {
-			combined = malloc(namelen + 1 + vallen);
-			if (combined == NULL) {
 				__set_errno(ENOMEM);
 				__set_errno(ENOMEM);
 				goto DONE;
 				goto DONE;
 			}
 			}
-			memcpy(combined, name, namelen);
+			memcpy(var_val, name, namelen);
-			combined[namelen] = '=';
+			var_val[namelen] = '=';
-			memcpy(&combined[namelen + 1], value, vallen);
+			memcpy(&var_val[namelen + 1], value, vallen);
 		}
 		}
-		*ep = combined;
+		*ep = var_val;
 	}
 	}
 
 
 	rv = 0;
 	rv = 0;
@@ -133,7 +122,8 @@ int __add_to_environ(const char *name, const char *value,
 /* libc_hidden_proto(setenv) */
 /* libc_hidden_proto(setenv) */
 int setenv(const char *name, const char *value, int replace)
 int setenv(const char *name, const char *value, int replace)
 {
 {
-	return __add_to_environ(name, value, NULL, replace);
+	/* NB: setenv("VAR", NULL, 1) inserts "VAR=" string */
+	return __add_to_environ(name, value ? value : "", replace);
 }
 }
 libc_hidden_def(setenv)
 libc_hidden_def(setenv)
 
 
@@ -183,7 +173,7 @@ int clearenv(void)
 	 * and is safe to free().  */
 	 * and is safe to free().  */
 	free(last_environ);
 	free(last_environ);
 	last_environ = NULL;
 	last_environ = NULL;
-	/* Clear the environment pointer removes the whole environment.  */
+	/* Clearing environ removes the whole environment.  */
 	__environ = NULL;
 	__environ = NULL;
 	__UCLIBC_MUTEX_UNLOCK(mylock);
 	__UCLIBC_MUTEX_UNLOCK(mylock);
 	return 0;
 	return 0;
@@ -193,7 +183,7 @@ int clearenv(void)
 int putenv(char *string)
 int putenv(char *string)
 {
 {
 	if (strchr(string, '=') != NULL) {
 	if (strchr(string, '=') != NULL) {
-		return __add_to_environ(string, NULL, string, 1);
+		return __add_to_environ(string, NULL, 1);
 	}
 	}
 	return unsetenv(string);
 	return unsetenv(string);
 }
 }