summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPino Toscano <toscano.pino@tiscali.it>2013-03-01 19:06:11 +0100
committerPino Toscano <toscano.pino@tiscali.it>2013-03-01 19:06:11 +0100
commit523a01e93db829290b9f304fb31e5fe001ca2418 (patch)
tree202592ac311fc0ff0e5ca80184c593451cbe33a5
parent757b6bf6feb3f1aba3d882f5dbe3b8b850f05294 (diff)
rpctrace: implement -E
Add a -E option to rpctrace, much like its strace's equivalent, to add/change/unset environment variables among the ones inherited by the process. Implements the savannah task #9331. * utils/rpctrace.c: Include <envz.h>. (options): Add the 'E' option. (parse_opt) <'E'>: Handle case. Create ENVZ from ENVP, and change it according to ARG. (main): Create CMD_ENVP from ENVZ if not null, or assign ENVP to it. Pass CMD_ENVP to traced_spawn.
-rw-r--r--utils/rpctrace.c50
1 files changed, 49 insertions, 1 deletions
diff --git a/utils/rpctrace.c b/utils/rpctrace.c
index deb83405..281991ca 100644
--- a/utils/rpctrace.c
+++ b/utils/rpctrace.c
@@ -39,6 +39,7 @@
#include <stdbool.h>
#include <stddef.h>
#include <argz.h>
+#include <envz.h>
const char *argp_program_version = STANDARD_HURD_VERSION (rpctrace);
@@ -59,6 +60,9 @@ static const struct argp_option options[] =
"Add the directory DIR to the list of directories to be searched for files "
"containing message ID numbers."},
{0, 's', "SIZE", 0, "Specify the maximum string size to print (the default is 80)."},
+ {0, 'E', "var[=value]", 0,
+ "Set/change (var=value) or remove (var) an environment variable among the "
+ "ones inherited by the executed process."},
{0}
};
@@ -1718,6 +1722,9 @@ main (int argc, char **argv, char **envp)
char **cmd_argv = 0;
pthread_t thread;
error_t err;
+ char **cmd_envp = NULL;
+ char *envz = NULL;
+ size_t envz_len = 0;
/* Parse our options... */
error_t parse_opt (int key, char *arg, struct argp_state *state)
@@ -1747,6 +1754,34 @@ main (int argc, char **argv, char **envp)
strsize = atoi (arg);
break;
+ case 'E':
+ if (envz == NULL)
+ {
+ if (argz_create (envp, &envz, &envz_len))
+ error (1, errno, "argz_create");
+ }
+ if (envz != NULL)
+ {
+ char *equal = strchr (arg, '=');
+ char *name;
+ char *newval;
+ if (equal != NULL)
+ {
+ name = strndupa (arg, equal - arg);
+ if (name == NULL)
+ error (1, errno, "strndupa");
+ newval = equal + 1;
+ }
+ else
+ {
+ name = arg;
+ newval = NULL;
+ }
+ if (envz_add (&envz, &envz_len, name, newval))
+ error (1, errno, "envz_add");
+ }
+ break;
+
case ARGP_KEY_NO_ARGS:
argp_usage (state);
return EINVAL;
@@ -1819,12 +1854,24 @@ main (int argc, char **argv, char **envp)
perror ("pthread_create");
}
+ if (envz != NULL)
+ {
+ envz_strip (&envz, &envz_len);
+ cmd_envp = alloca ((argz_count (envz, envz_len) + 1) * sizeof (char *));
+ if (cmd_envp == NULL)
+ error (1, errno, "alloca");
+ else
+ argz_extract (envz, envz_len, cmd_envp);
+ }
+ if (cmd_envp == NULL)
+ cmd_envp = envp;
+
/* Run the program on the command line and wait for it to die.
The other thread does all the tracing and interposing. */
{
pid_t child, pid;
int status;
- child = traced_spawn (cmd_argv, envp);
+ child = traced_spawn (cmd_argv, cmd_envp);
pid = waitpid (child, &status, 0);
sleep (1); /* XXX gives other thread time to print */
if (pid != child)
@@ -1837,6 +1884,7 @@ main (int argc, char **argv, char **envp)
}
ports_destroy_right (notify_pi);
+ free (envz);
return 0;
}