Hi,

attached there is a patch for rpctrace to implement the -E option, as 
available for strace. This makes it possible to pass -Evar=value to 
set/change an envvar of the process, and -Evar to unset it.

Side question: do we have git hooks to automatically close bugs and 
tasks with commits?

Thanks,
-- 
Pino Toscano
From 7c60857c44b0792a1a79ebd4fd07704c2a712609 Mon Sep 17 00:00:00 2001
From: Pino Toscano <toscano.p...@tiscali.it>
Date: Fri, 1 Mar 2013 15:48:37 +0100
Subject: [PATCH] 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.
---
 utils/rpctrace.c |   50 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 49 insertions(+), 1 deletion(-)

diff --git a/utils/rpctrace.c b/utils/rpctrace.c
index deb8340..0a98f7d 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) != 0 ? 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;
 }
-- 
1.7.10.4

Attachment: signature.asc
Description: This is a digitally signed message part.

Reply via email to