diff options
author | Pino Toscano <toscano.pino@tiscali.it> | 2013-03-01 19:06:11 +0100 |
---|---|---|
committer | Pino Toscano <toscano.pino@tiscali.it> | 2013-03-01 19:06:11 +0100 |
commit | 523a01e93db829290b9f304fb31e5fe001ca2418 (patch) | |
tree | 202592ac311fc0ff0e5ca80184c593451cbe33a5 | |
parent | 757b6bf6feb3f1aba3d882f5dbe3b8b850f05294 (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.c | 50 |
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; } |