mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 12:53:13 +00:00
lint: deal with getpwent()
warnings
This suppresses lint warnings about using `getpwent()` because there is only one context where fish uses it. Thus the fact it may not be thread safe is not relevant to fish. This also improves that call site in `completer_t::try_complete_user()` method by short-circuiting the loop when a match is found.
This commit is contained in:
parent
f10e4f88b6
commit
c114cbc9af
1 changed files with 15 additions and 20 deletions
|
@ -1172,7 +1172,7 @@ bool completer_t::try_complete_variable(const wcstring &str) {
|
|||
|
||||
/// Try to complete the specified string as a username. This is used by ~USER type expansion.
|
||||
///
|
||||
/// \return 0 if unable to complete, 1 otherwise
|
||||
/// \return false if unable to complete, true otherwise
|
||||
bool completer_t::try_complete_user(const wcstring &str) {
|
||||
#ifndef HAVE_GETPWENT
|
||||
// The getpwent() function does not exist on Android. A Linux user on Android isn't
|
||||
|
@ -1184,48 +1184,43 @@ bool completer_t::try_complete_user(const wcstring &str) {
|
|||
const wchar_t *cmd = str.c_str();
|
||||
const wchar_t *first_char = cmd;
|
||||
|
||||
if (*first_char != L'~' || wcschr(first_char, L'/')) {
|
||||
return false;
|
||||
}
|
||||
if (*first_char != L'~' || wcschr(first_char, L'/')) return false;
|
||||
|
||||
const wchar_t *user_name = first_char + 1;
|
||||
const wchar_t *name_end = wcschr(user_name, L'~');
|
||||
if (name_end) {
|
||||
return false;
|
||||
}
|
||||
if (name_end) return false;
|
||||
|
||||
double start_time = timef();
|
||||
bool result = false;
|
||||
struct passwd *pw;
|
||||
size_t name_len = wcslen(user_name);
|
||||
|
||||
// We don't bother with the thread-safe `getpwent_r()` variant because it isn't needed. This is
|
||||
// only run in a completion context and thus will only be called from a single thread and there
|
||||
// is no place else in fish where we call `getpwent()`.
|
||||
struct passwd *pw;
|
||||
setpwent();
|
||||
while ((pw = getpwent()) != 0) {
|
||||
double current_time = timef();
|
||||
if (current_time - start_time > 0.2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!pw->pw_name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// cppcheck-suppress getpwentCalled
|
||||
while ((pw = getpwent()) != NULL) {
|
||||
const wcstring pw_name_str = str2wcstring(pw->pw_name);
|
||||
const wchar_t *pw_name = pw_name_str.c_str();
|
||||
if (wcsncmp(user_name, pw_name, name_len) == 0) {
|
||||
wcstring desc = format_string(COMPLETE_USER_DESC, pw_name);
|
||||
append_completion(&this->completions, &pw_name[name_len], desc, COMPLETE_NO_SPACE);
|
||||
|
||||
result = true;
|
||||
break;
|
||||
} else if (wcsncasecmp(user_name, pw_name, name_len) == 0) {
|
||||
wcstring name = format_string(L"~%ls", pw_name);
|
||||
wcstring desc = format_string(COMPLETE_USER_DESC, pw_name);
|
||||
|
||||
append_completion(&this->completions, name, desc,
|
||||
COMPLETE_REPLACES_TOKEN | COMPLETE_DONT_ESCAPE | COMPLETE_NO_SPACE);
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// If we've spent too much time (more than 200 ms) doing this give up.
|
||||
if (timef() - start_time > 0.2) break;
|
||||
}
|
||||
|
||||
endpwent();
|
||||
return result;
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue