mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
refactor(exit): pass error message to preserve_exit() (#22097)
Problem: 1. Some calls to preserve_exit() don't put a message in IObuff, so the IObuff printed by preserve_exit() contains unrelated information. 2. If a TUI client runs out of memory or receives a deadly signal, the error message is shown on alternate screen and cannot be easily seen because the TUI exits alternate screen soon afterwards. Solution: Pass error message to preserve_exit() and exit alternate screen before printing it. Note that this doesn't fix the problem that server error messages cannot be easily seen on exit. This is tracked in #21608 and #21843.
This commit is contained in:
parent
90333b24c3
commit
69bb145cea
@ -155,7 +155,7 @@ static void fread_idle_cb(uv_idle_t *handle)
|
||||
uintmax_t fpos_intmax = stream->fpos;
|
||||
if (fpos_intmax > INT64_MAX) {
|
||||
ELOG("stream offset overflow");
|
||||
preserve_exit();
|
||||
preserve_exit("stream offset overflow");
|
||||
}
|
||||
|
||||
// Synchronous read
|
||||
|
@ -211,9 +211,7 @@ static int nlua_luv_cfpcall(lua_State *lstate, int nargs, int nresult, int flags
|
||||
if (status) {
|
||||
if (status == LUA_ERRMEM && !(flags & LUVF_CALLBACK_NOEXIT)) {
|
||||
// consider out of memory errors unrecoverable, just like xmalloc()
|
||||
os_errmsg(e_outofmem);
|
||||
os_errmsg("\n");
|
||||
preserve_exit();
|
||||
preserve_exit(e_outofmem);
|
||||
}
|
||||
const char *error = lua_tostring(lstate, -1);
|
||||
|
||||
|
@ -790,10 +790,10 @@ void getout(int exitval)
|
||||
os_exit(exitval);
|
||||
}
|
||||
|
||||
/// Preserve files, print contents of `IObuff`, and exit 1.
|
||||
/// Preserve files, print contents of `errmsg`, and exit 1.
|
||||
///
|
||||
/// May be called from deadly_signal().
|
||||
void preserve_exit(void)
|
||||
void preserve_exit(const char *errmsg)
|
||||
FUNC_ATTR_NORETURN
|
||||
{
|
||||
// 'true' when we are sure to exit, e.g., after a deadly signal
|
||||
@ -812,12 +812,15 @@ void preserve_exit(void)
|
||||
// Ignore SIGHUP while we are already exiting. #9274
|
||||
signal_reject_deadly();
|
||||
|
||||
if (ui_client_channel_id) {
|
||||
// For TUI: exit alternate screen so that the error messages can be seen.
|
||||
ui_client_stop();
|
||||
}
|
||||
os_errmsg(errmsg);
|
||||
os_errmsg("\n");
|
||||
if (ui_client_channel_id) {
|
||||
os_exit(1);
|
||||
}
|
||||
|
||||
os_errmsg(IObuff);
|
||||
os_errmsg("\n");
|
||||
ui_flush();
|
||||
|
||||
ml_close_notmod(); // close all not-modified buffers
|
||||
|
@ -121,9 +121,7 @@ void *xmalloc(size_t size)
|
||||
{
|
||||
void *ret = try_malloc(size);
|
||||
if (!ret) {
|
||||
os_errmsg(e_outofmem);
|
||||
os_errmsg("\n");
|
||||
preserve_exit();
|
||||
preserve_exit(e_outofmem);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -152,9 +150,7 @@ void *xcalloc(size_t count, size_t size)
|
||||
try_to_free_memory();
|
||||
ret = calloc(allocated_count, allocated_size);
|
||||
if (!ret) {
|
||||
os_errmsg(e_outofmem);
|
||||
os_errmsg("\n");
|
||||
preserve_exit();
|
||||
preserve_exit(e_outofmem);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -174,9 +170,7 @@ void *xrealloc(void *ptr, size_t size)
|
||||
try_to_free_memory();
|
||||
ret = realloc(ptr, allocated_size);
|
||||
if (!ret) {
|
||||
os_errmsg(e_outofmem);
|
||||
os_errmsg("\n");
|
||||
preserve_exit();
|
||||
preserve_exit(e_outofmem);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -194,8 +188,7 @@ void *xmallocz(size_t size)
|
||||
{
|
||||
size_t total_size = size + 1;
|
||||
if (total_size < size) {
|
||||
os_errmsg(_("Vim: Data too large to fit into virtual memory space\n"));
|
||||
preserve_exit();
|
||||
preserve_exit(_("Vim: Data too large to fit into virtual memory space\n"));
|
||||
}
|
||||
|
||||
void *ret = xmalloc(total_size);
|
||||
|
@ -550,8 +550,7 @@ static void read_error_exit(void)
|
||||
if (silent_mode) { // Normal way to exit for "nvim -es".
|
||||
getout(0);
|
||||
}
|
||||
STRCPY(IObuff, _("Vim: Error reading input, exiting...\n"));
|
||||
preserve_exit();
|
||||
preserve_exit(_("Vim: Error reading input, exiting...\n"));
|
||||
}
|
||||
|
||||
static bool pending_events(MultiQueue *events)
|
||||
|
@ -172,11 +172,10 @@ static void deadly_signal(int signum)
|
||||
|
||||
ILOG("got signal %d (%s)", signum, signal_name(signum));
|
||||
|
||||
snprintf(IObuff, sizeof(IObuff), "Vim: Caught deadly signal '%s'\r\n",
|
||||
signal_name(signum));
|
||||
snprintf(IObuff, IOSIZE, "Vim: Caught deadly signal '%s'\r\n", signal_name(signum));
|
||||
|
||||
// Preserve files and exit.
|
||||
preserve_exit();
|
||||
preserve_exit(IObuff);
|
||||
}
|
||||
|
||||
static void on_signal(SignalWatcher *handle, int signum, void *data)
|
||||
|
@ -458,9 +458,6 @@ static void tui_terminal_stop(TUIData *tui)
|
||||
|
||||
void tui_stop(TUIData *tui)
|
||||
{
|
||||
if (tui->stopped) {
|
||||
return;
|
||||
}
|
||||
tui_terminal_stop(tui);
|
||||
stream_set_blocking(tui->input.in_fd, true); // normalize stream (#2598)
|
||||
tinput_destroy(&tui->input);
|
||||
@ -470,7 +467,7 @@ void tui_stop(TUIData *tui)
|
||||
}
|
||||
|
||||
/// Returns true if UI `ui` is stopped.
|
||||
static bool tui_is_stopped(TUIData *tui)
|
||||
bool tui_is_stopped(TUIData *tui)
|
||||
{
|
||||
return tui->stopped;
|
||||
}
|
||||
|
@ -122,7 +122,9 @@ void ui_client_run(bool remote_ui)
|
||||
|
||||
void ui_client_stop(void)
|
||||
{
|
||||
tui_stop(tui);
|
||||
if (!tui_is_stopped(tui)) {
|
||||
tui_stop(tui);
|
||||
}
|
||||
}
|
||||
|
||||
void ui_client_set_size(int width, int height)
|
||||
|
Loading…
Reference in New Issue
Block a user