/* * 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 #include extern char **environ; extern char *GC_malloc(); extern char *GC_realloc(); /* extern */ char **XR_environ; extern char *XR_findenv(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_environ; *p; ++p ) if ( ! strncmp(*p, name, len) ) if ( *(c = *p + len) == '=' ) { *offset = p - XR_environ; 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_findenv(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_environ, 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_findenv(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_environ, cnt = 0; *p; ++p, ++cnt ); if ( alloced ) { /* just increase size */ XR_environ = (char **)GC_realloc((char *)XR_environ, (u_int)(sizeof(char *) * (cnt + 2))); if ( ! XR_environ ) 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_environ, p, cnt * sizeof(char *)); XR_environ = p; } XR_environ[cnt + 1] = NULL; offset = cnt; } for ( c = name; *c && *c != '='; ++c ); /* no `=' in name */ if ( ! (XR_environ[offset] = GC_malloc((u_int)((int)(c - name) + l_value + 2))) ) return(-1); /* name + `=' + value */ for ( c = XR_environ[offset]; (*c = *name++) && *c != '='; ++c ); for ( *c++ = '='; *c++ = *value++; ); return(0); } extern void XR_unsetenv(name) char *name; { /* * Delete environmental variable "name" * - alters XR_environ, should be monitor locked! */ register char **p; int offset; while ( XR_findenv(name, &offset) ) /* if set multiple times */ for (p = &XR_environ[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_environ = environ; ok = XR_setenv("XR_environ", "TRUE", 1); } /* eof */