sim: nrun: add --env-{set,unset,clear} command line options
authorMike Frysinger <vapier@gentoo.org>
Tue, 16 Nov 2021 07:54:44 +0000 (02:54 -0500)
committerMike Frysinger <vapier@gentoo.org>
Tue, 16 Nov 2021 08:34:00 +0000 (03:34 -0500)
Provide explicit control over the program's environment with the
basic set/unset/clear options.  These are a bit clunky to use,
but they're functional.

The env set operation is split out into a separate function as it'll
be used in the next commit.

With these in place, we can adjust the custom cris testsuite to use
the now standard options and not its one-off hack.

sim/common/nrun.c
sim/common/sim-options.c
sim/testsuite/cris/c/c.exp
sim/testsuite/cris/c/readlink7.c
sim/testsuite/cris/c/readlink8.c

index b3e48e214ed398430ab49f3f928beab75e3d8f05..320380e91d59f9612a36ba019ef2b39e0c4f261b 100644 (file)
@@ -62,6 +62,7 @@ main (int argc, char **argv)
 {
   const char *name;
   char **prog_argv = NULL;
+  char **prog_envp = NULL;
   struct bfd *prog_bfd;
   enum sim_stop reason;
   int sigrc = 0;
@@ -99,6 +100,7 @@ main (int argc, char **argv)
 
   /* Was there a program to run?  */
   prog_argv = STATE_PROG_ARGV (sd);
+  prog_envp = STATE_PROG_ENVP (sd) ? : environ;
   prog_bfd = STATE_PROG_BFD (sd);
   if (prog_argv == NULL || *prog_argv == NULL)
     usage ();
@@ -131,7 +133,7 @@ main (int argc, char **argv)
     exit (1);
 
   /* Prepare the program for execution.  */
-  sim_create_inferior (sd, prog_bfd, prog_argv, environ);
+  sim_create_inferior (sd, prog_bfd, prog_argv, prog_envp);
 
   /* To accommodate relative file paths, chdir to sysroot now.  We
      mustn't do this until BFD has opened the program, else we wouldn't
index 17e550e55577ee47b87a95a81c54e84e16afb1b9..f94b814a6cb3985cbabc3a5a26e3481e1e98e722 100644 (file)
@@ -25,10 +25,12 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <stdlib.h>
 #include <ctype.h>
 #include <stdio.h>
+#include <unistd.h>
 #include "libiberty.h"
 #include "sim-options.h"
 #include "sim-io.h"
 #include "sim-assert.h"
+#include "environ.h"
 #include "version.h"
 #include "hashtab.h"
 
@@ -106,6 +108,9 @@ typedef enum {
   OPTION_LOAD_VMA,
   OPTION_SYSROOT,
   OPTION_ARGV0,
+  OPTION_ENV_SET,
+  OPTION_ENV_UNSET,
+  OPTION_ENV_CLEAR,
 } STANDARD_OPTIONS;
 
 static const OPTION standard_options[] =
@@ -184,9 +189,63 @@ static const OPTION standard_options[] =
       '\0', "ARGV0", "Set argv[0] to the specified string",
       standard_option_handler, NULL },
 
+  { {"env-set", required_argument, NULL, OPTION_ENV_SET},
+      '\0', "VAR=VAL", "Set the variable in the program's environment",
+      standard_option_handler, NULL },
+  { {"env-unset", required_argument, NULL, OPTION_ENV_UNSET},
+      '\0', "VAR", "Unset the variable in the program's environment",
+      standard_option_handler, NULL },
+  { {"env-clear", no_argument, NULL, OPTION_ENV_CLEAR},
+      '\0', NULL, "Clear the program's environment",
+      standard_option_handler, NULL },
+
   { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL }
 };
 
+static SIM_RC
+env_set (SIM_DESC sd, const char *arg)
+{
+  int i, varlen;
+  char *eq;
+  char **envp;
+
+  if (STATE_PROG_ENVP (sd) == NULL)
+    STATE_PROG_ENVP (sd) = dupargv (environ);
+
+  eq = strchr (arg, '=');
+  if (eq == NULL)
+    {
+      sim_io_eprintf (sd, "invalid syntax when setting env var `%s'"
+                     ": missing value", arg);
+      return SIM_RC_FAIL;
+    }
+  /* Include the = in the comparison below.  */
+  varlen = eq - arg + 1;
+
+  /* If we can find an existing variable, replace it.  */
+  envp = STATE_PROG_ENVP (sd);
+  for (i = 0; envp[i]; ++i)
+    {
+      if (strncmp (envp[i], arg, varlen) == 0)
+       {
+         free (envp[i]);
+         envp[i] = xstrdup (arg);
+         break;
+       }
+    }
+
+  /* If we didn't find the var, add it.  */
+  if (envp[i] == NULL)
+    {
+      envp = xrealloc (envp, (i + 2) * sizeof (char *));
+      envp[i] = xstrdup (arg);
+      envp[i + 1] = NULL;
+      STATE_PROG_ENVP (sd) = envp;
+  }
+
+  return SIM_RC_OK;
+}
+
 static SIM_RC
 standard_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt,
                         char *arg, int is_command)
@@ -430,6 +489,46 @@ standard_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt,
       free (STATE_PROG_ARGV0 (sd));
       STATE_PROG_ARGV0 (sd) = xstrdup (arg);
       break;
+
+    case OPTION_ENV_SET:
+      return env_set (sd, arg);
+
+    case OPTION_ENV_UNSET:
+      {
+       int i, varlen;
+       char **envp;
+
+       if (STATE_PROG_ENVP (sd) == NULL)
+         STATE_PROG_ENVP (sd) = dupargv (environ);
+
+       varlen = strlen (arg);
+
+       /* If we can find an existing variable, replace it.  */
+       envp = STATE_PROG_ENVP (sd);
+       for (i = 0; envp[i]; ++i)
+         {
+           char *env = envp[i];
+
+           if (strncmp (env, arg, varlen) == 0
+               && (env[varlen] == '\0' || env[varlen] == '='))
+             {
+               free (envp[i]);
+               break;
+             }
+         }
+
+       /* If we clear the var, shift the array down.  */
+       for (; envp[i]; ++i)
+         envp[i] = envp[i + 1];
+
+       break;
+      }
+
+    case OPTION_ENV_CLEAR:
+      freeargv (STATE_PROG_ENVP (sd));
+      STATE_PROG_ENVP (sd) = xmalloc (sizeof (char *));
+      STATE_PROG_ENVP (sd)[0] = NULL;
+      break;
     }
 
   return SIM_RC_OK;
index ec89c5c1de20a8b15b4f875ce432bb31faa293c3..506f68ab08654821d794be1d46a5a67cf156c8e6 100644 (file)
@@ -101,7 +101,6 @@ foreach src [lsort [glob -nocomplain $srcdir/$subdir/*.c]] {
     set opts(timeout) ""
     set opts(mach) ""
     set opts(xerror) "no"
-    set opts(simenv) ""
     set opts(kfail) ""
     set opts(xfail) ""
     set opts(target) ""
@@ -211,7 +210,7 @@ foreach src [lsort [glob -nocomplain $srcdir/$subdir/*.c]] {
     }
 
     set result [sim_run "$testname.x" "$opts(sim,$mach)" "$opts(progoptions)" \
-       "" "$opts(simenv)"]
+       "" ""]
     set return_code [lindex $result 0]
     set output [lindex $result 1]
 
index 9c2b3b732c8c7dbf9928029f12d4eafcfd0944a2..52c0733ca8a44de5dcbee506ba257273bb7ae1bf 100644 (file)
@@ -1,6 +1,5 @@
 /* Check that rare readlink calls don't cause the simulator to abort.
 #notarget: cris*-*-elf
-#simenv: env(-u\ PWD\ foo)=bar
-   FIXME: Need to unset PWD, but right now I won't bother tweaking the
-   generic parts of the testsuite machinery and instead abuse a flaw.  */
+#sim: --env-unset PWD
+ */
 #include "readlink2.c"
index 55f6fe8541f231364755239ce1c0719a48126d3c..98319fb4e3447bd20b5acfec53409ab6131b70da 100644 (file)
@@ -1,8 +1,6 @@
 /* Check that rare readlink calls don't cause the simulator to abort.
 #notarget: cris*-*-elf
-#sim: --sysroot=@exedir@
-#simenv: env(-u\ PWD\ foo)=bar
-   FIXME: Need to unset PWD, but right now I won't bother tweaking the
-   generic parts of the testsuite machinery and instead abuse a flaw.  */
+#sim: --sysroot=@exedir@ --env-unset PWD
+ */
 #define SYSROOTED 1
 #include "readlink2.c"