summaryrefslogtreecommitdiffstats
path: root/src/common/signal_chain.cpp
blob: e0c6b9d4e3f134b99e5d400c5bcae693aef2e798 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#include <dlfcn.h>

#include "common/assert.h"
#include "common/dynamic_library.h"
#include "common/scope_exit.h"
#include "common/signal_chain.h"

namespace Common {

template <typename T>
T* LookupLibcSymbol(const char* name) {
#if defined(__BIONIC__)
    Common::DynamicLibrary provider("libc.so");
    if (!provider.IsOpen()) {
        UNREACHABLE_MSG("Failed to open libc!");
    }
#else
    // For other operating environments, we assume the symbol is not overriden.
    const char* base = nullptr;
    Common::DynamicLibrary provider(base);
#endif

    void* sym = provider.GetSymbolAddress(name);
    if (sym == nullptr) {
        sym = dlsym(RTLD_DEFAULT, name);
    }
    if (sym == nullptr) {
        UNREACHABLE_MSG("Unable to find symbol {}!", name);
    }

    return reinterpret_cast<T*>(sym);
}

int SigAction(int signum, const struct sigaction* act, struct sigaction* oldact) {
    static auto libc_sigaction = LookupLibcSymbol<decltype(sigaction)>("sigaction");
    return libc_sigaction(signum, act, oldact);
}

} // namespace Common