mirror of
https://github.com/fish-shell/fish-shell.git
synced 2025-02-21 11:35:00 +08:00
history: Handle Ctrl-C/SIGINT or other errors on output append
When there are multiple screens worth of output and `history` is writing to the pager, pressing Ctrl-C at the end of a screen doesn't exit the pager (`q` is needed for that) but previously caused fish to emit an error ("write: Interrupted system call) until we starting silently handling SIGINT in `fd_output_stream_t::append()`. This patch makes `history` detect when the `append()` call returns with an error and causes it to end early rather than repeatedly trying (and failing) to write to the output stream.
This commit is contained in:
parent
83636fa599
commit
920ded26b9
@ -1482,8 +1482,10 @@ bool history_t::search(history_search_type_t search_type, const wcstring_list_t
|
||||
wcstring_list_t collected;
|
||||
wcstring formatted_record;
|
||||
size_t remaining = max_items;
|
||||
bool output_error = false;
|
||||
|
||||
// The function we use to act on each item.
|
||||
// The function we use to act on each item. The return value indicates whether the search should
|
||||
// continue (true) or stop (on false).
|
||||
std::function<bool(const history_item_t &item)> func = [&](const history_item_t &item) -> bool {
|
||||
if (remaining == 0) return false;
|
||||
remaining -= 1;
|
||||
@ -1493,7 +1495,11 @@ bool history_t::search(history_search_type_t search_type, const wcstring_list_t
|
||||
collected.push_back(std::move(formatted_record));
|
||||
} else {
|
||||
// We can output this immediately.
|
||||
streams.out.append(formatted_record);
|
||||
if (!streams.out.append(formatted_record)) {
|
||||
// This can happen if the user hit Ctrl-C to abort (maybe after the first page?).
|
||||
output_error = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
@ -1514,9 +1520,16 @@ bool history_t::search(history_search_type_t search_type, const wcstring_list_t
|
||||
}
|
||||
|
||||
// Output any items we collected (which only happens in reverse).
|
||||
for (auto iter = collected.rbegin(); iter != collected.rend(); ++iter) {
|
||||
streams.out.append(*iter);
|
||||
for (auto iter = collected.rbegin(); !output_error && iter != collected.rend(); ++iter) {
|
||||
if (!streams.out.append(*iter)) {
|
||||
// Don't force an error if output was aborted (typically via Ctrl-C/SIGINT); just don't
|
||||
// try writing any more.
|
||||
output_error = true;
|
||||
}
|
||||
}
|
||||
|
||||
// We are intentionally not returning false in case of an output error, as the user aborting the
|
||||
// output early (the most common case) isn't a reason to exit w/ a non-zero status code.
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user