diff options
-rw-r--r-- | sim/common/nrun.c | 4 | ||||
-rw-r--r-- | sim/common/sim-options.c | 99 | ||||
-rw-r--r-- | sim/testsuite/cris/c/c.exp | 3 | ||||
-rw-r--r-- | sim/testsuite/cris/c/readlink7.c | 5 | ||||
-rw-r--r-- | sim/testsuite/cris/c/readlink8.c | 6 |
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" |