ack/lang/cem/libcc.ansi/stdlib/setenv.c
David Given d273497077 Add some missing libc functions: setenv, unsetenv, strdup.
--HG--
rename : lang/cem/libcc.ansi/stdlib/getenv.c => lang/cem/libcc.ansi/stdlib/setenv.c
rename : lang/cem/libcc.ansi/string/strlen.c => lang/cem/libcc.ansi/string/strdup.c
extra : source : 64d6e6eec18d76bf8f3947ec5d171db94acdb282
2013-05-29 21:41:58 +01:00

88 lines
2.4 KiB
C

/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Id$ */
#include <stdlib.h>
#include <string.h>
extern char* _findenv(const char* name, int* offset);
extern char **environ;
/*
* setenv(name,value,rewrite)
* Set the value of the environmental variable "name" to be
* "value". If rewrite is set, replace any current value.
*/
int setenv(register const char* name, register const char* value, int rewrite)
{
static int alloced = 0; /* if allocated space before */
register char *C;
int l_value,
offset;
if (*value == '=') /* no `=' in value */
++value;
l_value = strlen(value);
if ((C = _findenv(name,&offset))) { /* find if already exists */
if (!rewrite)
return(0);
if (strlen(C) >= l_value) { /* old larger; copy over */
while (*C++ = *value++);
return(0);
}
}
else { /* create new slot */
register int cnt = 0;
register char **P;
if (environ)
for (P = environ;*P;++P,++cnt);
if (alloced) { /* just increase size */
environ = (char **)realloc((char *)environ,
(unsigned)(sizeof(char *) * (cnt + 2)));
if (!environ)
return(-1);
}
else { /* get new space */
alloced = 1; /* copy old entries into it */
P = (char **)malloc((unsigned)(sizeof(char *) *
(cnt + 2)));
if (!P)
return(-1);
if (environ)
bcopy(environ,P,cnt * sizeof(char *));
environ = P;
}
environ[cnt + 1] = NULL;
offset = cnt;
}
for (C = name;*C && *C != '=';++C); /* no `=' in name */
if (!(environ[offset] = /* name + `=' + value */
malloc((unsigned)((int)(C - name) + l_value + 2))))
return(-1);
for (C = environ[offset];(*C = *name++) && *C != '=';++C);
for (*C++ = '=';*C++ = *value++;);
return(0);
}
/*
* unsetenv(name) --
* Delete environmental variable "name".
*/
int
unsetenv(const char* name)
{
register char **P;
int offset;
while (_findenv(name,&offset)) /* if set multiple times */
for (P = &environ[offset];;++P)
if (!(*P = *(P + 1)))
break;
return 0;
}