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
This commit is contained in:
parent
f522aba4af
commit
d273497077
|
@ -186,6 +186,7 @@ $(call ackfile, lang/cem/libcc.ansi/stdlib/div.c)
|
|||
$(call ackfile, lang/cem/libcc.ansi/stdlib/atexit.c)
|
||||
$(call ackfile, lang/cem/libcc.ansi/stdlib/exit.c)
|
||||
$(call ackfile, lang/cem/libcc.ansi/stdlib/getenv.c)
|
||||
$(call ackfile, lang/cem/libcc.ansi/stdlib/setenv.c)
|
||||
$(call ackfile, lang/cem/libcc.ansi/stdlib/labs.c)
|
||||
$(call ackfile, lang/cem/libcc.ansi/stdlib/ldiv.c)
|
||||
$(call ackfile, lang/cem/libcc.ansi/stdlib/mblen.c)
|
||||
|
@ -238,6 +239,7 @@ $(call ackfile, lang/cem/libcc.ansi/string/strpbrk.c)
|
|||
$(call ackfile, lang/cem/libcc.ansi/string/strspn.c)
|
||||
$(call ackfile, lang/cem/libcc.ansi/string/strncmp.c)
|
||||
$(call ackfile, lang/cem/libcc.ansi/string/strxfrm.c)
|
||||
$(call ackfile, lang/cem/libcc.ansi/string/strdup.c)
|
||||
|
||||
# Time
|
||||
|
||||
|
|
|
@ -36,6 +36,9 @@ extern int atexit(void (*_func)(void));
|
|||
extern void exit(int _status);
|
||||
extern void _Exit(int _status);
|
||||
extern char* getenv(const char *_name);
|
||||
extern int setenv(const char *_name, const char *_value, int _overwrite);
|
||||
extern int unsetenv(const char *_name);
|
||||
extern int putenv(char *_string);
|
||||
extern int system(const char *_string);
|
||||
extern void* bsearch(const void *_key, const void *_base,
|
||||
size_t _nmemb, size_t _size,
|
||||
|
|
|
@ -33,5 +33,8 @@ extern char *strtok(char *_s1, const char *_s2);
|
|||
extern void *memset(void *_s, int _c, size_t _n);
|
||||
extern char *strerror(int _errnum);
|
||||
extern size_t strlen(const char *_s);
|
||||
extern char *strdup(const char *_s);
|
||||
|
||||
#define bcopy(s, d, z) memmove(d, s, z)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -10,18 +10,17 @@
|
|||
#define ENTRY_INC 10
|
||||
#define rounded(x) (((x / ENTRY_INC) + 1) * ENTRY_INC)
|
||||
|
||||
extern const char **_penvp;
|
||||
extern const char **environ; /* environ is a shadow name for _penvp */
|
||||
extern char **environ;
|
||||
|
||||
int
|
||||
putenv(char *name)
|
||||
{
|
||||
register const char **v = _penvp;
|
||||
register char **v = environ;
|
||||
register char *r;
|
||||
static int size = 0;
|
||||
/* When size != 0, it contains the number of entries in the
|
||||
* table (including the final NULL pointer). This means that the
|
||||
* last non-null entry is _penvp[size - 2].
|
||||
* last non-null entry is environ[size - 2].
|
||||
*/
|
||||
|
||||
if (!name) return 0;
|
||||
|
@ -48,11 +47,11 @@ putenv(char *name)
|
|||
}
|
||||
}
|
||||
*r = '=';
|
||||
v = _penvp;
|
||||
v = environ;
|
||||
}
|
||||
|
||||
if (!size) {
|
||||
register const char **p;
|
||||
register char **p;
|
||||
register int i = 0;
|
||||
|
||||
if (v)
|
||||
|
@ -62,18 +61,17 @@ putenv(char *name)
|
|||
if (!(v = malloc(rounded(i) * sizeof(char **))))
|
||||
return 1;
|
||||
size = i;
|
||||
p = _penvp;
|
||||
_penvp = v;
|
||||
p = environ;
|
||||
environ = v;
|
||||
while (*v++ = *p++); /* copy the environment */
|
||||
v = _penvp;
|
||||
v = environ;
|
||||
} else if (!(size % ENTRY_INC)) {
|
||||
if (!(v = realloc(_penvp, rounded(size) * sizeof(char **))))
|
||||
if (!(v = realloc(environ, rounded(size) * sizeof(char **))))
|
||||
return 1;
|
||||
_penvp = v;
|
||||
environ = v;
|
||||
}
|
||||
v[size - 1] = name;
|
||||
v[size] = NULL;
|
||||
size++;
|
||||
environ = _penvp;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -5,23 +5,47 @@
|
|||
/* $Id$ */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
char *
|
||||
getenv(const char *name)
|
||||
extern char* _findenv(const char* name, int* offset);
|
||||
|
||||
/*
|
||||
* getenv(name) --
|
||||
* Returns ptr to value associated with name, if any, else NULL.
|
||||
*/
|
||||
char* getenv(const char* name)
|
||||
{
|
||||
register char **v = environ;
|
||||
register const char *p, *q;
|
||||
int offset;
|
||||
|
||||
if (v == NULL || name == NULL)
|
||||
return (char *)NULL;
|
||||
while ((p = *v++) != NULL) {
|
||||
q = name;
|
||||
while (*q && (*q == *p++))
|
||||
q++;
|
||||
if (*q || (*p != '='))
|
||||
continue;
|
||||
return (char *)p + 1;
|
||||
}
|
||||
return (char *)NULL;
|
||||
return(_findenv(name,&offset));
|
||||
}
|
||||
|
||||
/*
|
||||
* _findenv(name,offset) --
|
||||
* Returns pointer to value associated with name, if any, else NULL.
|
||||
* Sets offset to be the offset of the name/value combination in the
|
||||
* environmental array, for use by setenv(3) and unsetenv(3).
|
||||
* Explicitly removes '=' in argument name.
|
||||
*
|
||||
* This routine *should* be a static; don't use it.
|
||||
*/
|
||||
char* _findenv(register const char* name, int* offset)
|
||||
{
|
||||
extern char **environ;
|
||||
register int len;
|
||||
register char **P;
|
||||
register const char *C;
|
||||
|
||||
if (!environ)
|
||||
return NULL;
|
||||
|
||||
for (C = name,len = 0;*C && *C != '=';++C,++len);
|
||||
for (P = environ;*P;++P)
|
||||
if (!strncmp(*P,name,len))
|
||||
if (*(C = *P + len) == '=') {
|
||||
*offset = P - environ;
|
||||
return (char*)(++C);
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
|
87
lang/cem/libcc.ansi/stdlib/setenv.c
Normal file
87
lang/cem/libcc.ansi/stdlib/setenv.c
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* (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;
|
||||
}
|
||||
|
17
lang/cem/libcc.ansi/string/strdup.c
Normal file
17
lang/cem/libcc.ansi/string/strdup.c
Normal file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* (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 <string.h>
|
||||
|
||||
char*
|
||||
strdup(const char *s)
|
||||
{
|
||||
int len = strlen(s);
|
||||
char *p = malloc(len+1);
|
||||
if (p)
|
||||
memcpy(p, s, len+1);
|
||||
return p;
|
||||
}
|
Loading…
Reference in a new issue