aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/env.c48
-rw-r--r--lib/lib.h1
-rw-r--r--lib/xwrap.c9
3 files changed, 39 insertions, 19 deletions
diff --git a/lib/env.c b/lib/env.c
index 3e05f4e4..af0ec29d 100644
--- a/lib/env.c
+++ b/lib/env.c
@@ -22,6 +22,12 @@ long environ_bytes()
// Use this instead of envc so we keep track of what needs to be freed.
void xclearenv(void)
{
+ if (toys.envc) {
+ char **ss;
+
+ for (ss = environ; *ss; ss++) free(*ss);
+ free(environ);
+ }
toys.envc = 0;
*environ = 0;
}
@@ -29,18 +35,18 @@ void xclearenv(void)
// Frees entries we set earlier. Use with libc getenv but not setenv/putenv.
// if name has an equals and !val, act like putenv (name=val must be malloced!)
// if !val unset name. (Name with = and val is an error)
-void xsetenv(char *name, char *val)
+void xsetmyenv(int *envc, char ***env, char *name, char *val)
{
- unsigned i, len, envc;
+ unsigned i, len, ec;
char *new;
// If we haven't snapshot initial environment state yet, do so now.
- if (!toys.envc) {
+ if (!*envc) {
// envc is size +1 so even if env empty it's nonzero after initialization
- while (environ[toys.envc++]);
- memcpy(new = xmalloc(((toys.envc|0xff)+1)*sizeof(char *)),
- environ, toys.envc*sizeof(char *));
- environ = (void *)new;
+ while ((*env)[(*envc)++]);
+ memcpy(new = xmalloc(((*envc|0xff)+1)*sizeof(char *)), *env,
+ *envc*sizeof(char *));
+ *env = (void *)new;
}
new = strchr(name, '=');
@@ -53,16 +59,16 @@ void xsetenv(char *name, char *val)
if (val) new = xmprintf("%s=%s", name, val);
}
- envc = toys.envc-1; // compensate for size +1 above
- for (i = 0; environ[i]; i++) {
+ ec = (*envc)-1; // compensate for size +1 above
+ for (i = 0; (*env)[i]; i++) {
// Drop old entry, freeing as appropriate. Assumes no duplicates.
- if (!memcmp(name, environ[i], len) && environ[i][len]=='=') {
- if (i>=envc) free(environ[i]);
+ if (!memcmp(name, (*env)[i], len) && (*env)[i][len]=='=') {
+ if (i>=ec) free((*env)[i]);
else {
// move old entries down, add at end of old data
- toys.envc = envc--;
- for (; new ? i<envc : !!environ[i]; i++) environ[i] = environ[i+1];
- i = envc;
+ *envc = ec--;
+ for (; new ? i<ec : !!(*env)[i]; i++) (*env)[i] = (*env)[i+1];
+ i = ec;
}
break;
}
@@ -71,12 +77,18 @@ void xsetenv(char *name, char *val)
if (!new) return;
// resize and null terminate if expanding
- if (!environ[i]) {
+ if (!(*env)[i]) {
len = i+1;
- if (!(len&255)) environ = xrealloc(environ, len*sizeof(char *));
- environ[len] = 0;
+ if (!(len&255)) *env = xrealloc(*env, len*sizeof(char *));
+ (*env)[len] = 0;
}
- environ[i] = new;
+ (*env)[i] = new;
+}
+
+// xsetenv for normal environment (extern variables).
+void xsetenv(char *name, char *val)
+{
+ return xsetmyenv(&toys.envc, &environ, name, val);
}
void xunsetenv(char *name)
diff --git a/lib/lib.h b/lib/lib.h
index 8f949096..5ec648c8 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -134,6 +134,7 @@ void xputs(char *s);
void xputc(char c);
void xflush(int flush);
void xexec(char **argv);
+pid_t xpopen_setup(char **argv, int *pipes, void (*callback)(void));
pid_t xpopen_both(char **argv, int *pipes);
int xwaitpid(pid_t pid);
int xpclose_both(pid_t pid, int *pipes);
diff --git a/lib/xwrap.c b/lib/xwrap.c
index 591c9513..cfd17219 100644
--- a/lib/xwrap.c
+++ b/lib/xwrap.c
@@ -224,7 +224,7 @@ void xexec(char **argv)
// If -1, replace with pipe handle connected to stdin/stdout.
// NULL treated as {0, 1}, I.E. leave stdin/stdout as is
// return: pid of child process
-pid_t xpopen_both(char **argv, int *pipes)
+pid_t xpopen_setup(char **argv, int *pipes, void (*callback)(void))
{
int cestnepasun[4], pid;
@@ -269,6 +269,7 @@ pid_t xpopen_both(char **argv, int *pipes)
close(pipes[1]);
}
}
+ if (callback) callback();
if (argv) xexec(argv);
// In fork() case, force recursion because we know it's us.
@@ -309,6 +310,12 @@ pid_t xpopen_both(char **argv, int *pipes)
return pid;
}
+pid_t xpopen_both(char **argv, int *pipes)
+{
+ return xpopen_setup(argv, pipes, 0);
+}
+
+
// Wait for child process to exit, then return adjusted exit code.
int xwaitpid(pid_t pid)
{