+/*
+ * err_shelve_state returns the current thread local error state
+ * and freezes the error module until err_unshelve_state is called.
+ */
+int err_shelve_state(void **state)
+{
+ if (!OPENSSL_init_crypto(OPENSSL_INIT_BASE_ONLY, NULL))
+ return 0;
+
+ if (!RUN_ONCE(&err_init, err_do_init))
+ return 0;
+
+ *state = CRYPTO_THREAD_get_local(&err_thread_local);
+ if (!CRYPTO_THREAD_set_local(&err_thread_local, (ERR_STATE*)-1))
+ return 0;
+
+ return 1;
+}
+
+/*
+ * err_unshelve_state restores the error state that was returned
+ * by err_shelve_state previously.
+ */
+void err_unshelve_state(void* state)
+{
+ if (state != (void*)-1)
+ CRYPTO_THREAD_set_local(&err_thread_local, (ERR_STATE*)state);
+}
+