#include <errno.h>
#include <stdlib.h>
#include <string.h>
static char **lastenv;
int
putenv(char *str)
{
char **P, *cp;
size_t cnt = 0;
int offset = 0;
for (cp = str; *cp && *cp != '='; ++cp)
;
if (cp == str || *cp != '=') {
errno = EINVAL;
return (-1);
}
if (__findenv(str, (int)(cp - str), &offset) != NULL) {
environ[offset++] = str;
while (__findenv(str, (int)(cp - str), &offset)) {
for (P = &environ[offset];; ++P)
if (!(*P = *(P + 1)))
break;
}
return (0);
}
if (environ != NULL) {
for (P = environ; *P != NULL; P++)
;
cnt = P - environ;
}
P = reallocarray(lastenv, cnt + 2, sizeof(char *));
if (!P)
return (-1);
if (lastenv != environ && environ != NULL)
memcpy(P, environ, cnt * sizeof(char *));
lastenv = environ = P;
environ[cnt] = str;
environ[cnt + 1] = NULL;
return (0);
}
DEF_WEAK(putenv);
int
setenv(const char *name, const char *value, int rewrite)
{
char *C, **P;
const char *np;
int l_value, offset = 0;
if (!name || !*name) {
errno = EINVAL;
return (-1);
}
for (np = name; *np && *np != '='; ++np)
;
if (*np) {
errno = EINVAL;
return (-1);
}
l_value = strlen(value);
if ((C = __findenv(name, (int)(np - name), &offset)) != NULL) {
int tmpoff = offset + 1;
if (!rewrite)
return (0);
#if 0
if (strlen(C) >= l_value) {
while ((*C++ = *value++))
;
return (0);
}
#endif
while (__findenv(name, (int)(np - name), &tmpoff)) {
for (P = &environ[tmpoff];; ++P)
if (!(*P = *(P + 1)))
break;
}
} else {
size_t cnt = 0;
if (environ != NULL) {
for (P = environ; *P != NULL; P++)
;
cnt = P - environ;
}
P = reallocarray(lastenv, cnt + 2, sizeof(char *));
if (!P)
return (-1);
if (lastenv != environ && environ != NULL)
memcpy(P, environ, cnt * sizeof(char *));
lastenv = environ = P;
offset = cnt;
environ[cnt + 1] = NULL;
}
if (!(environ[offset] =
malloc((int)(np - name) + l_value + 2)))
return (-1);
for (C = environ[offset]; (*C = *name++) && *C != '='; ++C)
;
for (*C++ = '='; (*C++ = *value++); )
;
return (0);
}
DEF_WEAK(setenv);
int
unsetenv(const char *name)
{
char **P;
const char *np;
int offset = 0;
if (!name || !*name) {
errno = EINVAL;
return (-1);
}
for (np = name; *np && *np != '='; ++np)
;
if (*np) {
errno = EINVAL;
return (-1);
}
while (__findenv(name, (int)(np - name), &offset)) {
for (P = &environ[offset];; ++P)
if (!(*P = *(P + 1)))
break;
}
return (0);
}
DEF_WEAK(unsetenv);