mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-06-06 00:41:15 -03:00
Add workaround to env_get_pwd_slash() for cases where PWD is not set
There's been no reproducible case entered for #5080, but the stack trace indicates the problem is with env_get_pwd_slash() returning an empty string, which isn't a string that terminates in `/`. In addition to making the failure case to return the path `./` (which has the benefit of having the same meaning as $PWD), trying a little bit harder to retrieve the real PWD by using getcwd(3). While get_current_dir(3) is documented as relying on PWD, getcwd(3) does not mention any such caveats, so it's possible that it will work even if something is breaking PWD. Just a thought, but it's possible if due to some recursion PWD surpassed some predetermined value (maybe PATH_MAX) that PWD (on certain platforms or under certain enivronments) won't be set (hence the code that deals with ERANGE errors from the getcwd(3) call). Closes #5080.
This commit is contained in:
32
src/env.cpp
32
src/env.cpp
@@ -698,10 +698,36 @@ void env_set_read_limit() {
|
||||
|
||||
wcstring env_get_pwd_slash() {
|
||||
auto pwd_var = env_get(L"PWD");
|
||||
if (pwd_var.missing_or_empty()) {
|
||||
return L"";
|
||||
wcstring pwd;
|
||||
if (!pwd_var.missing_or_empty()) {
|
||||
pwd = pwd_var->as_string();
|
||||
}
|
||||
wcstring pwd = pwd_var->as_string();
|
||||
else {
|
||||
// Not sure how we can end up here, but it's possible.
|
||||
// See https://github.com/fish-shell/fish-shell/issues/5080
|
||||
// Perhaps it can happen on some platforms if the path is too long?
|
||||
std::vector<char> path;
|
||||
bool cwd_success = false;
|
||||
for (int i = 1; !cwd_success && i <= 10; ++i) {
|
||||
path.resize(PATH_MAX * i);
|
||||
if (getcwd(&path[0], PATH_MAX * i) == nullptr) {
|
||||
if (errno == ERANGE) {
|
||||
// buffer is not big enough, try again (up to a point)
|
||||
continue;
|
||||
}
|
||||
debug(1, "getcwd() failed with errno %d", errno);
|
||||
// . but with a trailing slash, because that's what this function does
|
||||
return L"./";
|
||||
}
|
||||
cwd_success = true;
|
||||
}
|
||||
if (!cwd_success) {
|
||||
debug(1, "getcwd() path too long!");
|
||||
return L"./";
|
||||
}
|
||||
pwd = str2wcstring(path.data());
|
||||
}
|
||||
|
||||
if (!string_suffixes_string(L"/", pwd)) {
|
||||
pwd.push_back(L'/');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user