Blame src/LYexit.c

Packit f574b8
/*
Packit f574b8
 * $LynxId: LYexit.c,v 1.37 2018/03/21 00:50:51 tom Exp $
Packit f574b8
 *
Packit f574b8
 *	Copyright (c) 1994, University of Kansas, All Rights Reserved
Packit f574b8
 *	(most of this file was rewritten in 1996 and 2004).
Packit f574b8
 */
Packit f574b8
#include <HTUtils.h>
Packit f574b8
#include <LYexit.h>
Packit f574b8
#include <HTAlert.h>
Packit f574b8
#ifndef VMS
Packit f574b8
#include <LYGlobalDefs.h>
Packit f574b8
#include <LYUtils.h>
Packit f574b8
#include <LYSignal.h>
Packit f574b8
#include <LYMainLoop.h>
Packit f574b8
#endif /* !VMS */
Packit f574b8
#include <LYStrings.h>
Packit f574b8
#include <LYClean.h>
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * Flag for outofmem macro.  - FM
Packit f574b8
 */
Packit f574b8
BOOL LYOutOfMemory = FALSE;
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * Stack of functions to call upon exit.
Packit f574b8
 */
Packit f574b8
static void (*callstack[ATEXITSIZE]) (void);
Packit f574b8
static int topOfStack = 0;
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * Capture "atexit()" calls for our own accounting.
Packit f574b8
 */
Packit f574b8
int LYatexit(void (*function) (void))
Packit f574b8
{
Packit f574b8
    int result = 0;
Packit f574b8
Packit f574b8
    if (topOfStack >= ATEXITSIZE) {
Packit f574b8
	CTRACE((tfp, "(LY)atexit: Too many functions, ignoring one!\n"));
Packit f574b8
	result = -1;
Packit f574b8
    } else {
Packit f574b8
	int n;
Packit f574b8
	BOOLEAN found = FALSE;
Packit f574b8
Packit f574b8
	for (n = 0; n < topOfStack; ++n) {
Packit f574b8
	    if (callstack[n] == function) {
Packit f574b8
		found = TRUE;
Packit f574b8
		break;
Packit f574b8
	    }
Packit f574b8
	}
Packit f574b8
	if (!found) {
Packit f574b8
	    callstack[topOfStack++] = function;
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
    return result;
Packit f574b8
}
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * Purpose:		Call the functions registered with LYatexit
Packit f574b8
 * Arguments:		void
Packit f574b8
 * Return Value:	void
Packit f574b8
 * Remarks/Portability/Dependencies/Restrictions:
Packit f574b8
 * Revision History:
Packit f574b8
 *	06-15-94	created Lynx 2-3-1 Garrett Arch Blythe
Packit f574b8
 */
Packit f574b8
static void LYCompleteExit(void)
Packit f574b8
{
Packit f574b8
    /*
Packit f574b8
     * Just loop through registered functions.  This is reentrant if more exits
Packit f574b8
     * occur in the registered functions.
Packit f574b8
     */
Packit f574b8
    while (--topOfStack >= 0) {
Packit f574b8
	callstack[topOfStack] ();
Packit f574b8
    }
Packit f574b8
}
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * Purpose:		Terminates program, reports memory not freed.
Packit f574b8
 * Arguments:		status	Exit code.
Packit f574b8
 * Return Value:	void
Packit f574b8
 * Remarks/Portability/Dependencies/Restrictions:
Packit f574b8
 *	Function calls stdlib.h exit
Packit f574b8
 * Revision History:
Packit f574b8
 *	06-15-94	created Lynx 2-3-1 Garrett Arch Blythe
Packit f574b8
 */
Packit f574b8
void LYexit(int status)
Packit f574b8
{
Packit f574b8
#ifndef VMS			/*  On VMS, the VMSexit() handler does these. - FM */
Packit f574b8
#ifdef _WINDOWS
Packit f574b8
    DeleteCriticalSection(&critSec_READ);
Packit f574b8
Packit f574b8
    WSACleanup();
Packit f574b8
#endif
Packit f574b8
    if (LYOutOfMemory == TRUE) {
Packit f574b8
	/*
Packit f574b8
	 * Ignore further interrupts.  - FM
Packit f574b8
	 */
Packit f574b8
#ifndef NOSIGHUP
Packit f574b8
	(void) signal(SIGHUP, SIG_IGN);
Packit f574b8
#endif /* NOSIGHUP */
Packit f574b8
	(void) signal(SIGTERM, SIG_IGN);
Packit f574b8
	(void) signal(SIGINT, SIG_IGN);
Packit f574b8
#ifndef __linux__
Packit f574b8
#ifdef SIGBUS
Packit f574b8
	(void) signal(SIGBUS, SIG_IGN);
Packit f574b8
#endif /* SIGBUS */
Packit f574b8
#endif /* !__linux__ */
Packit f574b8
	(void) signal(SIGSEGV, SIG_IGN);
Packit f574b8
	(void) signal(SIGILL, SIG_IGN);
Packit f574b8
Packit f574b8
	/*
Packit f574b8
	 * Flush all messages.  - FM
Packit f574b8
	 */
Packit f574b8
	fflush(stderr);
Packit f574b8
	fflush(stdout);
Packit f574b8
Packit f574b8
	/*
Packit f574b8
	 * Deal with curses, if on, and clean up.  - FM
Packit f574b8
	 */
Packit f574b8
	if (LYCursesON) {
Packit f574b8
	    LYSleepAlert();
Packit f574b8
	}
Packit f574b8
	cleanup_sig(0);
Packit f574b8
#ifndef __linux__
Packit f574b8
#ifdef SIGBUS
Packit f574b8
	signal(SIGBUS, SIG_DFL);
Packit f574b8
#endif /* SIGBUS */
Packit f574b8
#endif /* !__linux__ */
Packit f574b8
	signal(SIGSEGV, SIG_DFL);
Packit f574b8
	signal(SIGILL, SIG_DFL);
Packit f574b8
    }
Packit f574b8
#endif /* !VMS */
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * Close syslog before doing atexit-cleanup, since it may use a string
Packit f574b8
     * that would be freed there.
Packit f574b8
     */
Packit f574b8
#ifdef SYSLOG_REQUESTED_URLS
Packit f574b8
    LYCloselog();
Packit f574b8
#endif
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * Do functions registered with LYatexit.  - GAB
Packit f574b8
     */
Packit f574b8
    LYCompleteExit();
Packit f574b8
Packit f574b8
    LYCloseCmdLogfile();
Packit f574b8
Packit f574b8
#ifdef exit
Packit f574b8
/*  Make sure we use stdlib exit and not LYexit. - GAB
Packit f574b8
*/
Packit f574b8
#undef exit
Packit f574b8
#endif /* exit */
Packit f574b8
Packit f574b8
    cleanup_files();		/* if someone starts with LYNXfoo: page */
Packit f574b8
#ifndef VMS			/*  On VMS, the VMSexit() handler does these. - FM */
Packit f574b8
    fflush(stderr);
Packit f574b8
    if (LYOutOfMemory == TRUE) {
Packit f574b8
	LYOutOfMemory = FALSE;
Packit f574b8
	printf("\r\n%s\r\n\r\n", MEMORY_EXHAUSTED_ABORT);
Packit f574b8
	fflush(stdout);
Packit f574b8
    }
Packit f574b8
    LYCloseTracelog();
Packit f574b8
#endif /* !VMS */
Packit f574b8
    show_alloc();
Packit f574b8
Packit f574b8
#if defined(NCURSES_VERSION) && defined(LY_FIND_LEAKS)
Packit f574b8
#if defined(HAVE__NC_FREE_AND_EXIT)
Packit f574b8
    _nc_free_and_exit(status);
Packit f574b8
#elif defined(HAVE__NC_FREEALL)
Packit f574b8
    _nc_freeall();
Packit f574b8
#endif
Packit f574b8
#endif /* NCURSES_VERSION */
Packit f574b8
Packit f574b8
    exit(status);
Packit f574b8
}
Packit f574b8
Packit f574b8
void outofmem(const char *fname,
Packit f574b8
	      const char *func)
Packit f574b8
{
Packit f574b8
    fprintf(stderr, "\n\n\n%s %s: %s\n", fname, func, MEMORY_EXHAUSTED_ABORTING);
Packit f574b8
    LYOutOfMemory = TRUE;
Packit f574b8
    LYexit(-1);
Packit f574b8
}