Download raw body.
tog atexit() infinite loop
On Fri, May 20, 2022 at 10:13:14AM +0200, Stefan Sperling wrote: > On Fri, May 20, 2022 at 10:03:34AM +0200, Stefan Sperling wrote: > > #3 0x00000cd17cf3b5d7 in cleanup (sig=<optimized out>) at /usr/src/lib/libcurses/tty/lib_tstp.c:283 > > Reading the code in ncurses above, it looks like the root of the problem > is in ncurses. > > Of course, the log thread isn't supposed to be calling into curses > at all, yet still ends up here... sigh... For now, the best idea I have is the following. OK? ----------------------------------------------- commit d3ce8022aa10758c9e2d856b3e52501405b06d67 (tog-signals) from: Stefan Sperling <stsp@stsp.name> date: Fri May 20 08:23:50 2022 UTC tog: override SIGTERM and SIGINT handlers to avoid ncurses cleanup() handler diff 3d5026743b4462677a70d5a09bf4e5b65caee742 f05d359ae19407de65c59cad943debd2188f71a8 blob - a4221a9f756b84c1412ef1f4983cccd6aa233c2d blob + 0b71fb34c2bb552a0ccbb6848d023911e8d34c72 --- tog/tog.c +++ tog/tog.c @@ -595,6 +595,8 @@ static const struct got_error *search_next_ref_view(st static volatile sig_atomic_t tog_sigwinch_received; static volatile sig_atomic_t tog_sigpipe_received; static volatile sig_atomic_t tog_sigcont_received; +static volatile sig_atomic_t tog_sigint_received; +static volatile sig_atomic_t tog_sigterm_received; static void tog_sigwinch(int signo) @@ -614,6 +616,26 @@ tog_sigcont(int signo) tog_sigcont_received = 1; } +static void +tog_sigint(int signo) +{ + tog_sigint_received = 1; +} + +static void +tog_sigterm(int signo) +{ + tog_sigterm_received = 1; +} + +static int +tog_fatal_signal_received() +{ + return (tog_sigpipe_received || + tog_sigint_received || tog_sigint_received); +} + + static const struct got_error * view_close(struct tog_view *view) { @@ -1040,7 +1062,7 @@ view_loop(struct tog_view *view) return err; update_panels(); doupdate(); - while (!TAILQ_EMPTY(&views) && !done && !tog_sigpipe_received) { + while (!TAILQ_EMPTY(&views) && !done && !tog_fatal_signal_received()) { /* Refresh fast during initialization, then become slower. */ if (fast_refresh && fast_refresh-- == 0) halfdelay(10); /* switch to once per second */ @@ -2021,11 +2043,15 @@ block_signals_used_by_main_thread(void) if (sigemptyset(&sigset) == -1) return got_error_from_errno("sigemptyset"); - /* tog handles SIGWINCH and SIGCONT */ + /* tog handles SIGWINCH, SIGCONT, SIGINT, SIGTERM */ if (sigaddset(&sigset, SIGWINCH) == -1) return got_error_from_errno("sigaddset"); if (sigaddset(&sigset, SIGCONT) == -1) return got_error_from_errno("sigaddset"); + if (sigaddset(&sigset, SIGINT) == -1) + return got_error_from_errno("sigaddset"); + if (sigaddset(&sigset, SIGTERM) == -1) + return got_error_from_errno("sigaddset"); /* ncurses handles SIGTSTP */ if (sigaddset(&sigset, SIGTSTP) == -1) @@ -2050,7 +2076,7 @@ log_thread(void *arg) if (err) return (void *)err; - while (!done && !err && !tog_sigpipe_received) { + while (!done && !err && !tog_fatal_signal_received()) { err = queue_commits(a); if (err) { if (err->code != GOT_ERR_ITER_COMPLETED) @@ -2694,6 +2720,17 @@ apply_unveil(const char *repo_path, const char *worktr static void init_curses(void) { + /* + * Override default signal handlers before starting ncurses. + * This should prevent ncurses from installing its own + * broken cleanup() signal handler. + */ + signal(SIGWINCH, tog_sigwinch); + signal(SIGPIPE, tog_sigpipe); + signal(SIGCONT, tog_sigcont); + signal(SIGINT, tog_sigint); + signal(SIGTERM, tog_sigterm); + initscr(); cbreak(); halfdelay(1); /* Do fast refresh while initial view is loading. */ @@ -2706,9 +2743,6 @@ init_curses(void) start_color(); use_default_colors(); } - signal(SIGWINCH, tog_sigwinch); - signal(SIGPIPE, tog_sigpipe); - signal(SIGCONT, tog_sigcont); } static const struct got_error *
tog atexit() infinite loop