1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-10 17:42:29 +03:00
Files
postgres/src/backend/utils/error/exc.c
2001-10-25 05:50:21 +00:00

199 lines
4.1 KiB
C

/*-------------------------------------------------------------------------
*
* exc.c
* POSTGRES exception handling code.
*
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/error/Attic/exc.c,v 1.38 2001/10/25 05:49:46 momjian Exp $
*
* NOTE
* XXX this code needs improvement--check for state violations and
* XXX reset after handling an exception.
* XXX Probably should be merged with elog.c.
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include <errno.h>
#include "storage/ipc.h"
#include "utils/exc.h"
extern int errno;
static void ExcUnCaught(Exception *excP, ExcDetail detail, ExcData data,
ExcMessage message);
static void ExcPrint(Exception *excP, ExcDetail detail, ExcData data,
ExcMessage message);
/*
* Global Variables
*/
static bool ExceptionHandlingEnabled = false;
char *ExcFileName = NULL;
Index ExcLineNumber = 0;
ExcFrame *ExcCurFrameP = NULL;
static ExcProc *ExcUnCaughtP = NULL;
/*
* Exported Functions
*/
/*
* EnableExceptionHandling
* Enables/disables the exception handling system.
*
* Note:
* This must be called before any exceptions occur. I.e., call this first!
* This routine will not return if an error is detected.
* This does not follow the usual Enable... protocol.
* This should be merged more closely with the error logging and tracing
* packages.
*
* Exceptions:
* none
*/
/*
* Excection handling should be supported by the language, thus there should
* be no need to explicitly enable exception processing.
*
* This function should probably not be called, ever. Currently it does
* almost nothing. If there is a need for this intialization and checking.
* then this function should be converted to the new-style Enable code and
* called by all the other module Enable functions.
*/
void
EnableExceptionHandling(bool on)
{
if (on == ExceptionHandlingEnabled)
{
/* XXX add logging of failed state */
proc_exit(255);
/* ExitPostgres(FatalExitStatus); */
}
if (on)
{ /* initialize */
;
}
else
{ /* cleanup */
ExcFileName = NULL;
ExcLineNumber = 0;
ExcCurFrameP = NULL;
ExcUnCaughtP = NULL;
}
ExceptionHandlingEnabled = on;
}
static void
ExcPrint(Exception *excP,
ExcDetail detail,
ExcData data,
ExcMessage message)
{
/* this buffer is only used if errno has a bogus value: */
char errorstr_buf[32];
const char *errorstr;
#ifdef lint
data = data;
#endif
/* Save error str before calling any function that might change errno */
errorstr = strerror(errno);
/*
* Some strerror()s return an empty string for out-of-range errno.
* This is ANSI C spec compliant, but not exactly useful.
*/
if (errorstr == NULL || *errorstr == '\0')
{
sprintf(errorstr_buf, "error %d", errno);
errorstr = errorstr_buf;
}
fflush(stdout); /* In case stderr is buffered */
if (message != NULL)
fprintf(stderr, "%s", message);
else if (excP->message != NULL)
fprintf(stderr, "%s", excP->message);
else
fprintf(stderr, "UNNAMED EXCEPTION %p", excP);
fprintf(stderr, " (%ld) [%s]\n", detail, errorstr);
fflush(stderr);
}
#ifdef NOT_USED
ExcProc *
ExcGetUnCaught(void)
{
return ExcUnCaughtP;
}
#endif
#ifdef NOT_USED
ExcProc *
ExcSetUnCaught(ExcProc *newP)
{
ExcProc *oldP = ExcUnCaughtP;
ExcUnCaughtP = newP;
return oldP;
}
#endif
static void
ExcUnCaught(Exception *excP,
ExcDetail detail,
ExcData data,
ExcMessage message)
{
ExcPrint(excP, detail, data, message);
ExcAbort(excP, detail, data, message);
}
void
ExcRaise(Exception *excP,
ExcDetail detail,
ExcData data,
ExcMessage message)
{
ExcFrame *efp;
efp = ExcCurFrameP;
if (efp == NULL)
{
if (ExcUnCaughtP != NULL)
(*ExcUnCaughtP) (excP, detail, data, message);
ExcUnCaught(excP, detail, data, message);
}
else
{
efp->id = excP;
efp->detail = detail;
efp->data = data;
efp->message = message;
ExcCurFrameP = efp->link;
siglongjmp(efp->context, 1);
}
}