/* final.c
*/
/* This software is copyrighted as detailed in the LICENSE file. */
#include "EXTERN.h"
#include "common.h"
#include "list.h"
#include "env.h"
#include "util.h"
#include "hash.h"
#include "cache.h"
#include "bits.h"
#include "term.h"
#include "color.h"
#include "ng.h"
#include "init.h"
#include "last.h"
#include "ngdata.h"
#include "nntpclient.h"
#include "nntpinit.h"
#include "datasrc.h"
#include "nntp.h"
#include "rcstuff.h"
#include "artio.h"
#include "intrp.h"
#include "kfile.h"
#ifdef SCORE
#include "score.h"
#include "scoresave.h"
#endif
#ifdef USE_TCL
#include "tkstuff.h"
#endif
#ifdef USE_FILTER
#include "filter.h"
#endif
#include "INTERN.h"
#include "final.h"
#ifndef sigmask
#define sigmask(m) (1 << ((m)-1))
#endif
void
final_init()
{
#ifdef SIGTSTP
sigset(SIGTSTP, stop_catcher); /* job control signals */
sigset(SIGTTOU, stop_catcher); /* job control signals */
sigset(SIGTTIN, stop_catcher); /* job control signals */
#endif
sigset(SIGINT, int_catcher); /* always catch interrupts */
#ifdef SIGHUP
sigset(SIGHUP, sig_catcher); /* and hangups */
#endif
#ifdef SIGWINCH
sigset(SIGWINCH, winch_catcher);
#endif
#ifdef SUPPORT_NNTP
sigset(SIGPIPE,pipe_catcher);
#endif
#ifndef lint
#ifdef SIGEMT
sigignore(SIGEMT); /* Ignore EMT signals from old [t]rn's */
#endif
#endif
#ifdef DEBUG
/* sometimes we WANT a core dump */
if (debug & DEB_COREDUMPSOK)
return;
#endif
sigset(SIGILL, sig_catcher);
#ifdef SIGTRAP
sigset(SIGTRAP, sig_catcher);
#endif
sigset(SIGFPE, sig_catcher);
#ifdef SIGBUS
sigset(SIGBUS, sig_catcher);
#endif
sigset(SIGSEGV, sig_catcher);
#ifdef SIGSYS
sigset(SIGSYS, sig_catcher);
#endif
sigset(SIGTERM, sig_catcher);
#ifdef SIGXCPU
sigset(SIGXCPU, sig_catcher);
#endif
#ifdef SIGXFSZ
sigset(SIGXFSZ, sig_catcher);
#endif
}
void /* very much void */
finalize(status)
int status;
{
#ifdef SUPPORT_NNTP
int i;
char* s;
#endif
#ifdef SCORE
sc_sv_savefile(); /* save any scores from memory to disk */
#endif
#ifdef USE_FILTER
filter_cleanup();
#endif
#ifdef KILLFILES
update_thread_kfile();
#endif
color_default();
termlib_reset();
if (bizarre)
resetty();
xmouse_off(); /* turn off mouse tracking (if on) */
fflush(stdout);
chdir(tmpdir);
unuse_multirc(multirc);
if (datasrc_list) {
DATASRC* dp;
for (dp = datasrc_first(); dp && dp->name; dp = datasrc_next(dp))
close_datasrc(dp);
}
#ifdef SUPPORT_NNTP
for (i = 0; i < MAX_NNTP_ARTICLES; i++) {
s = nntp_tmpname(i);
UNLINK(s);
}
cleanup_nntp();
#endif
if (headname)
UNLINK(headname);
#ifdef USE_TCL
if (ttcl_running)
ttcl_finalize(status);
#endif
if (status < 0) {
sigset(SIGILL,SIG_DFL);
#ifdef HAS_SIGBLOCK
sigsetmask(sigblock(0) & ~(sigmask(SIGILL) | sigmask(SIGIOT)));
#endif
abort();
}
#ifdef RESTORE_ORIGDIR
if (origdir)
chdir(origdir);
#endif
exit(status);
}
/* come here on interrupt */
Signal_t
int_catcher(dummy)
int dummy;
{
sigset(SIGINT,int_catcher);
#ifdef DEBUG
if (debug)
write(2,"int_catcher\n",12);
#endif
if (!waiting) {
if (int_count++) { /* was there already an interrupt? */
if (int_count == 3 || int_count > 5) {
write(2,"\nBye-bye.\n",10);
sig_catcher(0); /* emulate the other signals */
}
write(2,"\n(Interrupt -- one more to kill trn)\n",37);
}
}
}
/* come here on signal other than interrupt, stop, or cont */
Signal_t
sig_catcher(signo)
int signo;
{
#ifdef VERBOSE
static char* signame[] = {
"",
"HUP",
"INT",
"QUIT",
"ILL",
"TRAP",
"IOT",
"EMT",
"FPE",
"KILL",
"BUS",
"SEGV",
"SYS",
"PIPE",
"ALRM",
"TERM",
"???"
#ifdef SIGTSTP
,"STOP",
"TSTP",
"CONT",
"CHLD",
"TTIN",
"TTOU",
"TINT",
"XCPU",
"XFSZ"
#ifdef SIGPROF
,"VTALARM",
"PROF"
#endif
#endif
};
#endif
#ifdef DEBUG
if (debug) {
printf("\nSIG%s--.newsrc not restored in debug\n",signame[signo]);
finalize(-1);
}
#endif
if (panic) {
#ifdef HAS_SIGBLOCK
sigsetmask(sigblock(0) & ~(sigmask(SIGILL) | sigmask(SIGIOT)));
#endif
abort();
}
(void) sigset(SIGILL,SIG_DFL);
panic = TRUE; /* disable terminal I/O */
if (doing_ng) { /* need we reconstitute rc line? */
yankback();
bits_to_rc(); /* then do so (hope this works) */
}
doing_ng = FALSE;
if (!write_newsrcs(multirc)) { /* write anything that's changed */
/*$$ get_old_newsrcs(multirc); ?? */
}
#ifdef KILLFILES
update_thread_kfile();
#endif
#ifdef SIGHUP
if (signo != SIGHUP) {
#endif
#ifdef VERBOSE
IF(verbose)
printf("\nCaught %s%s--.newsrc restored\n",
signo ? "a SIG" : "an internal error", signame[signo]);
ELSE
#endif
#ifdef TERSE
printf("\nSignal %d--bye bye\n",signo);
#endif
#ifdef SIGHUP
}
#endif
switch (signo) {
#ifdef SIGBUS
case SIGBUS:
#endif
case SIGILL:
case SIGSEGV:
finalize(-signo);
}
finalize(1); /* and blow up */
}
#ifdef SUPPORT_NNTP
Signal_t
pipe_catcher(signo)
int signo;
{
;/*$$ we lost the current nntp connection */
sigset(SIGPIPE,pipe_catcher);
}
#endif
/* come here on stop signal */
#ifdef SIGTSTP
Signal_t
stop_catcher(signo)
int signo;
{
if (!waiting) {
xmouse_off();
checkpoint_newsrcs(); /* good chance of crash while stopped */
if (bos_on_stop) {
goto_xy(0, LINES-1);
putchar('\n') FLUSH;
}
termlib_reset();
resetty(); /* this is the point of all this */
#ifdef DEBUG
if (debug)
write(2,"stop_catcher\n",13);
#endif
fflush(stdout);
sigset(signo,SIG_DFL); /* enable stop */
#ifdef HAS_SIGBLOCK
sigsetmask(sigblock(0) & ~(1 << (signo-1)));
#endif
kill(0,signo); /* and do the stop */
savetty();
#ifdef MAILCALL
mailcount = 0; /* force recheck */
#endif
if (!panic) {
if (!waiting) {
termlib_init();
noecho(); /* set no echo */
crmode(); /* set cbreak mode */
forceme("\f"); /* cause a refresh */
/* (defined only if TIOCSTI defined) */
errno = 0; /* needed for getcmd */
}
}
xmouse_check();
}
sigset(signo,stop_catcher); /* unenable the stop */
}
#endif
syntax highlighted by Code2HTML, v. 0.9.1