aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/err
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2003-06-11 20:49:58 +0000
committerRichard Levitte <levitte@openssl.org>2003-06-11 20:49:58 +0000
commit54f64516703cb090758369351a84e3df76868799 (patch)
tree9a03de66b753e87a3d1fca820d6de79416d96d76 /crypto/err
parent490967195a57553c2a8f6606d2a34f86d80b0257 (diff)
downloadopenssl-54f64516703cb090758369351a84e3df76868799.tar.gz
Add functionality to set marks on the error stack and to pop all errors to the next mark.
Diffstat (limited to 'crypto/err')
-rw-r--r--crypto/err/err.c51
-rw-r--r--crypto/err/err.h6
2 files changed, 52 insertions, 5 deletions
diff --git a/crypto/err/err.c b/crypto/err/err.c
index 1f943c82a0..2da71c01b7 100644
--- a/crypto/err/err.c
+++ b/crypto/err/err.c
@@ -548,13 +548,24 @@ static void build_SYS_str_reasons()
#endif
#define err_clear_data(p,i) \
+ do { \
if (((p)->err_data[i] != NULL) && \
(p)->err_data_flags[i] & ERR_TXT_MALLOCED) \
{ \
OPENSSL_free((p)->err_data[i]); \
(p)->err_data[i]=NULL; \
} \
- (p)->err_data_flags[i]=0;
+ (p)->err_data_flags[i]=0; \
+ } while(0)
+
+#define err_clear(p,i) \
+ do { \
+ es->err_flags[i]=0; \
+ es->err_buffer[i]=0; \
+ err_clear_data(p,i); \
+ es->err_file[i]=NULL; \
+ es->err_line[i]= -1; \
+ } while(0)
static void ERR_STATE_free(ERR_STATE *s)
{
@@ -645,6 +656,7 @@ void ERR_put_error(int lib, int func, int reason, const char *file,
es->top=(es->top+1)%ERR_NUM_ERRORS;
if (es->top == es->bottom)
es->bottom=(es->bottom+1)%ERR_NUM_ERRORS;
+ es->err_flags[es->top]=0;
es->err_buffer[es->top]=ERR_PACK(lib,func,reason);
es->err_file[es->top]=file;
es->err_line[es->top]=line;
@@ -660,10 +672,7 @@ void ERR_clear_error(void)
for (i=0; i<ERR_NUM_ERRORS; i++)
{
- es->err_buffer[i]=0;
- err_clear_data(es,i);
- es->err_file[i]=NULL;
- es->err_line[i]= -1;
+ err_clear(es,i);
}
es->top=es->bottom=0;
}
@@ -1034,3 +1043,35 @@ void ERR_add_error_data(int num, ...)
err:
va_end(args);
}
+
+int ERR_set_mark(void)
+ {
+ int i=0;
+ ERR_STATE *es;
+
+ es=ERR_get_state();
+
+ if (es->bottom == es->top) return 0;
+ es->err_flags[es->top]|=ERR_FLAG_MARK;
+ return 1;
+ }
+
+int ERR_pop_to_mark(void)
+ {
+ int i=0;
+ ERR_STATE *es;
+
+ es=ERR_get_state();
+
+ while(es->bottom != es->top
+ && (es->err_flags[es->top] & ERR_FLAG_MARK) == 0)
+ {
+ err_clear(es,es->top);
+ es->top-=1;
+ if (es->top == -1) es->top=ERR_NUM_ERRORS;
+ }
+
+ if (es->bottom == es->top) return 0;
+ es->err_flags[es->top]&=~ERR_FLAG_MARK;
+ return 1;
+ }
diff --git a/crypto/err/err.h b/crypto/err/err.h
index 08838190fd..1228acfe5c 100644
--- a/crypto/err/err.h
+++ b/crypto/err/err.h
@@ -88,10 +88,13 @@ extern "C" {
#define ERR_TXT_MALLOCED 0x01
#define ERR_TXT_STRING 0x02
+#define ERR_FLAG_MARK 0x01
+
#define ERR_NUM_ERRORS 16
typedef struct err_state_st
{
unsigned long pid;
+ int err_flags[ERR_NUM_ERRORS];
unsigned long err_buffer[ERR_NUM_ERRORS];
char *err_data[ERR_NUM_ERRORS];
int err_data_flags[ERR_NUM_ERRORS];
@@ -294,6 +297,9 @@ LHASH *ERR_get_err_state_table(void);
int ERR_get_next_error_library(void);
+int ERR_set_mark(void);
+int ERR_pop_to_mark(void);
+
/* This opaque type encapsulates the low-level error-state functions */
typedef struct st_ERR_FNS ERR_FNS;
/* An application can use this function and provide the return value to loaded