/// Call vars.set. If this is a path variable, e.g. PATH, validate the elements. On error, print a /// description of the problem to stderr. static int env_set_reporting_errors(const wchar_t *cmd, const wchar_t *key, int scope, const wcstring_list_t &list, io_streams_t &streams, env_stack_t &vars) { if (is_path_variable(key) && !validate_path_warning_on_colons(cmd, key, list, streams, vars)) { return STATUS_CMD_ERROR; } int retval = vars.set(key, scope | ENV_USER, list); handle_env_return(retval, cmd, key, streams); return retval; }
/** Call env_set. If this is a path variable, e.g. PATH, validate the elements. On error, print a description of the problem to stderr. */ static int my_env_set( const wchar_t *key, wcstring_list_t &val, int scope ) { size_t i; int retcode = 0; const wchar_t *val_str=NULL; if( is_path_variable( key ) ) { int error = 0; for( i=0; i< val.size() ; i++ ) { int show_perror = 0; int show_hint = 0; struct stat buff; const wchar_t *dir = val[i].c_str(); if( wstat( dir, &buff ) ) { error = 1; show_perror = 1; } if( !( S_ISDIR(buff.st_mode) ) ) { error = 1; } if( error ) { const wchar_t *colon; append_format(stderr_buffer, _(BUILTIN_SET_PATH_ERROR), L"set", dir, key); colon = wcschr( dir, L':' ); if( colon && *(colon+1) ) { show_hint = 1; } } if( show_perror ) { builtin_wperror( L"set" ); } if( show_hint ) { append_format(stderr_buffer, _(BUILTIN_SET_PATH_HINT), L"set", key, key, wcschr( dir, L':' )+1); } if( error ) { break; } } if( error ) { return 1; } } wcstring sb; if( val.size() ) { for( i=0; i< val.size() ; i++ ) { sb.append(val[i]); if( i<val.size() - 1 ) { sb.append( ARRAY_SEP_STR ); } } val_str = sb.c_str(); } switch( env_set( key, val_str, scope | ENV_USER ) ) { case ENV_PERM: { append_format(stderr_buffer, _(L"%ls: Tried to change the read-only variable '%ls'\n"), L"set", key); retcode=1; break; } case ENV_INVALID: { append_format(stderr_buffer, _(L"%ls: Unknown error"), L"set" ); retcode=1; break; } } return retcode; }
/** Call env_set. If this is a path variable, e.g. PATH, validate the elements. On error, print a description of the problem to stderr. */ static int my_env_set(const wchar_t *key, const wcstring_list_t &val, int scope) { size_t i; int retcode = 0; const wchar_t *val_str=NULL; if (is_path_variable(key)) { /* Fix for https://github.com/fish-shell/fish-shell/issues/199 . Return success if any path setting succeeds. */ bool any_success = false; /* Don't bother validating (or complaining about) values that are already present */ wcstring_list_t existing_values; const env_var_t existing_variable = env_get_string(key, scope); if (! existing_variable.missing_or_empty()) tokenize_variable_array(existing_variable, existing_values); for (i=0; i< val.size() ; i++) { const wcstring &dir = val.at(i); if (list_contains_string(existing_values, dir)) { any_success = true; continue; } bool show_perror = false; int show_hint = 0; bool error = false; struct stat buff; if (wstat(dir, &buff)) { error = true; show_perror = true; } if (!(S_ISDIR(buff.st_mode))) { error = true; } if (!error) { any_success = true; } else { append_format(stderr_buffer, _(BUILTIN_SET_PATH_ERROR), L"set", dir.c_str(), key); const wchar_t *colon = wcschr(dir.c_str(), L':'); if (colon && *(colon+1)) { show_hint = 1; } } if (show_perror) { builtin_wperror(L"set"); } if (show_hint) { append_format(stderr_buffer, _(BUILTIN_SET_PATH_HINT), L"set", key, key, wcschr(dir.c_str(), L':')+1); } } /* Fail at setting the path if we tried to set it to something non-empty, but it wound up empty. */ if (! val.empty() && ! any_success) { return 1; } } wcstring sb; if (! val.empty()) { for (i=0; i< val.size() ; i++) { sb.append(val[i]); if (i<val.size() - 1) { sb.append(ARRAY_SEP_STR); } } val_str = sb.c_str(); } switch (env_set(key, val_str, scope | ENV_USER)) { case ENV_PERM: { append_format(stderr_buffer, _(L"%ls: Tried to change the read-only variable '%ls'\n"), L"set", key); retcode=1; 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: Tried to set the special variable '%ls' to an invalid value\n"), L"set", key); retcode=1; break; } } return retcode; }
/** Call env_set. If this is a path variable, e.g. PATH, validate the elements. On error, print a description of the problem to stderr. */ static int my_env_set(const wchar_t *key, const wcstring_list_t &val, int scope, io_streams_t &streams) { size_t i; int retcode = 0; const wchar_t *val_str=NULL; if (is_path_variable(key)) { /* Fix for https://github.com/fish-shell/fish-shell/issues/199 . Return success if any path setting succeeds. */ bool any_success = false; /* Don't bother validating (or complaining about) values that are already present. When determining already-present values, use ENV_DEFAULT instead of the passed-in scope because in: set -l PATH stuff $PATH where we are temporarily shadowing a variable, we want to compare against the shadowed value, not the (missing) local value. Also don't bother to complain about relative paths, which don't start with /. */ wcstring_list_t existing_values; const env_var_t existing_variable = env_get_string(key, ENV_DEFAULT); if (! existing_variable.missing_or_empty()) tokenize_variable_array(existing_variable, existing_values); for (i=0; i< val.size() ; i++) { const wcstring &dir = val.at(i); if (!string_prefixes_string(L"/", dir) || list_contains_string(existing_values, dir)) { any_success = true; continue; } bool show_perror = false; int show_hint = 0; bool error = false; struct stat buff; if (wstat(dir, &buff)) { error = true; show_perror = true; } if (!(S_ISDIR(buff.st_mode))) { error = true; } if (!error) { any_success = true; } else { streams.err.append_format(_(BUILTIN_SET_PATH_ERROR), L"set", dir.c_str(), key); const wchar_t *colon = wcschr(dir.c_str(), L':'); if (colon && *(colon+1)) { show_hint = 1; } } if (show_perror) { builtin_wperror(L"set", streams); } if (show_hint) { streams.err.append_format(_(BUILTIN_SET_PATH_HINT), L"set", key, key, wcschr(dir.c_str(), L':')+1); } } /* Fail at setting the path if we tried to set it to something non-empty, but it wound up empty. */ if (! val.empty() && ! any_success) { return 1; } } wcstring sb; if (! val.empty()) { for (i=0; i< val.size() ; i++) { sb.append(val[i]); if (i<val.size() - 1) { sb.append(ARRAY_SEP_STR); } } val_str = sb.c_str(); } switch (env_set(key, val_str, scope | ENV_USER)) { case ENV_PERM: { streams.err.append_format(_(L"%ls: Tried to change the read-only variable '%ls'\n"), L"set", key); retcode=1; break; } case ENV_SCOPE: { streams.err.append_format(_(L"%ls: Tried to set the special variable '%ls' with the wrong scope\n"), L"set", key); retcode=1; break; } case ENV_INVALID: { streams.err.append_format(_(L"%ls: Tried to set the special variable '%ls' to an invalid value\n"), L"set", key); retcode=1; break; } } return retcode; }
/** Call env_set. If this is a path variable, e.g. PATH, validate the elements. On error, print a description of the problem to stderr. */ static int my_env_set( const wchar_t *key, const wcstring_list_t &val, int scope ) { size_t i; int retcode = 0; const wchar_t *val_str=NULL; if( is_path_variable( key ) ) { /* Fix for https://github.com/fish-shell/fish-shell/issues/199 . Return success if any path setting succeeds. */ bool any_success = false, any_error = false; for( i=0; i< val.size() ; i++ ) { bool show_perror = false; int show_hint = 0; bool error = false; struct stat buff; const wchar_t *dir = val[i].c_str(); if( wstat( dir, &buff ) ) { error = true; show_perror = true; } if( !( S_ISDIR(buff.st_mode) ) ) { error = true; } if( !error ) { any_success = true; } else { any_error = true; const wchar_t *colon; append_format(stderr_buffer, _(BUILTIN_SET_PATH_ERROR), L"set", dir, key); colon = wcschr( dir, L':' ); if( colon && *(colon+1) ) { show_hint = 1; } } if( show_perror ) { builtin_wperror( L"set" ); } if( show_hint ) { append_format(stderr_buffer, _(BUILTIN_SET_PATH_HINT), L"set", key, key, wcschr( dir, L':' )+1); } } /* Fail at setting the path if we tried to set it to something non-empty, but it wound up empty. */ if( ! val.empty() && ! any_success ) { return 1; } } wcstring sb; if( val.size() ) { for( i=0; i< val.size() ; i++ ) { sb.append(val[i]); if( i<val.size() - 1 ) { sb.append( ARRAY_SEP_STR ); } } val_str = sb.c_str(); } switch( env_set( key, val_str, scope | ENV_USER ) ) { case ENV_PERM: { append_format(stderr_buffer, _(L"%ls: Tried to change the read-only variable '%ls'\n"), L"set", key); retcode=1; break; } case ENV_INVALID: { append_format(stderr_buffer, _(L"%ls: Unknown error"), L"set" ); retcode=1; break; } } return retcode; }