<commit_before>/*
 * Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include "e_os.h"
#include "internal/cryptlib_int.h"
#include <openssl/err.h>
#include "internal/rand_int.h"
#include "internal/bio.h"
#include <openssl/evp.h>
#include "internal/evp_int.h"
#include "internal/conf.h"
#include "internal/async.h"
#include "internal/engine.h"
#include "internal/comp.h"
#include "internal/err.h"
#include "internal/err_int.h"
#include "internal/objects.h"
#include <stdlib.h>
#include <assert.h>
#include "internal/thread_once.h"
#include "internal/dso_conf.h"
#include "internal/dso.h"
#include "internal/store.h"

static int stopped = 0;

/*
 * Since per-thread-specific-data destructors are not universally
 * available, i.e. not on Windows, only below CRYPTO_THREAD_LOCAL key
 * is assumed to have destructor associated. And then an effort is made
 * to call this single destructor on non-pthread platform[s].
 *
 * Initial value is "impossible". It is used as guard value to shortcut
 * destructor for threads terminating before libcrypto is initialized or
 * after it's de-initialized. Access to the key doesn't have to be
 * serialized for the said threads, because they didn't use libcrypto
 * and it doesn't matter if they pick "impossible" or dereference real
 * key value and pull NULL past initialization in the first thread that
 * intends to use libcrypto.
 */
static union {
    long sane;
    CRYPTO_THREAD_LOCAL value;
} destructor_key = { -1 };

static void ossl_init_thread_stop(struct thread_local_inits_st *locals);

static void ossl_init_thread_destructor(void *local)
{
    ossl_init_thread_stop((struct thread_local_inits_st *)local);
}

static struct thread_local_inits_st *ossl_init_get_thread_local(int alloc)
{
    struct thread_local_inits_st *local =
        CRYPTO_THREAD_get_local(&destructor_key.value);

    if (alloc) {
        if (local == NULL
            && (local = OPENSSL_zalloc(sizeof(*local))) != NULL
            && !CRYPTO_THREAD_set_local(&destructor_key.value, local)) {
            OPENSSL_free(local);
            return NULL;
        }
    } else {
        CRYPTO_THREAD_set_local(&destructor_key.value, NULL);
    }

    return local;
}

typedef struct ossl_init_stop_st OPENSSL_INIT_STOP;
struct ossl_init_stop_st {
    void (*handler)(void);
    OPENSSL_INIT_STOP *next;
};

static OPENSSL_INIT_STOP *stop_handlers = NULL;
static CRYPTO_RWLOCK *init_lock = NULL;

static CRYPTO_ONCE base = CRYPTO_ONCE_STATIC_INIT;
static int base_inited = 0;
DEFINE_RUN_ONCE_STATIC(ossl_init_base)
{
    CRYPTO_THREAD_LOCAL key;

#ifdef OPENSSL_INIT_DEBUG
    fprintf(stderr, "OPENSSL_INIT: ossl_init_base: Setting up stop handlers\n");
#endif
#ifndef OPENSSL_NO_CRYPTO_MDEBUG
    ossl_malloc_setup_failures();
#endif
    if (!CRYPTO_THREAD_init_local(&key, ossl_init_thread_destructor))
        return 0;
    if ((init_lock = CRYPTO_THREAD_lock_new()) == NULL)
        goto err;
    OPENSSL_cpuid_setup();

    destructor_key.value = key;
    base_inited = 1;
    return 1;

err:
#ifdef OPENSSL_INIT_DEBUG
    fprintf(stderr, "OPENSSL_INIT: ossl_init_base not ok!\n");
#endif
    CRYPTO_THREAD_lock_free(init_lock);
    init_lock = NULL;

    CRYPTO_THREAD_cleanup_local(&key);
    return 0;
}

static CRYPTO_ONCE register_atexit = CRYPTO_ONCE_STATIC_INIT;
#if !defined(OPENSSL_SYS_UEFI) && defined(_WIN32)
static int win32atexit(void)
{
    OPENSSL_cleanup();
    return 0;
}
#endif

DEFINE_RUN_ONCE_STATIC(ossl_init_register_atexit)
{
#ifdef OPENSSL_INIT_DEBUG
    fprintf(stderr, "OPENSSL_INIT: ossl_init_register_atexit()\n");
#endif
#ifndef OPENSSL_SYS_UEFI
# ifdef _WIN32
    /* We use _onexit() in preference because it gets called on DLL unload */
    if (_onexit(win32atexit) == NULL)
        return 0;
# else
    if (atexit(OPENSSL_cleanup) != 0)
        return 0;
# endif
#endif

    return 1;
}

DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_register_atexit,
                           ossl_init_register_atexit)
{
#ifdef OPENSSL_INIT_DEBUG
    fprintf(stderr, "OPENSSL_INIT: ossl_init_no_register_atexit ok!\n");
#endif
    /* Do nothing in this case */
    return 1;
}
<commit_msg>atexit() call was moved, re-enabling it for AmiSSL - disable again<commit_after>/*
 * Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include "e_os.h"
#include "internal/cryptlib_int.h"
#include <openssl/err.h>
#include "internal/rand_int.h"
#include "internal/bio.h"
#include <openssl/evp.h>
#include "internal/evp_int.h"
#include "internal/conf.h"
#include "internal/async.h"
#include "internal/engine.h"
#include "internal/comp.h"
#include "internal/err.h"
#include "internal/err_int.h"
#include "internal/objects.h"
#include <stdlib.h>
#include <assert.h>
#include "internal/thread_once.h"
#include "internal/dso_conf.h"
#include "internal/dso.h"
#include "internal/store.h"

static int stopped = 0;

/*
 * Since per-thread-specific-data destructors are not universally
 * available, i.e. not on Windows, only below CRYPTO_THREAD_LOCAL key
 * is assumed to have destructor associated. And then an effort is made
 * to call this single destructor on non-pthread platform[s].
 *
 * Initial value is "impossible". It is used as guard value to shortcut
 * destructor for threads terminating before libcrypto is initialized or
 * after it's de-initialized. Access to the key doesn't have to be
 * serialized for the said threads, because they didn't use libcrypto
 * and it doesn't matter if they pick "impossible" or dereference real
 * key value and pull NULL past initialization in the first thread that
 * intends to use libcrypto.
 */
static union {
    long sane;
    CRYPTO_THREAD_LOCAL value;
} destructor_key = { -1 };

static void ossl_init_thread_stop(struct thread_local_inits_st *locals);

static void ossl_init_thread_destructor(void *local)
{
    ossl_init_thread_stop((struct thread_local_inits_st *)local);
}

static struct thread_local_inits_st *ossl_init_get_thread_local(int alloc)
{
    struct thread_local_inits_st *local =
        CRYPTO_THREAD_get_local(&destructor_key.value);

    if (alloc) {
        if (local == NULL
            && (local = OPENSSL_zalloc(sizeof(*local))) != NULL
            && !CRYPTO_THREAD_set_local(&destructor_key.value, local)) {
            OPENSSL_free(local);
            return NULL;
        }
    } else {
        CRYPTO_THREAD_set_local(&destructor_key.value, NULL);
    }

    return local;
}

typedef struct ossl_init_stop_st OPENSSL_INIT_STOP;
struct ossl_init_stop_st {
    void (*handler)(void);
    OPENSSL_INIT_STOP *next;
};

static OPENSSL_INIT_STOP *stop_handlers = NULL;
static CRYPTO_RWLOCK *init_lock = NULL;

static CRYPTO_ONCE base = CRYPTO_ONCE_STATIC_INIT;
static int base_inited = 0;
DEFINE_RUN_ONCE_STATIC(ossl_init_base)
{
    CRYPTO_THREAD_LOCAL key;

#ifdef OPENSSL_INIT_DEBUG
    fprintf(stderr, "OPENSSL_INIT: ossl_init_base: Setting up stop handlers\n");
#endif
#ifndef OPENSSL_NO_CRYPTO_MDEBUG
    ossl_malloc_setup_failures();
#endif
    if (!CRYPTO_THREAD_init_local(&key, ossl_init_thread_destructor))
        return 0;
    if ((init_lock = CRYPTO_THREAD_lock_new()) == NULL)
        goto err;
    OPENSSL_cpuid_setup();

    destructor_key.value = key;
    base_inited = 1;
    return 1;

err:
#ifdef OPENSSL_INIT_DEBUG
    fprintf(stderr, "OPENSSL_INIT: ossl_init_base not ok!\n");
#endif
    CRYPTO_THREAD_lock_free(init_lock);
    init_lock = NULL;

    CRYPTO_THREAD_cleanup_local(&key);
    return 0;
}

static CRYPTO_ONCE register_atexit = CRYPTO_ONCE_STATIC_INIT;
#if !defined(OPENSSL_SYS_UEFI) && defined(_WIN32)
static int win32atexit(void)
{
    OPENSSL_cleanup();
    return 0;
}
#endif

DEFINE_RUN_ONCE_STATIC(ossl_init_register_atexit)
{
#ifdef OPENSSL_INIT_DEBUG
    fprintf(stderr, "OPENSSL_INIT: ossl_init_register_atexit()\n");
#endif
#if !defined(OPENSSL_SYS_UEFI) && !defined(OPENSSL_SYS_AMIGA)
# ifdef _WIN32
    /* We use _onexit() in preference because it gets called on DLL unload */
    if (_onexit(win32atexit) == NULL)
        return 0;
# else
    if (atexit(OPENSSL_cleanup) != 0)
        return 0;
# endif
#endif

    return 1;
}

DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_register_atexit,
                           ossl_init_register_atexit)
{
#ifdef OPENSSL_INIT_DEBUG
    fprintf(stderr, "OPENSSL_INIT: ossl_init_no_register_atexit ok!\n");
#endif
    /* Do nothing in this case */
    return 1;
}

{'fraction_non_alphanumeric': 0.09647349505840072, 'fraction_numerical': 0.00651392632524708, 'mean_word_length': 4.186371578334304, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4853922', 'n_tokens_mistral': 3139, 'n_tokens_neox': 2985, 'n_words': 778}