[pacman-dev] [PATCH] Move cursor to the end of the screen at the SIGINT
It requires exposing 'move cursor to the end' function in a pacman header file. We use it as a chance to make naming of the cursor management functions more consistent. Note that there is still possibility of a race condition in the cursor update logic. 'update cursor index variable' and 'send ASCII control symbols to console' is not an atomic operation. So if an SIGINT is received between these two action then cursor position is going to be screwed. Fixes FS#67973 Signed-off-by: Anatol Pomozov <anatol.pomozov@gmail.com> --- src/pacman/callback.c | 24 +++++++++++------------- src/pacman/sighandler.c | 3 +++ src/pacman/util.h | 1 + 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/pacman/callback.c b/src/pacman/callback.c index 53518101..12ab952f 100644 --- a/src/pacman/callback.c +++ b/src/pacman/callback.c @@ -92,8 +92,6 @@ struct pacman_multibar_ui { struct pacman_multibar_ui multibar_ui = {0}; -static void cursor_goto_end(void); - void multibar_move_completed_up(bool value) { multibar_ui.move_completed_up = value; } @@ -226,7 +224,7 @@ static int number_length(size_t n) void cb_event(alpm_event_t *event) { if(config->print) { - cursor_goto_end(); + console_cursor_move_end(); return; } switch(event->type) { @@ -389,7 +387,7 @@ void cb_event(alpm_event_t *event) case ALPM_EVENT_DB_RETRIEVE_FAILED: case ALPM_EVENT_PKG_RETRIEVE_DONE: case ALPM_EVENT_PKG_RETRIEVE_FAILED: - cursor_goto_end(); + console_cursor_move_end(); flush_output_list(); on_progress = 0; break; @@ -694,7 +692,7 @@ static int dload_progressbar_enabled(void) } /* Goto the line that corresponds to num-th active download */ -static void cursor_goto_bar(int num) +static void console_cursor_goto_bar(int num) { if(num > multibar_ui.cursor_lineno) { console_cursor_move_down(num - multibar_ui.cursor_lineno); @@ -705,9 +703,9 @@ static void cursor_goto_bar(int num) } /* Goto the line *after* the last active progress bar */ -static void cursor_goto_end(void) +void console_cursor_move_end(void) { - cursor_goto_bar(multibar_ui.active_downloads_num); + console_cursor_goto_bar(multibar_ui.active_downloads_num); } /* Returns true if element with the specified name is found, false otherwise */ @@ -849,7 +847,7 @@ static void dload_init_event(const char *filename, alpm_download_event_init_t *d bar->rate = 0.0; multibar_ui.active_downloads = alpm_list_add(multibar_ui.active_downloads, bar); - cursor_goto_end(); + console_cursor_move_end(); printf(_(" %s downloading...\n"), filename); multibar_ui.cursor_lineno++; multibar_ui.active_downloads_num++; @@ -894,7 +892,7 @@ static void dload_progress_event(const char *filename, alpm_download_event_progr bar->total_size = data->total; bar->xfered = data->downloaded; - cursor_goto_bar(index); + console_cursor_goto_bar(index); draw_pacman_progress_bar(bar); fflush(stdout); } @@ -920,7 +918,7 @@ static void dload_complete_event(const char *filename, alpm_download_event_compl bar->total_size = data->total; if(data->result == 1) { - cursor_goto_bar(index); + console_cursor_goto_bar(index); printf(_(" %s is up to date"), bar->filename); /* The line contains text from previous status. Erase these leftovers. */ console_erase_line(); @@ -947,16 +945,16 @@ static void dload_complete_event(const char *filename, alpm_download_event_compl multibar_ui.active_downloads->data = bar; baritem->data = former_topbar; - cursor_goto_bar(index); + console_cursor_goto_bar(index); draw_pacman_progress_bar(former_topbar); index = 0; } - cursor_goto_bar(index); + console_cursor_goto_bar(index); draw_pacman_progress_bar(bar); } else { - cursor_goto_bar(index); + console_cursor_goto_bar(index); printf(_(" %s failed to download"), bar->filename); console_erase_line(); } diff --git a/src/pacman/sighandler.c b/src/pacman/sighandler.c index fc4ea766..ff9c6ac4 100644 --- a/src/pacman/sighandler.c +++ b/src/pacman/sighandler.c @@ -53,6 +53,8 @@ static void _reset_handler(int signum) */ static void soft_interrupt_handler(int signum) { + console_cursor_move_end(); + if(signum == SIGINT) { const char msg[] = "\nInterrupt signal received\n"; xwrite(STDERR_FILENO, msg, ARRAYSIZE(msg) - 1); @@ -96,6 +98,7 @@ static void segv_handler(int signum) sigset_t segvset; const char msg[] = "\nerror: segmentation fault\n" "Please submit a full bug report with --debug if appropriate.\n"; + console_cursor_move_end(); xwrite(STDERR_FILENO, msg, sizeof(msg) - 1); xwrite(STDOUT_FILENO, CURSOR_SHOW_ANSICODE, sizeof(CURSOR_SHOW_ANSICODE) - 1); diff --git a/src/pacman/util.h b/src/pacman/util.h index c97048fb..ceaec6bd 100644 --- a/src/pacman/util.h +++ b/src/pacman/util.h @@ -85,6 +85,7 @@ void console_cursor_hide(void); void console_cursor_show(void); void console_cursor_move_up(unsigned int lines); void console_cursor_move_down(unsigned int lines); +void console_cursor_move_end(void); /* Erases line from the current cursor position till the end of the line */ void console_erase_line(void); -- 2.29.2
On 4/11/20 11:04 am, Anatol Pomozov wrote:
It requires exposing 'move cursor to the end' function in a pacman header file. We use it as a chance to make naming of the cursor management functions more consistent.
Note that there is still possibility of a race condition in the cursor update logic. 'update cursor index variable' and 'send ASCII control symbols to console' is not an atomic operation. So if an SIGINT is received between these two action then cursor position is going to be screwed.
Fixes FS#67973
Signed-off-by: Anatol Pomozov <anatol.pomozov@gmail.com> ---
Looks good. As an aside, I'd like to boot those console functions into a separate file at some stage. Allan
participants (2)
-
Allan McRae
-
Anatol Pomozov