#if !defined(_GNU_SOURCE)
#define _GNU_SOURCE …
#endif
#include "../bcm_support.h"
#if defined(OPENSSL_FORK_DETECTION_MADVISE)
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/mman.h>
#if defined(MADV_WIPEONFORK)
static_assert;
#else
#define MADV_WIPEONFORK …
#endif
#elif defined(OPENSSL_FORK_DETECTION_PTHREAD_ATFORK)
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#endif
#include "../internal.h"
#if defined(OPENSSL_FORK_DETECTION_MADVISE)
static int g_force_madv_wipeonfork;
static int g_force_madv_wipeonfork_enabled;
static CRYPTO_once_t g_fork_detect_once = …;
static CRYPTO_MUTEX g_fork_detect_lock = …;
static CRYPTO_atomic_u32 * g_fork_detect_addr;
static uint64_t g_fork_generation;
static void init_fork_detect(void) { … }
uint64_t CRYPTO_get_fork_generation(void) { … }
void CRYPTO_fork_detect_force_madv_wipeonfork_for_testing(int on) { … }
#elif defined(OPENSSL_FORK_DETECTION_PTHREAD_ATFORK)
static CRYPTO_once_t g_pthread_fork_detection_once = CRYPTO_ONCE_INIT;
static uint64_t g_atfork_fork_generation;
static void we_are_forked(void) {
uint64_t value = g_atfork_fork_generation + 1;
if (value == 0) {
value = 1;
}
g_atfork_fork_generation = value;
}
static void init_pthread_fork_detection(void) {
if (pthread_atfork(NULL, NULL, we_are_forked) != 0) {
abort();
}
g_atfork_fork_generation = 1;
}
uint64_t CRYPTO_get_fork_generation(void) {
CRYPTO_once(&g_pthread_fork_detection_once, init_pthread_fork_detection);
return g_atfork_fork_generation;
}
#elif defined(OPENSSL_DOES_NOT_FORK)
uint64_t CRYPTO_get_fork_generation(void) { return 0xc0ffee; }
#else
uint64_t CRYPTO_get_fork_generation(void) { return 0; }
#endif