some const fixes and cleanup
[openssl.git] / crypto / err / err.c
index 2da71c01b745fe301462a94ea3c30a4bdbbf1837..1d186a7b9bbdf8beefb4bc9c95fea797524d3da4 100644 (file)
@@ -226,6 +226,7 @@ struct st_ERR_FNS
        ERR_STRING_DATA *(*cb_err_del_item)(ERR_STRING_DATA *);
        /* Works on the "thread_hash" error-state table */
        LHASH *(*cb_thread_get)(int create);
+       void (*cb_thread_release)(LHASH **hash);
        ERR_STATE *(*cb_thread_get_item)(const ERR_STATE *);
        ERR_STATE *(*cb_thread_set_item)(ERR_STATE *);
        void (*cb_thread_del_item)(const ERR_STATE *);
@@ -240,6 +241,7 @@ static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *);
 static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *);
 static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *);
 static LHASH *int_thread_get(int create);
+static void int_thread_release(LHASH **hash);
 static ERR_STATE *int_thread_get_item(const ERR_STATE *);
 static ERR_STATE *int_thread_set_item(ERR_STATE *);
 static void int_thread_del_item(const ERR_STATE *);
@@ -253,6 +255,7 @@ static const ERR_FNS err_defaults =
        int_err_set_item,
        int_err_del_item,
        int_thread_get,
+       int_thread_release,
        int_thread_get_item,
        int_thread_set_item,
        int_thread_del_item,
@@ -272,6 +275,7 @@ static const ERR_FNS *err_fns = NULL;
  * and state in the loading application. */
 static LHASH *int_error_hash = NULL;
 static LHASH *int_thread_hash = NULL;
+static int int_thread_hash_references = 0;
 static int int_err_library_number= ERR_LIB_USER;
 
 /* Internal function that checks whether "err_fns" is set and if not, sets it to
@@ -418,11 +422,37 @@ static LHASH *int_thread_get(int create)
                CRYPTO_pop_info();
                }
        if (int_thread_hash)
+               {
+               int_thread_hash_references++;
                ret = int_thread_hash;
+               }
        CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
        return ret;
        }
 
+static void int_thread_release(LHASH **hash)
+       {
+       int i;
+
+       if (hash == NULL || *hash == NULL)
+               return;
+
+       i = CRYPTO_add(&int_thread_hash_references, -1, CRYPTO_LOCK_ERR);
+
+#ifdef REF_PRINT
+       fprintf(stderr,"%4d:%s\n",int_thread_hash_references,"ERR");
+#endif
+       if (i > 0) return;
+#ifdef REF_CHECK
+       if (i < 0)
+               {
+               fprintf(stderr,"int_thread_release, bad reference count\n");
+               abort(); /* ok */
+               }
+#endif
+       *hash = NULL;
+       }
+
 static ERR_STATE *int_thread_get_item(const ERR_STATE *d)
        {
        ERR_STATE *p;
@@ -437,6 +467,7 @@ static ERR_STATE *int_thread_get_item(const ERR_STATE *d)
        p = (ERR_STATE *)lh_retrieve(hash, d);
        CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
 
+       ERRFN(thread_release)(&hash);
        return p;
        }
 
@@ -454,6 +485,7 @@ static ERR_STATE *int_thread_set_item(ERR_STATE *d)
        p = (ERR_STATE *)lh_insert(hash, d);
        CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
 
+       ERRFN(thread_release)(&hash);
        return p;
        }
 
@@ -470,13 +502,15 @@ static void int_thread_del_item(const ERR_STATE *d)
        CRYPTO_w_lock(CRYPTO_LOCK_ERR);
        p = (ERR_STATE *)lh_delete(hash, d);
        /* make sure we don't leak memory */
-       if (int_thread_hash && (lh_num_items(int_thread_hash) == 0))
+       if (int_thread_hash_references == 1
+               && int_thread_hash && (lh_num_items(int_thread_hash) == 0))
                {
                lh_free(int_thread_hash);
                int_thread_hash = NULL;
                }
        CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
 
+       ERRFN(thread_release)(&hash);
        if (p)
                ERR_STATE_free(p);
        }
@@ -507,7 +541,7 @@ static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1];
  * will be returned for SYSerr(), which always gets an errno
  * value and never one of those 'standard' reason codes. */
 
-static void build_SYS_str_reasons()
+static void build_SYS_str_reasons(void)
        {
        /* OPENSSL_malloc cannot be used here, use static storage instead */
        static char strerror_tab[NUM_SYS_STR_REASONS][LEN_SYS_STR_REASON];
@@ -560,11 +594,11 @@ static void build_SYS_str_reasons()
 
 #define err_clear(p,i) \
        do { \
-       es->err_flags[i]=0; \
-       es->err_buffer[i]=0; \
+       (p)->err_flags[i]=0; \
+       (p)->err_buffer[i]=0; \
        err_clear_data(p,i); \
-       es->err_file[i]=NULL; \
-       es->err_line[i]= -1; \
+       (p)->err_file[i]=NULL; \
+       (p)->err_line[i]= -1; \
        } while(0)
 
 static void ERR_STATE_free(ERR_STATE *s)
@@ -855,6 +889,12 @@ LHASH *ERR_get_err_state_table(void)
        return ERRFN(thread_get)(0);
        }
 
+void ERR_release_err_state_table(LHASH **hash)
+       {
+       err_fns_check();
+       ERRFN(thread_release)(hash);
+       }
+
 const char *ERR_lib_error_string(unsigned long e)
        {
        ERR_STRING_DATA d,*p;
@@ -903,7 +943,7 @@ static unsigned long err_hash(const void *a_void)
        {
        unsigned long ret,l;
 
-       l=((ERR_STRING_DATA *)a_void)->error;
+       l=((const ERR_STRING_DATA *)a_void)->error;
        ret=l^ERR_GET_LIB(l)^ERR_GET_FUNC(l);
        return(ret^ret%19*13);
        }
@@ -911,21 +951,21 @@ static unsigned long err_hash(const void *a_void)
 /* static int err_cmp(ERR_STRING_DATA *a, ERR_STRING_DATA *b) */
 static int err_cmp(const void *a_void, const void *b_void)
        {
-       return((int)(((ERR_STRING_DATA *)a_void)->error -
-                       ((ERR_STRING_DATA *)b_void)->error));
+       return((int)(((const ERR_STRING_DATA *)a_void)->error -
+                       ((const ERR_STRING_DATA *)b_void)->error));
        }
 
 /* static unsigned long pid_hash(ERR_STATE *a) */
 static unsigned long pid_hash(const void *a_void)
        {
-       return(((ERR_STATE *)a_void)->pid*13);
+       return(((const ERR_STATE *)a_void)->pid*13);
        }
 
 /* static int pid_cmp(ERR_STATE *a, ERR_STATE *b) */
 static int pid_cmp(const void *a_void, const void *b_void)
        {
-       return((int)((long)((ERR_STATE *)a_void)->pid -
-                       (long)((ERR_STATE *)b_void)->pid));
+       return((int)((long)((const ERR_STATE *)a_void)->pid -
+                       (long)((const ERR_STATE *)b_void)->pid));
        }
 
 void ERR_remove_state(unsigned long pid)
@@ -1035,7 +1075,7 @@ void ERR_add_error_data(int num, ...)
                                else
                                        str=p;
                                }
-                       strcat(str,a);
+                       BUF_strlcat(str,a,(size_t)s+1);
                        }
                }
        ERR_set_error_data(str,ERR_TXT_MALLOCED|ERR_TXT_STRING);
@@ -1046,7 +1086,6 @@ err:
 
 int ERR_set_mark(void)
        {
-       int i=0;
        ERR_STATE *es;
 
        es=ERR_get_state();
@@ -1058,7 +1097,6 @@ int ERR_set_mark(void)
 
 int ERR_pop_to_mark(void)
        {
-       int i=0;
        ERR_STATE *es;
 
        es=ERR_get_state();