while (findenv(name, &offset)) { /* if set multiple times */
for (p = &environ[offset];; p++)
if (!(*p = *(p + 1)))
break;
}
return 0;
}
int
setenv(const char *name, const char *value, int rewrite)
{
char *c, **newenv;
const char *cc;
size_t l_value, size;
int offset;
if (name == NULL || value == NULL) {
errno = EINVAL;
return -1;
}
if (*value == '=') /* no `=' in value */
value++;
l_value = strlen(value);
/* find if already exists */
if ((c = findenv(name, &offset))) {
if (!rewrite)
return 0;
if (strlen(c) >= l_value) /* old larger; copy over */
goto copy;
} else { /* create new slot */
size = sizeof(char *) * (offset + 2);
if (savedEnv == environ) { /* just increase size */
if ((newenv = realloc(savedEnv, size)) == NULL)
return -1;
savedEnv = newenv;
} else { /* get new space */
/*
* We don't free here because we don't know if
* the first allocation is valid on all OS's
*/
if ((savedEnv = malloc(size)) == NULL)
return -1;
(void)memcpy(savedEnv, environ, size - sizeof(char *));
}
environ = savedEnv;
environ[offset + 1] = NULL;
}
for (cc = name; *cc && *cc != '='; cc++) /* no `=' in name */
continue;
size = cc - name;
/* name + `=' + value */
if ((environ[offset] = malloc(size + l_value + 2)) == NULL)
return -1;
c = environ[offset];
(void)memcpy(c, name, size);
c += size;
*c++ = '=';
copy:
(void)memcpy(c, value, l_value + 1);
return 0;
}
#ifdef TEST
int
main(int argc, char *argv[])
{
setenv(argv[1], argv[2], 0);
printf("%s\n", getenv(argv[1]));
unsetenv(argv[1]);
printf("%s\n", getenv(argv[1]));
return 0;
}
#endif
#endif
#if defined(__hpux__) || defined(__hpux)
/*
* strrcpy():
* Like strcpy, going backwards and returning the new pointer
*/
static char *
strrcpy(char *ptr, char *str)
{
int len = strlen(str);
/* find the inode of the current directory */
if (lstat(".", &st_cur) == -1) {
(void)sprintf(pathname,
"getwd: Cannot stat \".\" (%s)", strerror(errno));
return NULL;
}
nextpathptr = strrcpy(nextpathptr, "../");
/* Descend to root */
for (;;) {
/* look if we found root yet */
if (st_cur.st_ino == st_root.st_ino &&
DEV_DEV_COMPARE(st_cur.st_dev, st_root.st_dev)) {
(void)strcpy(pathname, *pathptr != '/' ? "/" : pathptr);
return pathname;
}
/* open the parent directory */
if (stat(nextpathptr, &st_dotdot) == -1) {
(void)sprintf(pathname,
"getwd: Cannot stat directory \"%s\" (%s)",
nextpathptr, strerror(errno));
return NULL;
}
if ((dp = opendir(nextpathptr)) == NULL) {
(void)sprintf(pathname,
"getwd: Cannot open directory \"%s\" (%s)",
nextpathptr, strerror(errno));
return NULL;
}
/* look in the parent for the entry with the same inode */
if (DEV_DEV_COMPARE(st_dotdot.st_dev, st_cur.st_dev)) {
/* Parent has same device. No need to stat every member */
for (d = readdir(dp); d != NULL; d = readdir(dp))
if (d->d_fileno == st_cur.st_ino)
break;
} else {
/*
* Parent has a different device. This is a mount point so we
* need to stat every member
*/
for (d = readdir(dp); d != NULL; d = readdir(dp)) {
if (ISDOT(d->d_name) || ISDOTDOT(d->d_name))
continue;
(void)strcpy(cur_name_add, d->d_name);
if (lstat(nextpathptr, &st_next) == -1) {
(void)sprintf(pathname,
"getwd: Cannot stat \"%s\" (%s)",
d->d_name, strerror(errno));
(void)closedir(dp);
return NULL;
}
/* check if we found it yet */
if (st_next.st_ino == st_cur.st_ino &&
DEV_DEV_COMPARE(st_next.st_dev, st_cur.st_dev))
break;
}
}
if (d == NULL) {
(void)sprintf(pathname,
"getwd: Cannot find \".\" in \"..\"");
(void)closedir(dp);
return NULL;
}
st_cur = st_dotdot;
pathptr = strrcpy(pathptr, d->d_name);
pathptr = strrcpy(pathptr, "/");
nextpathptr = strrcpy(nextpathptr, "../");
(void)closedir(dp);
*cur_name_add = '\0';
}
} /* end getwd */
#endif /* __hpux */
/* force posix signals */
SignalProc
bmake_signal(int s, SignalProc a)
{
struct sigaction sa, osa;