mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-10 01:29:05 -04:00
ncdirect: set up fatal signal handlers #1271
This commit is contained in:
parent
3a658dad3e
commit
6d6416064e
@ -28,7 +28,7 @@ typedef struct ncplane ncdirectv;
|
||||
// We typically install a signal handler for SIG{INT, SEGV, ABRT, QUIT} that
|
||||
// restores the screen, and then calls the old signal handler. Set to inhibit
|
||||
// registration of these signal handlers. Chosen to match fullscreen mode.
|
||||
#define NCDIRECT_NO_QUIT_SIGHANDLERS 0x0008ull
|
||||
#define NCDIRECT_OPTION_NO_QUIT_SIGHANDLERS 0x0008ull
|
||||
|
||||
// Initialize a direct-mode Notcurses context on the connected terminal at 'fp'.
|
||||
// 'fp' must be a tty. You'll usually want stdout. Direct mode supports a
|
||||
|
@ -592,8 +592,33 @@ int get_controlling_tty(FILE* ttyfp){
|
||||
return open(cbuf, O_RDWR | O_CLOEXEC);
|
||||
}
|
||||
|
||||
static int
|
||||
ncdirect_stop_minimal(void* vnc){
|
||||
ncdirect* nc = static_cast<ncdirect*>(vnc);
|
||||
int ret = 0;
|
||||
if(nc->tcache.op && term_emit("op", nc->tcache.op, nc->ttyfp, true)){
|
||||
ret = -1;
|
||||
}
|
||||
if(nc->tcache.sgr0 && term_emit("sgr0", nc->tcache.sgr0, nc->ttyfp, true)){
|
||||
ret = -1;
|
||||
}
|
||||
if(nc->tcache.oc && term_emit("oc", nc->tcache.oc, nc->ttyfp, true)){
|
||||
ret = -1;
|
||||
}
|
||||
if(nc->ctermfd >= 0){
|
||||
if(nc->tcache.cnorm && tty_emit("cnorm", nc->tcache.cnorm, nc->ctermfd)){
|
||||
ret = -1;
|
||||
}
|
||||
if(!(nc->flags & NCDIRECT_OPTION_INHIBIT_CBREAK)){
|
||||
ret |= tcsetattr(nc->ctermfd, TCSANOW, &nc->tpreserved);
|
||||
}
|
||||
ret |= close(nc->ctermfd);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ncdirect* ncdirect_init(const char* termtype, FILE* outfp, uint64_t flags){
|
||||
if(flags > (NCDIRECT_OPTION_INHIBIT_CBREAK << 1)){ // allow them through with warning
|
||||
if(flags > (NCDIRECT_OPTION_NO_QUIT_SIGHANDLERS << 1)){ // allow them through with warning
|
||||
logwarn((struct notcurses*)NULL, "Passed unsupported flags 0x%016jx\n", (uintmax_t)flags);
|
||||
}
|
||||
if(outfp == nullptr){
|
||||
@ -613,6 +638,11 @@ ncdirect* ncdirect_init(const char* termtype, FILE* outfp, uint64_t flags){
|
||||
if(encoding && strcmp(encoding, "UTF-8") == 0){
|
||||
ret->utf8 = true;
|
||||
}
|
||||
if(setup_signals(ret, (flags & NCDIRECT_OPTION_NO_QUIT_SIGHANDLERS),
|
||||
true, ncdirect_stop_minimal)){
|
||||
delete ret;
|
||||
return nullptr;
|
||||
}
|
||||
// we don't need a controlling tty for everything we do; allow a failure here
|
||||
if((ret->ctermfd = get_controlling_tty(ret->ttyfp)) >= 0){
|
||||
if(!(flags & NCDIRECT_OPTION_INHIBIT_CBREAK)){
|
||||
@ -658,24 +688,7 @@ err:
|
||||
int ncdirect_stop(ncdirect* nc){
|
||||
int ret = 0;
|
||||
if(nc){
|
||||
if(nc->tcache.op && term_emit("op", nc->tcache.op, nc->ttyfp, true)){
|
||||
ret = -1;
|
||||
}
|
||||
if(nc->tcache.sgr0 && term_emit("sgr0", nc->tcache.sgr0, nc->ttyfp, true)){
|
||||
ret = -1;
|
||||
}
|
||||
if(nc->tcache.oc && term_emit("oc", nc->tcache.oc, nc->ttyfp, true)){
|
||||
ret = -1;
|
||||
}
|
||||
if(nc->ctermfd >= 0){
|
||||
if(nc->tcache.cnorm && tty_emit("cnorm", nc->tcache.cnorm, nc->ctermfd)){
|
||||
ret = -1;
|
||||
}
|
||||
if(!(nc->flags & NCDIRECT_OPTION_INHIBIT_CBREAK)){
|
||||
ret |= tcsetattr(nc->ctermfd, TCSANOW, &nc->tpreserved);
|
||||
}
|
||||
ret |= close(nc->ctermfd);
|
||||
}
|
||||
ret |= ncdirect_stop_minimal(nc);
|
||||
input_free_esctrie(&nc->input.inputescapes);
|
||||
delete(nc);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user