From 2457997cd9c624034f28f1be218f93cdc60a3e58 Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Sat, 12 Jul 2014 14:05:42 -0700 Subject: [PATCH] set: Print an error when setting a special var in the wrong scope When attempting to set a readonly or electric variable in the local or universal scopes, print an appropriate error. Similarly, print an error when setting an electric variable as exported. In most cases this is simply a nicer error instead of the 'read-only' one, but for the 'umask' variable it prevents `set -l umask 0023` from silently changing the global value. --- builtin_set.cpp | 7 +++++++ env.cpp | 9 +++++++++ env.h | 2 ++ 3 files changed, 18 insertions(+) diff --git a/builtin_set.cpp b/builtin_set.cpp index 9068372f0..aae87550d 100644 --- a/builtin_set.cpp +++ b/builtin_set.cpp @@ -157,6 +157,13 @@ static int my_env_set(const wchar_t *key, const wcstring_list_t &val, int scope) break; } + case ENV_SCOPE: + { + append_format(stderr_buffer, _(L"%ls: Tried to set the special variable '%ls' with the wrong scope\n"), L"set", key); + retcode=1; + break; + } + case ENV_INVALID: { append_format(stderr_buffer, _(L"%ls: Unknown error"), L"set"); diff --git a/env.cpp b/env.cpp index 821bd8f1b..77ee75aa5 100644 --- a/env.cpp +++ b/env.cpp @@ -634,6 +634,15 @@ int env_set(const wcstring &key, const wchar_t *val, int var_mode) } } + if ((var_mode & (ENV_LOCAL | ENV_UNIVERSAL)) && (is_read_only(key) || is_electric(key))) + { + return ENV_SCOPE; + } + if ((var_mode & ENV_EXPORT) && is_electric(key)) + { + return ENV_SCOPE; + } + if ((var_mode & ENV_USER) && is_read_only(key)) { return ENV_PERM; diff --git a/env.h b/env.h index e886a5b2c..a0931c87f 100644 --- a/env.h +++ b/env.h @@ -49,6 +49,7 @@ enum { ENV_PERM = 1, + ENV_SCOPE, ENV_INVALID } ; @@ -82,6 +83,7 @@ void env_init(const struct config_paths_t *paths = NULL); The current error codes are: * ENV_PERM, can only be returned when setting as a user, e.g. ENV_USER is set. This means that the user tried to change a read-only variable. + * ENV_SCOPE, the variable cannot be set in the given scope. This applies to readonly/electric variables set from the local or universal scopes, or set as exported. * ENV_INVALID, the variable name or mode was invalid */