improve set PATH warning message

This modifies the code path for `set PATH` and `set CDPATH` to emit an
easier to understand warning when an entry in those vars is invalid. For
example

$ set PATH $PATH /tmp/arglebargle
set: Warning: $PATH entry "/tmp/arglebargle": No such file or directory
$ mkdir /tmp/d
$ chmod 0 /tmp/d
$ set PATH $PATH /tmp/d
set: Warning: $PATH entry "/tmp/d": Permission denied
$ touch /tmp/x
$ set PATH $PATH /tmp/x
set: Warning: $PATH entry "/tmp/x": Not a directory

Fixes #3450
This commit is contained in:
Kurtis Rader 2016-10-14 20:26:23 -07:00
parent 4f397e86d7
commit dc6b538f56

View file

@ -26,7 +26,7 @@
class parser_t;
// Error message for invalid path operations.
#define BUILTIN_SET_PATH_ERROR L"%ls: Warning: path component %ls may not be valid in %ls.\n"
#define BUILTIN_SET_PATH_ERROR L"%ls: Warning: $%ls entry \"%ls\" is not valid (%s)\n"
// Hint for invalid path operation with a colon.
#define BUILTIN_SET_PATH_HINT L"%ls: Did you mean 'set %ls $%ls %ls'?\n"
@ -72,24 +72,25 @@ static int my_env_set(const wchar_t *key, const wcstring_list_t &val, int scope,
continue;
}
bool show_perror = false;
int show_hint = 0;
bool error = false;
struct stat buff;
if (wstat(dir, &buff)) {
if (wstat(dir, &buff) == -1) {
error = true;
show_perror = true;
}
if (!(S_ISDIR(buff.st_mode))) {
else if (!S_ISDIR(buff.st_mode)) {
error = true;
errno = ENOTDIR;
}
else if (waccess(dir, X_OK) == -1) {
error = true;
}
if (!error) {
any_success = true;
} else {
streams.err.append_format(_(BUILTIN_SET_PATH_ERROR), L"set", dir.c_str(), key);
streams.err.append_format(_(BUILTIN_SET_PATH_ERROR), L"set", key, dir.c_str(),
strerror(errno));
const wchar_t *colon = wcschr(dir.c_str(), L':');
if (colon && *(colon + 1)) {
@ -97,10 +98,6 @@ static int my_env_set(const wchar_t *key, const wcstring_list_t &val, int scope,
}
}
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);