diff --git a/src/lib/direct.c b/src/lib/direct.c index 60cbed33d..6b69a99d0 100644 --- a/src/lib/direct.c +++ b/src/lib/direct.c @@ -832,7 +832,7 @@ int ncdirect_printf_aligned(ncdirect* n, int y, ncalign_e align, const char* fmt } static int -ncdirect_stop_minimal(void* vnc, void** altstack){ +ncdirect_stop_minimal(void* vnc, void** altstack, int errret){ ncdirect* nc = vnc; int ret = drop_signals(nc, altstack); fbuf f = {0}; @@ -862,6 +862,9 @@ ncdirect_stop_minimal(void* vnc, void** altstack){ #ifndef __MINGW32__ del_curterm(cur_term); #endif + if(errret){ + ret = errret; + } return ret; } @@ -955,7 +958,7 @@ int ncdirect_stop(ncdirect* nc){ int ret = 0; if(nc){ void* altstack; - ret |= ncdirect_stop_minimal(nc, &altstack); + ret |= ncdirect_stop_minimal(nc, &altstack, 0); free_terminfo_cache(&nc->tcache); if(nc->tcache.ttyfd >= 0){ ret |= close(nc->tcache.ttyfd); diff --git a/src/lib/notcurses.c b/src/lib/notcurses.c index 1228d206e..0bca9f077 100644 --- a/src/lib/notcurses.c +++ b/src/lib/notcurses.c @@ -118,7 +118,7 @@ int reset_term_palette(const tinfo* ti, fbuf* f, unsigned touchedpalette){ // to tear down and account for internal structures. note that we do lots of // shit here that is unsafe within a signal handler =[ FIXME. static int -notcurses_stop_minimal(void* vnc, void** altstack){ +notcurses_stop_minimal(void* vnc, void** altstack, int errret){ notcurses* nc = vnc; int ret = 0; ret |= drop_signals(nc, altstack); @@ -170,6 +170,9 @@ notcurses_stop_minimal(void* vnc, void** altstack){ } } } + if(errret){ + ret = errret; + } logdebug("restored terminal, returning %d", ret); return ret; } @@ -1390,7 +1393,7 @@ notcurses* notcurses_core_init(const notcurses_options* opts, FILE* outfp){ err:{ void* altstack; logpanic("alas, you will not be going to space today."); - notcurses_stop_minimal(ret, &altstack); + notcurses_stop_minimal(ret, &altstack, -1); fbuf_free(&ret->rstate.f); if(ret->tcache.ttyfd >= 0 && ret->tcache.tpreserved){ (void)tcsetattr(ret->tcache.ttyfd, TCSAFLUSH, ret->tcache.tpreserved); @@ -1449,7 +1452,7 @@ int notcurses_stop(notcurses* nc){ int ret = 0; if(nc){ void* altstack; - ret |= notcurses_stop_minimal(nc, &altstack); + ret |= notcurses_stop_minimal(nc, &altstack, 0); // if we were not using the alternate screen, our cursor's wherever we last // wrote. move it to the furthest place to which it advanced. if(!get_escape(&nc->tcache, ESCAPE_SMCUP)){ diff --git a/src/lib/unixsig.c b/src/lib/unixsig.c index b7d458a34..bd93009e2 100644 --- a/src/lib/unixsig.c +++ b/src/lib/unixsig.c @@ -32,7 +32,7 @@ int drop_signals(void* nc, void** altstack){ // inhibited), and ensures that only one notcurses/ncdirect context is active // at any given time. int setup_signals(void* vnc, bool no_quit_sigs, bool no_winch_sigs, - int(*handler)(void*, void**)){ + int(*handler)(void*, void**, int)){ (void)no_quit_sigs; (void)no_winch_sigs; (void)handler; @@ -75,7 +75,9 @@ static struct sigaction old_term; // Prepared in setup_signals(), and never changes across our lifetime. static sigset_t wblock_signals; -static int(*fatal_callback)(void*, void**); // fatal handler callback +// fatal handler callback, takes notcurses struct, pointer to altstack, +// and return value override. +static int(*fatal_callback)(void*, void**, int); int block_signals(sigset_t* old_blocked_signals){ if(pthread_sigmask(SIG_BLOCK, &wblock_signals, old_blocked_signals)){ @@ -160,7 +162,7 @@ static void fatal_handler(int signo, siginfo_t* siginfo, void* v){ notcurses* nc = atomic_load(&signal_nc); if(nc){ - fatal_callback(nc, NULL); // fuck the alt stack save yourselves + fatal_callback(nc, NULL, signo); // fuck the alt stack save yourselves switch(signo){ case SIGTERM: invoke_old(&old_term, signo, siginfo, v); break; case SIGSEGV: invoke_old(&old_segv, signo, siginfo, v); break; @@ -191,7 +193,7 @@ void setup_alt_sig_stack(void){ // inhibited), and ensures that only one notcurses/ncdirect context is active // at any given time. int setup_signals(void* vnc, bool no_quit_sigs, bool no_winch_sigs, - int(*handler)(void*, void**)){ + int(*handler)(void*, void**, int)){ notcurses* nc = vnc; void* expected = NULL; struct sigaction sa; diff --git a/src/lib/unixsig.h b/src/lib/unixsig.h index 9ff96c698..704130912 100644 --- a/src/lib/unixsig.h +++ b/src/lib/unixsig.h @@ -8,7 +8,7 @@ extern "C" { #include int setup_signals(void* nc, bool no_quit_sigs, bool no_winch_sig, - int(*handler)(void*, void**)); + int(*handler)(void*, void**, int)); // call at the beginning of shutdown (we don't want to run fatal signal // handlers during shutdown!). altstack is written to be freed late.