📄 ex_data.c
字号:
} } } CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); if(!p) CRYPTOerr(CRYPTO_F_DEF_GET_CLASS,ERR_R_MALLOC_FAILURE); return p; }/* Add a new method to the given EX_CLASS_ITEM and return the corresponding * index (or -1 for error). Handles locking. */static int def_add_index(EX_CLASS_ITEM *item, long argl, void *argp, CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) { int toret = -1; CRYPTO_EX_DATA_FUNCS *a = (CRYPTO_EX_DATA_FUNCS *)OPENSSL_malloc( sizeof(CRYPTO_EX_DATA_FUNCS)); if(!a) { CRYPTOerr(CRYPTO_F_DEF_ADD_INDEX,ERR_R_MALLOC_FAILURE); return -1; } a->argl=argl; a->argp=argp; a->new_func=new_func; a->dup_func=dup_func; a->free_func=free_func; CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); while (sk_CRYPTO_EX_DATA_FUNCS_num(item->meth) <= item->meth_num) { if (!sk_CRYPTO_EX_DATA_FUNCS_push(item->meth, NULL)) { CRYPTOerr(CRYPTO_F_DEF_ADD_INDEX,ERR_R_MALLOC_FAILURE); OPENSSL_free(a); goto err; } } toret = item->meth_num++; sk_CRYPTO_EX_DATA_FUNCS_set(item->meth, toret, a);err: CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); return toret; }/**************************************************************//* The functions in the default CRYPTO_EX_DATA_IMPL structure */static int int_new_class(void) { int toret; CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); toret = ex_class++; CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); return toret; }static void int_cleanup(void) { EX_DATA_CHECK(return;) lh_doall(ex_data, def_cleanup_cb); lh_free(ex_data); ex_data = NULL; impl = NULL; }static int int_get_new_index(int class_index, long argl, void *argp, CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) { EX_CLASS_ITEM *item = def_get_class(class_index); if(!item) return -1; return def_add_index(item, argl, argp, new_func, dup_func, free_func); }/* Thread-safe by copying a class's array of "CRYPTO_EX_DATA_FUNCS" entries in * the lock, then using them outside the lock. NB: Thread-safety only applies to * the global "ex_data" state (ie. class definitions), not thread-safe on 'ad' * itself. */static int int_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) { int mx,i; void *ptr; CRYPTO_EX_DATA_FUNCS **storage = NULL; EX_CLASS_ITEM *item = def_get_class(class_index); if(!item) /* error is already set */ return 0; ad->sk = NULL; CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA); mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth); if(mx > 0) { storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS*)); if(!storage) goto skip; for(i = 0; i < mx; i++) storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth,i); }skip: CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA); if((mx > 0) && !storage) { CRYPTOerr(CRYPTO_F_INT_NEW_EX_DATA,ERR_R_MALLOC_FAILURE); return 0; } for(i = 0; i < mx; i++) { if(storage[i] && storage[i]->new_func) { ptr = CRYPTO_get_ex_data(ad, i); storage[i]->new_func(obj,ptr,ad,i, storage[i]->argl,storage[i]->argp); } } if(storage) OPENSSL_free(storage); return 1; }/* Same thread-safety notes as for "int_new_ex_data" */static int int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from) { int mx, j, i; char *ptr; CRYPTO_EX_DATA_FUNCS **storage = NULL; EX_CLASS_ITEM *item; if(!from->sk) /* 'to' should be "blank" which *is* just like 'from' */ return 1; if((item = def_get_class(class_index)) == NULL) return 0; CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA); mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth); j = sk_num(from->sk); if(j < mx) mx = j; if(mx > 0) { storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS*)); if(!storage) goto skip; for(i = 0; i < mx; i++) storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth,i); }skip: CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA); if((mx > 0) && !storage) { CRYPTOerr(CRYPTO_F_INT_DUP_EX_DATA,ERR_R_MALLOC_FAILURE); return 0; } for(i = 0; i < mx; i++) { ptr = CRYPTO_get_ex_data(from, i); if(storage[i] && storage[i]->dup_func) storage[i]->dup_func(to,from,&ptr,i, storage[i]->argl,storage[i]->argp); CRYPTO_set_ex_data(to,i,ptr); } if(storage) OPENSSL_free(storage); return 1; }/* Same thread-safety notes as for "int_new_ex_data" */static void int_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) { int mx,i; EX_CLASS_ITEM *item; void *ptr; CRYPTO_EX_DATA_FUNCS **storage = NULL; if((item = def_get_class(class_index)) == NULL) return; CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA); mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth); if(mx > 0) { storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS*)); if(!storage) goto skip; for(i = 0; i < mx; i++) storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth,i); }skip: CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA); if((mx > 0) && !storage) { CRYPTOerr(CRYPTO_F_INT_FREE_EX_DATA,ERR_R_MALLOC_FAILURE); return; } for(i = 0; i < mx; i++) { if(storage[i] && storage[i]->free_func) { ptr = CRYPTO_get_ex_data(ad,i); storage[i]->free_func(obj,ptr,ad,i, storage[i]->argl,storage[i]->argp); } } if(storage) OPENSSL_free(storage); if(ad->sk) { sk_free(ad->sk); ad->sk=NULL; } }/********************************************************************//* API functions that defer all "state" operations to the "ex_data" * implementation we have set. *//* Obtain an index for a new class (not the same as getting a new index within * an existing class - this is actually getting a new *class*) */int CRYPTO_ex_data_new_class(void) { IMPL_CHECK return EX_IMPL(new_class)(); }/* Release all "ex_data" state to prevent memory leaks. This can't be made * thread-safe without overhauling a lot of stuff, and shouldn't really be * called under potential race-conditions anyway (it's for program shutdown * after all). */void CRYPTO_cleanup_all_ex_data(void) { IMPL_CHECK EX_IMPL(cleanup)(); }/* Inside an existing class, get/register a new index. */int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp, CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) { int ret = -1; IMPL_CHECK ret = EX_IMPL(get_new_index)(class_index, argl, argp, new_func, dup_func, free_func); return ret; }/* Initialise a new CRYPTO_EX_DATA for use in a particular class - including * calling new() callbacks for each index in the class used by this variable */int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) { IMPL_CHECK return EX_IMPL(new_ex_data)(class_index, obj, ad); }/* Duplicate a CRYPTO_EX_DATA variable - including calling dup() callbacks for * each index in the class used by this variable */int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from) { IMPL_CHECK return EX_IMPL(dup_ex_data)(class_index, to, from); }/* Cleanup a CRYPTO_EX_DATA variable - including calling free() callbacks for * each index in the class used by this variable */void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) { IMPL_CHECK EX_IMPL(free_ex_data)(class_index, obj, ad); }/* For a given CRYPTO_EX_DATA variable, set the value corresponding to a * particular index in the class used by this variable */int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val) { int i; if (ad->sk == NULL) { if ((ad->sk=sk_new_null()) == NULL) { CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA,ERR_R_MALLOC_FAILURE); return(0); } } i=sk_num(ad->sk); while (i <= idx) { if (!sk_push(ad->sk,NULL)) { CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA,ERR_R_MALLOC_FAILURE); return(0); } i++; } sk_set(ad->sk,idx,val); return(1); }/* For a given CRYPTO_EX_DATA_ variable, get the value corresponding to a * particular index in the class used by this variable */void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx) { if (ad->sk == NULL) return(0); else if (idx >= sk_num(ad->sk)) return(0); else return(sk_value(ad->sk,idx)); }IMPLEMENT_STACK_OF(CRYPTO_EX_DATA_FUNCS)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -