fixup environ handling

This commit is contained in:
K. Lange 2018-08-14 14:39:48 +09:00
parent 320a8c55ee
commit 64ae8d07bd
2 changed files with 53 additions and 34 deletions

View File

@ -1,5 +1,6 @@
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <stdlib.h>
#include <syscall.h> #include <syscall.h>
#include <syscall_nums.h> #include <syscall_nums.h>
@ -77,6 +78,44 @@ static void _libc_init(void) {
break; break;
} }
} }
if (!environ) {
environ = malloc(sizeof(char *) * 4);
environ[0] = NULL;
environ[1] = NULL;
environ[2] = NULL;
environ[3] = NULL;
_environ_size = 4;
} else {
/* Find actual size */
int size = 0;
char ** tmp = environ;
while (*tmp) {
size++;
tmp++;
}
if (size < 4) {
_environ_size = 4;
} else {
/* Multiply by two */
_environ_size = size * 2;
}
char ** new_environ = malloc(sizeof(char*) * _environ_size);
int i = 0;
while (i < _environ_size && environ[i]) {
new_environ[i] = environ[i];
i++;
}
while (i < _environ_size) {
new_environ[i] = NULL;
i++;
}
environ = new_environ;
}
_argv_0 = __get_argv()[0]; _argv_0 = __get_argv()[0];
} }

View File

@ -15,34 +15,6 @@ static int why_no_strnstr(char * a, char * b, int n) {
} }
int putenv(char * string) { int putenv(char * string) {
if (_environ_size == 0) {
/* Find actual size */
int size = 0;
char ** tmp = environ;
while (*tmp) {
size++;
tmp++;
}
/* Multiply by two */
_environ_size = size * 2;
char ** new_environ = malloc(sizeof(char*) * _environ_size);
int i = 0;
while (environ[i]) {
new_environ[i] = environ[i];
i++;
}
while (i < _environ_size) {
new_environ[i] = NULL;
i++;
}
environ = new_environ;
}
char name[strlen(string)]; char name[strlen(string)];
strcpy(name, string); strcpy(name, string);
char * c = strchr(name, '='); char * c = strchr(name, '=');
@ -54,19 +26,27 @@ int putenv(char * string) {
int s = strlen(name); int s = strlen(name);
int i; int i;
for (i = 0; environ[i]; ++i) { for (i = 0; i < (_environ_size - 1) && environ[i]; ++i) {
if (!why_no_strnstr(name, environ[i], s)) { if (!why_no_strnstr(name, environ[i], s)) {
environ[i] = string; environ[i] = string;
return 0; return 0;
} }
} }
/* Not found */ /* Not found */
if (i >= _environ_size) { if (i == _environ_size - 1) {
environ = realloc(environ, _environ_size * 2); int _new_environ_size = _environ_size * 2;
for (int i = _environ_size; i < _environ_size * 2; ++i) { char ** new_environ = malloc(sizeof(char*) * _new_environ_size);
environ[i] = NULL; int j = 0;
while (j < _new_environ_size && environ[j]) {
new_environ[j] = environ[j];
j++;
} }
_environ_size *= 2; while (j < _new_environ_size) {
new_environ[j] = NULL;
j++;
}
_environ_size = _new_environ_size;
environ = new_environ;
} }
environ[i] = string; environ[i] = string;