Goto sanos source index
//
// environ.c
//
// Environment variables
//
// Copyright (C) 2002 Michael Ringgaard. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the project nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
#include <os.h>
#include <string.h>
#include <inifile.h>
extern struct critsect env_lock;
//
// The environment block is a null terminated array of strings
// of the form NAME=VALUE.
//
char ***_environ()
{
return &gettib()->proc->env;
}
static char *findenv(char **env, const char *name, int *offset)
{
int i;
int len;
if (!env || !name) return NULL;
len = strlen(name);
for (i = 0; env[i]; i++)
{
if (strncmp(env[i], name, len) == 0 && env[i][len] == '=')
{
if (offset) *offset = i;
return env[i] + len + 1;
}
}
return NULL;
}
char **copyenv(char **env)
{
int n;
char **newenv;
if (!env) return NULL;
enter(&env_lock);
for (n = 0; env[n]; n++);
newenv = (char **) malloc((n + 1) * sizeof(char *));
if (newenv)
{
newenv[n] = NULL;
for (n = 0; env[n]; n++) newenv[n] = strdup(env[n]);
}
leave(&env_lock);
return newenv;
}
void freeenv(char **env)
{
int n;
if (!env) return;
enter(&env_lock);
for (n = 0; env[n]; n++) free(env[n]);
free(env);
leave(&env_lock);
}
char **initenv(struct section *sect)
{
int n;
char **env;
struct property *prop;
if (!sect) return NULL;
n = get_section_size(sect);
env = (char **) malloc((n + 1) * sizeof(char *));
if (!env) return NULL;
env[n] = NULL;
for (n = 0, prop = sect->properties; prop; n++, prop = prop->next)
{
int len = strlen(prop->name) + 1;
if (prop->value) len += strlen(prop->value);
env[n] = (char *) malloc(len + 1);
if (env[n])
{
strcpy(env[n], prop->name);
strcat(env[n], "=");
if (prop->value) strcat(env[n], prop->value);
}
}
return env;
}
char *getenv(const char *name)
{
char *value;
enter(&env_lock);
value = findenv(environ, name, NULL);
leave(&env_lock);
return value;
}
int setenv(const char *name, const char *value, int rewrite)
{
char **env;
char *p;
char *buf;
int offset;
size_t len;
if (!name)
{
errno = EINVAL;
return 0;
}
for (p = (char *) name; *p && *p != '='; p++);
if (*p == '=')
{
errno = EINVAL;
return 0;
}
if (*value == '=') value++;
enter(&env_lock);
env = environ;
len = strlen(value);
if ((p = findenv(env, name, &offset)))
{
if (!rewrite)
{
leave(&env_lock);
return 0;
}
if (strlen(p) >= len)
{
// Old value is larger; copy over
while ((*p++ = *value++) != 0);
leave(&env_lock);
return 0;
}
}
else
{
int n;
for (n = 0; env && env[n]; n++);
env = (char **) realloc(env, (n + 2) * sizeof(char *));
if (!env)
{
leave(&env_lock);
return -1;
}
env[n + 1] = NULL;
offset = n;
environ = env;
}
buf = (char *) malloc(strlen(name) + len + 2);
if (!buf)
{
leave(&env_lock);
return -1;
}
env[offset] = buf;
p = (char *) name;
while (*p) *buf++ = *p++;
*buf++ = '=';
p = (char *) value;
while (*p) *buf++ = *p++;
*buf = 0;
leave(&env_lock);
return 0;
}
void unsetenv(const char *name)
{
char **p;
char **env;
int offset;
enter(&env_lock);
env = environ;
while (findenv(env, name, &offset))
{
for (p = &(env[offset]);; p++)
if (!(*p = *(p + 1)))
break;
}
leave(&env_lock);
}
int putenv(const char *str)
{
char *p, *equal;
int rc;
p = strdup(str);
if (!p) return 1;
if ((equal = strchr(p, '=')))
{
*equal = '\0';
rc = setenv(p, equal + 1, 1);
}
else
{
unsetenv(p);
rc = 0;
}
free(p);
return rc;
}