]> granicus.if.org Git - postgresql/blob - src/backend/utils/error/exc.c
Out-of-bounds memory allocation request sizes should be treated as just
[postgresql] / src / backend / utils / error / exc.c
1 /*-------------------------------------------------------------------------
2  *
3  * exc.c
4  *        POSTGRES exception handling code.
5  *
6  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        $Header: /cvsroot/pgsql/src/backend/utils/error/Attic/exc.c,v 1.36 2001/01/24 19:43:15 momjian Exp $
12  *
13  * NOTE
14  *        XXX this code needs improvement--check for state violations and
15  *        XXX reset after handling an exception.
16  *        XXX Probably should be merged with elog.c.
17  *
18  *-------------------------------------------------------------------------
19  */
20 #include "postgres.h"
21
22 #include <errno.h>
23
24 #include "storage/ipc.h"
25 #include "utils/exc.h"
26
27 extern int      errno;
28
29
30 static void ExcUnCaught(Exception *excP, ExcDetail detail, ExcData data,
31                         ExcMessage message);
32 static void ExcPrint(Exception *excP, ExcDetail detail, ExcData data,
33                  ExcMessage message);
34
35 /*
36  * Global Variables
37  */
38 static bool ExceptionHandlingEnabled = false;
39
40 char       *ExcFileName = NULL;
41 Index           ExcLineNumber = 0;
42
43 ExcFrame   *ExcCurFrameP = NULL;
44
45 static ExcProc *ExcUnCaughtP = NULL;
46
47 /*
48  * Exported Functions
49  */
50
51 /*
52  * EnableExceptionHandling
53  *              Enables/disables the exception handling system.
54  *
55  * Note:
56  *              This must be called before any exceptions occur.  I.e., call this first!
57  *              This routine will not return if an error is detected.
58  *              This does not follow the usual Enable... protocol.
59  *              This should be merged more closely with the error logging and tracing
60  *              packages.
61  *
62  * Exceptions:
63  *              none
64  */
65 /*
66  * Excection handling should be supported by the language, thus there should
67  * be no need to explicitly enable exception processing.
68  *
69  * This function should probably not be called, ever.  Currently it does
70  * almost nothing.      If there is a need for this intialization and checking.
71  * then this function should be converted to the new-style Enable code and
72  * called by all the other module Enable functions.
73  */
74 void
75 EnableExceptionHandling(bool on)
76 {
77         if (on == ExceptionHandlingEnabled)
78         {
79                 /* XXX add logging of failed state */
80                 proc_exit(255);
81                 /* ExitPostgres(FatalExitStatus); */
82         }
83
84         if (on)
85         {                                                       /* initialize */
86                 ;
87         }
88         else
89         {                                                       /* cleanup */
90                 ExcFileName = NULL;
91                 ExcLineNumber = 0;
92                 ExcCurFrameP = NULL;
93                 ExcUnCaughtP = NULL;
94         }
95
96         ExceptionHandlingEnabled = on;
97 }
98
99 static void
100 ExcPrint(Exception *excP,
101                  ExcDetail detail,
102                  ExcData data,
103                  ExcMessage message)
104 {
105         /* this buffer is only used if errno has a bogus value: */
106         char            errorstr_buf[32];
107         const char *errorstr;
108
109 #ifdef  lint
110         data = data;
111 #endif
112
113         /* Save error str before calling any function that might change errno */
114         errorstr = strerror(errno);
115         /*
116          * Some strerror()s return an empty string for out-of-range errno.
117          * This is ANSI C spec compliant, but not exactly useful.
118          */
119         if (errorstr == NULL || *errorstr == '\0')
120         {
121                 sprintf(errorstr_buf, "error %d", errno);
122                 errorstr = errorstr_buf;
123         }
124
125         fflush(stdout);                         /* In case stderr is buffered */
126
127         if (message != NULL)
128                 fprintf(stderr, "%s", message);
129         else if (excP->message != NULL)
130                 fprintf(stderr, "%s", excP->message);
131         else
132                 fprintf(stderr, "UNNAMED EXCEPTION %p", excP);
133
134         fprintf(stderr, " (%ld) [%s]\n", detail, errorstr);
135
136         fflush(stderr);
137 }
138
139 #ifdef NOT_USED
140 ExcProc    *
141 ExcGetUnCaught(void)
142 {
143         return ExcUnCaughtP;
144 }
145
146 #endif
147
148 #ifdef NOT_USED
149 ExcProc    *
150 ExcSetUnCaught(ExcProc *newP)
151 {
152         ExcProc    *oldP = ExcUnCaughtP;
153
154         ExcUnCaughtP = newP;
155
156         return oldP;
157 }
158
159 #endif
160
161 static void
162 ExcUnCaught(Exception *excP,
163                         ExcDetail detail,
164                         ExcData data,
165                         ExcMessage message)
166 {
167         ExcPrint(excP, detail, data, message);
168
169         ExcAbort(excP, detail, data, message);
170 }
171
172 void
173 ExcRaise(Exception *excP,
174                  ExcDetail detail,
175                  ExcData data,
176                  ExcMessage message)
177 {
178         ExcFrame   *efp;
179
180         efp = ExcCurFrameP;
181         if (efp == NULL)
182         {
183                 if (ExcUnCaughtP != NULL)
184                         (*ExcUnCaughtP) (excP, detail, data, message);
185
186                 ExcUnCaught(excP, detail, data, message);
187         }
188         else
189         {
190                 efp->id = excP;
191                 efp->detail = detail;
192                 efp->data = data;
193                 efp->message = message;
194
195                 ExcCurFrameP = efp->link;
196
197                 siglongjmp(efp->context, 1);
198         }
199 }