diff options
| author | Rich Felker <dalias@aerifal.cx> | 2011-02-12 00:22:29 -0500 | 
|---|---|---|
| committer | Rich Felker <dalias@aerifal.cx> | 2011-02-12 00:22:29 -0500 | 
| commit | 0b44a0315b47dd8eced9f3b7f31580cf14bbfc01 (patch) | |
| tree | 6eaef0d8a720fa3da580de87b647fff796fe80b3 /src/env | |
| download | musl-0b44a0315b47dd8eced9f3b7f31580cf14bbfc01.tar.gz | |
initial check-in, version 0.5.0v0.5.0
Diffstat (limited to 'src/env')
| -rw-r--r-- | src/env/__environ.c | 7 | ||||
| -rw-r--r-- | src/env/__libc_start_main.c | 26 | ||||
| -rw-r--r-- | src/env/clearenv.c | 9 | ||||
| -rw-r--r-- | src/env/getenv.c | 14 | ||||
| -rw-r--r-- | src/env/putenv.c | 59 | ||||
| -rw-r--r-- | src/env/setenv.c | 31 | ||||
| -rw-r--r-- | src/env/unsetenv.c | 32 | 
7 files changed, 178 insertions, 0 deletions
diff --git a/src/env/__environ.c b/src/env/__environ.c new file mode 100644 index 00000000..d7bd5e50 --- /dev/null +++ b/src/env/__environ.c @@ -0,0 +1,7 @@ +#include "libc.h" + +#undef environ +char **___environ = 0; +weak_alias(___environ, __environ); +weak_alias(___environ, _environ); +weak_alias(___environ, environ); diff --git a/src/env/__libc_start_main.c b/src/env/__libc_start_main.c new file mode 100644 index 00000000..70af77b5 --- /dev/null +++ b/src/env/__libc_start_main.c @@ -0,0 +1,26 @@ +#include "libc.h" + +/* Any use of __environ/environ will override this symbol. */ +char **__dummy_environ = (void *)-1; +weak_alias(__dummy_environ, ___environ); + +int __libc_start_main( +	int (*main)(int, char **, char **), int argc, char **argv, +	int (*init)(int, char **, char **), void (*fini)(void), +	void (*ldso_fini)(void)) +{ +	/* Save the environment if it may be used by libc/application */ +	char **envp = argv+argc+1; +	if (___environ != (void *)-1) ___environ = envp; + +	/* Avoid writing 0 and triggering unnecessary COW */ +	if (ldso_fini) libc.ldso_fini = ldso_fini; +	if (fini) libc.fini = fini; + +	/* Execute constructors (static) linked into the application */ +	if (init) init(argc, argv, envp); + +	/* Pass control to to application */ +	exit(main(argc, argv, envp)); +	return 0; +} diff --git a/src/env/clearenv.c b/src/env/clearenv.c new file mode 100644 index 00000000..a2475ce7 --- /dev/null +++ b/src/env/clearenv.c @@ -0,0 +1,9 @@ +#include <stdlib.h> + +extern char **__environ; + +int clearenv() +{ +	__environ[0] = 0; +	return 0; +} diff --git a/src/env/getenv.c b/src/env/getenv.c new file mode 100644 index 00000000..00c1bce0 --- /dev/null +++ b/src/env/getenv.c @@ -0,0 +1,14 @@ +#include <stdlib.h> +#include <string.h> +#include "libc.h" + +char *getenv(const char *name) +{ +	int i; +	size_t l = strlen(name); +	if (!__environ || !*name || strchr(name, '=')) return NULL; +	for (i=0; __environ[i] && (strncmp(name, __environ[i], l) +		|| __environ[i][l] != '='); i++); +	if (__environ[i]) return __environ[i] + l+1; +	return NULL; +} diff --git a/src/env/putenv.c b/src/env/putenv.c new file mode 100644 index 00000000..181a4181 --- /dev/null +++ b/src/env/putenv.c @@ -0,0 +1,59 @@ +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <stdio.h> + +extern char **__environ; +char **__env_map; + +int __putenv(char *s, int a) +{ +	int i=0, j=0; +	char *end = strchr(s, '='); +	size_t l = end-s+1; +	char **newenv = 0; +	char **newmap = 0; +	static char **oldenv; +	 +	if (!end || l == 1) return -1; +	for (; __environ[i] && memcmp(s, __environ[i], l); i++); +	if (a) { +		if (!__env_map) { +			__env_map = calloc(2, sizeof(char *)); +			if (__env_map) __env_map[0] = s; +		} else { +			for (; __env_map[j] && __env_map[j] != __environ[i]; j++); +			if (!__env_map[j]) { +				newmap = realloc(__env_map, sizeof(char *)*(j+2)); +				if (newmap) { +					__env_map = newmap; +					__env_map[j] = s; +					__env_map[j+1] = NULL; +				} +			} else { +				free(__env_map[j]); +			} +		} +	} +	if (!__environ[i]) { +		newenv = malloc(sizeof(char *)*(i+2)); +		if (!newenv) { +			if (a && __env_map) __env_map[j] = 0; +			return -1; +		} +		memcpy(newenv, __environ, sizeof(char *)*i); +		newenv[i] = s; +		newenv[i+1] = 0; +		__environ = newenv; +		free(oldenv); +		oldenv = __environ; +	} + +	__environ[i] = s; +	return 0; +} + +int putenv(char *s) +{ +	return __putenv(s, 0); +} diff --git a/src/env/setenv.c b/src/env/setenv.c new file mode 100644 index 00000000..03e165c8 --- /dev/null +++ b/src/env/setenv.c @@ -0,0 +1,31 @@ +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +int __putenv(char *s, int a); + +int setenv(const char *var, const char *value, int overwrite) +{ +	char *s; +	int l1, l2; + +	if (strchr(var, '=')) { +		errno = EINVAL; +		return -1; +	} +	if (!overwrite && getenv(var)) return 0; + +	l1 = strlen(var); +	l2 = strlen(value); +	s = malloc(l1+l2+2); +	memcpy(s, var, l1); +	s[l1] = '='; +	memcpy(s+l1+1, value, l2); +	s[l1+l2+1] = 0; +	if (__putenv(s, 1)) { +		free(s); +		errno = ENOMEM; +		return -1; +	} +	return 0; +} diff --git a/src/env/unsetenv.c b/src/env/unsetenv.c new file mode 100644 index 00000000..7493d970 --- /dev/null +++ b/src/env/unsetenv.c @@ -0,0 +1,32 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +extern char **__environ; +extern char **__env_map; + +int unsetenv(const char *name) +{ +	int i, j; +	size_t l = strlen(name); + +	if (!*name || strchr(name, '=')) { +		errno = EINVAL; +		return -1; +	} +again: +	for (i=0; __environ[i] && (memcmp(name, __environ[i], l) || __environ[i][l] != '='); i++); +	if (__environ[i]) { +		if (__env_map) { +			for (j=0; __env_map[j] && __env_map[j] != __environ[i]; j++); +			free (__env_map[j]); +			for (; __env_map[j]; j++) +				__env_map[j] = __env_map[j+1]; +		} +		for (; __environ[i]; i++) +			__environ[i] = __environ[i+1]; +		goto again; +	} +	return 0; +}  | 
