aboutsummaryrefslogtreecommitdiff
path: root/t/rt.c
diff options
context:
space:
mode:
Diffstat (limited to 't/rt.c')
-rw-r--r--t/rt.c142
1 files changed, 132 insertions, 10 deletions
diff --git a/t/rt.c b/t/rt.c
index 1ecdc3a..bcb49a4 100644
--- a/t/rt.c
+++ b/t/rt.c
@@ -25,6 +25,7 @@
#include <sys/wait.h>
#include <errno.h>
#include <inttypes.h>
+#include <assert.h>
#include "runcap.h"
static char *progname;
@@ -49,6 +50,10 @@ usage(int code)
fprintf(fp, "tests the runcap library\n");
fprintf(fp, "OPTIONS are:\n\n");
fprintf(fp, " -S all|stderr|stdout selects capture for the next -m, -N, or -s option\n");
+ fprintf(fp, " -e VAR=NAME set environment variable\n");
+ fprintf(fp, " -e -VAR unset environment variable\n");
+ fprintf(fp, " -e - clear environment (except for PATH,\n");
+ fprintf(fp, " HOME, and LOGNAME)\n");
fprintf(fp, " -f FILE reads stdin from FILE\n");
fprintf(fp, " -i inline read (use before -f)\n");
fprintf(fp, " -N disable capturing\n");
@@ -234,11 +239,9 @@ readreq_do(struct runcap *rc, struct readreq *req)
if (req->full) {
char *buf = malloc(req->count);
ssize_t n;
-
- if (!buf) {
- perror("malloc");
- abort();
- }
+
+ assert(buf != NULL);
+
n = runcap_read(rc, req->what, buf, req->count);
if (n < 0) {
perror("runcap_read");
@@ -279,6 +282,123 @@ open_outfile(char *file, int stream, struct runcap *rc, int *flags)
*flags |= RCF_SC_TO_FLAG(RCF_SC_STORFD, stream);
}
+static int
+getenvind(char **env, char const *name)
+{
+ size_t i;
+ for (i = 0; env[i]; i++) {
+ char const *p;
+ char *q;
+
+ for (p = name, q = env[i]; *p == *q; p++, q++)
+ ;
+ if (*p == 0 && *q == '=') {
+ return i;
+ }
+ }
+ return -1;
+}
+
+char **
+envdup(char **env)
+{
+ int i;
+ char **new_env;
+
+ for (i = 0; env[i]; i++)
+ ;
+
+ new_env = calloc(i+1, sizeof(env[0]));
+ assert(new_env != NULL);
+
+ for (i = 0; env[i]; i++) {
+ new_env[i] = strdup(env[i]);
+ assert(new_env[i] != NULL);
+ }
+ new_env[i] = NULL;
+
+ return new_env;
+}
+
+char **envupdate(char **, char *);
+
+char **
+envclear(char **env)
+{
+ int i, j;
+ static char *keep[] = {
+ "PATH",
+ "HOME",
+ "LOGNAME",
+ NULL
+ };
+ char **new_env = calloc(1, sizeof(new_env[0]));
+ assert(new_env != NULL);
+ for (i = 0; keep[i]; i++) {
+ j = getenvind(env, keep[i]);
+ if (j != -1)
+ new_env = envupdate(new_env, env[j]);
+ }
+ for (i = 0; env[i]; i++)
+ free(env[i]);
+ free(env);
+ return new_env;
+}
+
+char **
+envappend(char **env, char *arg)
+{
+ int i;
+
+ for (i = 0; env[i]; i++)
+ ;
+ env = realloc(env, (i+2) * sizeof(env[0]));
+ assert(env != NULL);
+ env[i] = strdup(arg);
+ assert(env[i] != NULL);
+ env[i+1] = NULL;
+ return env;
+}
+
+char **
+envdelete(char **env, char *arg)
+{
+ int i = getenvind(env, arg);
+ if (i != -1) {
+ int n;
+ for (n = 0; env[n]; n++)
+ ;
+ free(env[i]);
+ memmove(env + i, env + i + 1, (n - i) * sizeof(env[0]));
+ }
+ return env;
+}
+
+extern char **environ;
+
+char **
+envupdate(char **env, char *arg)
+{
+ if (env == NULL)
+ env = envdup(environ);
+ if (*arg == '-') {
+ if (arg[1] == 0)
+ env = envclear(env);
+ else
+ env = envdelete(env, arg+1);
+ } else {
+ int i = getenvind(env, arg);
+ if (i == -1)
+ env = envappend(env, arg);
+ else {
+ free(env[i]);
+ env[i] = strdup(arg);
+ assert(env[i] != NULL);
+ }
+ }
+ return env;
+}
+
int
main(int argc, char **argv)
{
@@ -306,8 +426,13 @@ main(int argc, char **argv)
progname++;
else
progname = argv[0];
- while ((c = getopt(argc, argv, "?f:iNn:mo:p:r:S:s:t:")) != EOF) {
+ memset(&rc, 0, sizeof(rc));
+ while ((c = getopt(argc, argv, "?e:f:iNn:mo:p:r:S:s:t:")) != EOF) {
switch (c) {
+ case 'e':
+ rc.rc_env = envupdate(rc.rc_env, optarg);
+ rcf |= RCF_ENV;
+ break;
case 'f':
fd = open(optarg, O_RDONLY);
if (fd == -1) {
@@ -325,10 +450,7 @@ main(int argc, char **argv)
}
size = st.st_size;
buffer = malloc(size + 1);
- if (!buffer) {
- error("not enough memory");
- exit(1);
- }
+ assert(buffer != NULL);
rc.rc_cap[RUNCAP_STDIN].sc_size = size;
rc.rc_cap[RUNCAP_STDIN].sc_base = buffer;

Return to:

Send suggestions and report system problems to the System administrator.