aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sim/common/nrun.c4
-rw-r--r--sim/common/sim-options.c99
-rw-r--r--sim/testsuite/cris/c/c.exp3
-rw-r--r--sim/testsuite/cris/c/readlink7.c5
-rw-r--r--sim/testsuite/cris/c/readlink8.c6
5 files changed, 107 insertions, 10 deletions
diff --git a/sim/common/nrun.c b/sim/common/nrun.c
index b3e48e2..320380e 100644
--- a/sim/common/nrun.c
+++ b/sim/common/nrun.c
@@ -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
diff --git a/sim/common/sim-options.c b/sim/common/sim-options.c
index 17e550e..f94b814 100644
--- a/sim/common/sim-options.c
+++ b/sim/common/sim-options.c
@@ -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,10 +189,64 @@ 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;
diff --git a/sim/testsuite/cris/c/c.exp b/sim/testsuite/cris/c/c.exp
index ec89c5c..506f68a 100644
--- a/sim/testsuite/cris/c/c.exp
+++ b/sim/testsuite/cris/c/c.exp
@@ -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]
diff --git a/sim/testsuite/cris/c/readlink7.c b/sim/testsuite/cris/c/readlink7.c
index 9c2b3b7..52c0733 100644
--- a/sim/testsuite/cris/c/readlink7.c
+++ b/sim/testsuite/cris/c/readlink7.c
@@ -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"
diff --git a/sim/testsuite/cris/c/readlink8.c b/sim/testsuite/cris/c/readlink8.c
index 55f6fe8..98319fb 100644
--- a/sim/testsuite/cris/c/readlink8.c
+++ b/sim/testsuite/cris/c/readlink8.c
@@ -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"