Index: tclpkcs11.c ================================================================== --- tclpkcs11.c +++ tclpkcs11.c @@ -533,28 +533,36 @@ getFuncList = tclpkcs11_int_lookup_sym(handle, "C_GetFunctionList"); if (!getFuncList) { Tcl_SetObjResult(interp, Tcl_NewStringObj("unable to locate C_GetFunctionList symbol in PKCS#11 module", -1)); + tclpkcs11_int_unload_module(handle); + return(TCL_ERROR); } chk_rv = getFuncList(&pkcs11_function_list); if (chk_rv != CKR_OK) { Tcl_SetObjResult(interp, tclpkcs11_pkcs11_error(chk_rv)); + + tclpkcs11_int_unload_module(handle); return(TCL_ERROR); } if (!pkcs11_function_list) { Tcl_SetObjResult(interp, Tcl_NewStringObj("C_GetFunctionList returned invalid data", -1)); + tclpkcs11_int_unload_module(handle); + return(TCL_ERROR); } if (!pkcs11_function_list->C_Initialize) { Tcl_SetObjResult(interp, Tcl_NewStringObj("C_GetFunctionList returned incomplete data", -1)); + + tclpkcs11_int_unload_module(handle); return(TCL_ERROR); } initargs.CreateMutex = tclpkcs11_create_mutex; @@ -567,10 +575,12 @@ chk_rv = pkcs11_function_list->C_Initialize(&initargs); if (chk_rv != CKR_OK) { Tcl_SetObjResult(interp, tclpkcs11_pkcs11_error(chk_rv)); + tclpkcs11_int_unload_module(handle); + return(TCL_ERROR); } interpdata = (struct tclpkcs11_interpdata *) cd; @@ -579,10 +589,16 @@ (interpdata->handles_idx)++; tcl_handle_entry = Tcl_CreateHashEntry(&interpdata->handles, (const char *) tcl_handle, &is_new_entry); if (!tcl_handle_entry) { Tcl_SetObjResult(interp, Tcl_NewStringObj("unable to create new hash entry", -1)); + + if (pkcs11_function_list->C_Finalize) { + pkcs11_function_list->C_Finalize(NULL); + } + + tclpkcs11_int_unload_module(handle); return(TCL_ERROR); } /* Allocate the per-handle structure */