/*
* XREnvironImpl.c
* created, February 9, 1989 8:31:34 pm PST
* bj, October 27, 1989 5:36:45 pm PDT
* eduardo, November 20, 1989 11:43:03 am PST
* Willie-Sue Orr, August 9, 1991 1:59:54 pm PDT
*/
#include <stdio.h>
#include <sys/types.h>
extern char **environ;
extern char *GC←malloc();
extern char *GC←realloc();
/* extern */ char **XR𡤎nviron;
extern
char *
XR𡤏indenv(name, offset)
register
char *name;
int *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.
* - result is pointer into string in env, treat as readonly!
*/
register int len;
register char **p, *c;
for ( c = name, len = 0; *c && *c != '='; ++c, ++len );
for ( p =
XR𡤎nviron; *p; ++p )
if ( ! strncmp(*p, name, len) )
if ( *(c = *p + len) == '=' ) { *offset = p - XR𡤎nviron; return(++c); }
return(NULL);
}
extern
char *
XR←getenv(name)
char *name; {
/*
* Returns ptr to value associated with name, if any, else NULL
* - result is pointer into string in env, treat as readonly!
* - GC←malloc & copy would protect us from clients!
*/
int offset;
return(XR𡤏indenv(name, &offset));
}
extern
int
XR←setenv(name, value, rewrite)
register
char *name, *value;
int rewrite; {
/*
* Set the value of the environmental variable "name" to be "value".
* If rewrite is set, replace any current value.
* - always GC←malloc new storage! - enforces readonly semantics invariant!
* - alters XR𡤎nviron, should be monitor locked!
* make XR←setenv static instead of extern, to catches uses - this code may not work
* XR←setenv is used in LoaderUtilsImpl.c, so have to provide it, so make extern again
*/
static int alloced; /* if allocated space before */
register char *c;
int l←value, offset;
if (*value == '=') ++value; /* no `=' in value */
l←value = strlen(value);
if ( (c = XR𡤏indenv(name, &offset)) )
{ /* find if already exists */
if ( ! rewrite ) return(0);
/*
if ( strlen(c) >= l←value ) { - don't bother, always GC←malloc new storage!
old larger; copy over
while ( *c++ = *value++ );
return(0);
} */
}
else { /* create new slot */
register int cnt;
register char **p;
for ( p = XR𡤎nviron, cnt = 0; *p; ++p, ++cnt );
if ( alloced )
{ /* just increase size */
XR𡤎nviron = (char **)GC←realloc((char *)XR𡤎nviron,
(u←int)(sizeof(char *) * (cnt + 2)));
if ( ! XR𡤎nviron ) return(-1);
}
else { /* get new space */
alloced = 1; /* copy old entries into it */
p = (char **)GC←malloc((u←int)(sizeof(char *) *(cnt + 2)));
if ( ! p ) return(-1);
bcopy(XR𡤎nviron, p, cnt * sizeof(char *));
XR𡤎nviron = p;
}
XR𡤎nviron[cnt + 1] = NULL;
offset = cnt;
}
for ( c = name; *c && *c != '='; ++c ); /* no `=' in name */
if ( ! (XR𡤎nviron[offset] = GC←malloc((u←int)((int)(c - name) + l←value + 2))) ) return(-1);
/* name + `=' + value */
for ( c = XR𡤎nviron[offset]; (*c = *name++) && *c != '='; ++c );
for ( *c++ = '='; *c++ = *value++; );
return(0);
}
extern
void
XR←unsetenv(name)
char *name; {
/*
* Delete environmental variable "name"
* - alters XR𡤎nviron, should be monitor locked!
*/
register char **p;
int offset;
while ( XR𡤏indenv(name, &offset) ) /* if set multiple times */
for (p = &
XR𡤎nviron[offset]; ; ++p)
if ( ! (*p = *(p + 1)) ) break;
}
extern
void
XR←install←XREnvironImpl() { /*
PRE-start trap */
};
extern
void
XR←run←XREnvironImpl() { /* start trap */
/* little ditty to get it "out of the global frame" for threads*/
int ok;
XR𡤎nviron = environ;
ok = XR←setenv("XR𡤎nviron", "TRUE", 1);
}
/* eof */