mirror of
https://github.com/kenzok8/small-package
synced 2025-01-05 11:36:47 +08:00
update 2024-10-07 20:38:53
This commit is contained in:
parent
4a680e90d9
commit
073258de65
@ -35,24 +35,6 @@ define Package/rblibtorrent/description
|
||||
full featured client, although it comes with a working example client.
|
||||
endef
|
||||
|
||||
TRY_SIGNAL_VERSION:=751a7e5a5be14892bcfdff1e63c653bcbf71cf39
|
||||
TRY_SIGNAL_FILE:=$(PKG_NAME)-try_signal-$(TRY_SIGNAL_VERSION).tar.xz
|
||||
define Download/try_signal
|
||||
VERSION:=$(TRY_SIGNAL_VERSION)
|
||||
SUBDIR:=deps/try_signal
|
||||
FILE:=$(TRY_SIGNAL_FILE)
|
||||
URL:=https://github.com/arvidn/try_signal.git
|
||||
MIRROR_HASH:=32a432e35e81c79f21c49744f00696c112e0deab45d15d91c61ceb63fe25a5f8
|
||||
PROTO:=git
|
||||
endef
|
||||
|
||||
$(eval $(call Download,try_signal))
|
||||
|
||||
define Build/Prepare
|
||||
$(Build/Prepare/Default)
|
||||
xzcat $(DL_DIR)/$(TRY_SIGNAL_FILE) | tar -C $(PKG_BUILD_DIR) $(TAR_OPTIONS)
|
||||
endef
|
||||
|
||||
TARGET_CFLAGS += $(FPIC) -ffunction-sections -fdata-sections
|
||||
TARGET_LDFLAGS += -Wl,--gc-sections,--as-needed
|
||||
|
||||
|
6
rblibtorrent/src/deps/try_signal/CMakeLists.txt
Normal file
6
rblibtorrent/src/deps/try_signal/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
||||
cmake_minimum_required(VERSION 2.8.12)
|
||||
project(try_signal)
|
||||
|
||||
add_library(try_signal signal_error_code try_signal)
|
||||
target_include_directories(try_signal PUBLIC .)
|
||||
|
18
rblibtorrent/src/deps/try_signal/Jamfile
Normal file
18
rblibtorrent/src/deps/try_signal/Jamfile
Normal file
@ -0,0 +1,18 @@
|
||||
lib try_signal
|
||||
: # sources
|
||||
signal_error_code.cpp try_signal.cpp
|
||||
: # requirements
|
||||
: # default build
|
||||
<link>static
|
||||
: # usage requirements
|
||||
<include>.
|
||||
;
|
||||
|
||||
exe test : test.cpp : <library>try_signal <link>static ;
|
||||
explicit test ;
|
||||
|
||||
exe example : example.cpp : <library>try_signal <link>static ;
|
||||
explicit example ;
|
||||
|
||||
install stage_test : test : <location>. ;
|
||||
|
29
rblibtorrent/src/deps/try_signal/LICENSE
Normal file
29
rblibtorrent/src/deps/try_signal/LICENSE
Normal file
@ -0,0 +1,29 @@
|
||||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) 2016, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
53
rblibtorrent/src/deps/try_signal/README.rst
Normal file
53
rblibtorrent/src/deps/try_signal/README.rst
Normal file
@ -0,0 +1,53 @@
|
||||
try_signal
|
||||
==========
|
||||
|
||||
.. image:: https://travis-ci.org/arvidn/try_signal.svg?branch=master
|
||||
:target: https://travis-ci.org/arvidn/try_signal
|
||||
|
||||
.. image:: https://ci.appveyor.com/api/projects/status/le8jjroaai8081f1?svg=true
|
||||
:target: https://ci.appveyor.com/project/arvidn/try-signal/branch/master
|
||||
|
||||
The ``try_signal`` library provide a way to turn signals into C++ exceptions.
|
||||
This is especially useful when performing disk I/O via memory mapped files,
|
||||
where I/O errors are reported as ``SIGBUS`` and ``SIGSEGV`` or as structured
|
||||
exceptions on windows.
|
||||
|
||||
The function ``try_signal`` takes a function object that will be executed once.
|
||||
If the function causes a signal (or structured exception) to be raised, it will
|
||||
throw a C++ exception. Note that RAII may not be relied upon within this function.
|
||||
It may not rely on destructors being called. Stick to simple operations like
|
||||
memcopy.
|
||||
|
||||
Example::
|
||||
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include <numeric>
|
||||
#include "try_signal.hpp"
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
int main() try
|
||||
{
|
||||
int fd = open("test_file", O_RDWR);
|
||||
void* map = mmap(nullptr, 1024, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
|
||||
std::vector<char> buf(1024);
|
||||
std::iota(buf.begin(), buf.end(), 0);
|
||||
|
||||
// disk full or access after EOF are reported as exceptions
|
||||
sig::try_signal([&]{
|
||||
std::memcpy(map, buf.data(), buf.size());
|
||||
});
|
||||
|
||||
munmap(map, 1024);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
fprintf(stderr, "exited with exception: %s\n", e.what());
|
||||
return 1;
|
||||
}
|
||||
|
50
rblibtorrent/src/deps/try_signal/appveyor.yml
Normal file
50
rblibtorrent/src/deps/try_signal/appveyor.yml
Normal file
@ -0,0 +1,50 @@
|
||||
version: "{build}"
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
os: Visual Studio 2015
|
||||
clone_depth: 1
|
||||
environment:
|
||||
matrix:
|
||||
- variant: debug
|
||||
compiler: msvc-14.0
|
||||
model: 64
|
||||
- variant: debug
|
||||
compiler: msvc-14.0
|
||||
model: 32
|
||||
- variant: release
|
||||
compiler: msvc-14.0
|
||||
model: 64
|
||||
- variant: debug
|
||||
compiler: gcc
|
||||
model: 32
|
||||
- variant: debug
|
||||
compiler: gcc
|
||||
model: 64
|
||||
- variant: release
|
||||
compiler: gcc
|
||||
model: 32
|
||||
|
||||
install:
|
||||
- set ROOT_DIRECTORY=%CD%
|
||||
- set BOOST_ROOT=c:\Libraries\boost_1_67_0
|
||||
- set BOOST_BUILD_PATH=%BOOST_ROOT%\tools\build
|
||||
- echo %BOOST_ROOT%
|
||||
- echo %BOOST_BUILD_PATH%
|
||||
- set PATH=%PATH%;%BOOST_BUILD_PATH%\src\engine\bin.ntx86
|
||||
- ps: '"using msvc : 14.0 ;`nusing gcc : : : <cxxflags>-std=c++11 ;" | Set-Content $env:HOMEDRIVE\$env:HOMEPATH\user-config.jam'
|
||||
- type %HOMEDRIVE%%HOMEPATH%\user-config.jam
|
||||
- set PATH=c:\msys64\mingw32\bin;%PATH%
|
||||
- g++ --version
|
||||
- python --version
|
||||
- echo %ROOT_DIRECTORY%
|
||||
- cd %BOOST_BUILD_PATH%\src\engine
|
||||
- build.bat >nul
|
||||
- cd %ROOT_DIRECTORY%
|
||||
|
||||
build_script:
|
||||
# examples
|
||||
- b2.exe warnings=all warnings-as-errors=on -j2 %compiler% address-model=%model% variant=%variant% stage_test
|
||||
|
||||
test_script:
|
||||
- test
|
31
rblibtorrent/src/deps/try_signal/example.cpp
Normal file
31
rblibtorrent/src/deps/try_signal/example.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include <numeric>
|
||||
#include "try_signal.hpp"
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
int main() try
|
||||
{
|
||||
int fd = open("test_file", O_RDWR);
|
||||
void* map = mmap(nullptr, 1024, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
|
||||
std::vector<char> buf(1024);
|
||||
std::iota(buf.begin(), buf.end(), 0);
|
||||
|
||||
// disk full or access after EOF are reported as exceptions
|
||||
sig::try_signal([&]{
|
||||
std::memcpy(map, buf.data(), buf.size());
|
||||
});
|
||||
|
||||
munmap(map, 1024);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
fprintf(stderr, "exited with exception: %s\n", e.what());
|
||||
return 1;
|
||||
}
|
||||
|
0
rblibtorrent/src/deps/try_signal/project-root.jam
Normal file
0
rblibtorrent/src/deps/try_signal/project-root.jam
Normal file
209
rblibtorrent/src/deps/try_signal/signal_error_code.cpp
Normal file
209
rblibtorrent/src/deps/try_signal/signal_error_code.cpp
Normal file
@ -0,0 +1,209 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2016, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include <system_error>
|
||||
#include <string>
|
||||
|
||||
#include "signal_error_code.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
struct signal_error_category : std::error_category
|
||||
{
|
||||
const char* name() const noexcept override
|
||||
{ return "signal"; }
|
||||
std::string message(int ev) const noexcept override
|
||||
{
|
||||
#define SIGNAL_CASE(x) case sig::errors::error_code_enum:: x: return #x;
|
||||
switch (ev)
|
||||
{
|
||||
SIGNAL_CASE(abort)
|
||||
SIGNAL_CASE(alarm)
|
||||
SIGNAL_CASE(arithmetic_exception)
|
||||
SIGNAL_CASE(hangup)
|
||||
SIGNAL_CASE(illegal)
|
||||
SIGNAL_CASE(interrupt)
|
||||
SIGNAL_CASE(kill)
|
||||
SIGNAL_CASE(pipe)
|
||||
SIGNAL_CASE(quit)
|
||||
case sig::errors::error_code_enum::segmentation: return "segmentation fault";
|
||||
SIGNAL_CASE(terminate)
|
||||
SIGNAL_CASE(user1)
|
||||
SIGNAL_CASE(user2)
|
||||
SIGNAL_CASE(child)
|
||||
SIGNAL_CASE(cont)
|
||||
SIGNAL_CASE(stop)
|
||||
SIGNAL_CASE(terminal_stop)
|
||||
SIGNAL_CASE(terminal_in)
|
||||
SIGNAL_CASE(terminal_out)
|
||||
SIGNAL_CASE(bus)
|
||||
#ifdef SIGPOLL
|
||||
SIGNAL_CASE(poll)
|
||||
#endif
|
||||
SIGNAL_CASE(profiler)
|
||||
SIGNAL_CASE(system_call)
|
||||
SIGNAL_CASE(trap)
|
||||
SIGNAL_CASE(urgent_data)
|
||||
SIGNAL_CASE(virtual_timer)
|
||||
SIGNAL_CASE(cpu_limit)
|
||||
SIGNAL_CASE(file_size_limit)
|
||||
default: return "unknown";
|
||||
}
|
||||
#undef SIGNAL_CASE
|
||||
}
|
||||
std::error_condition default_error_condition(int ev) const noexcept override
|
||||
{ return {ev, *this}; }
|
||||
};
|
||||
} // anonymous namespace
|
||||
|
||||
namespace sig {
|
||||
namespace errors {
|
||||
|
||||
std::error_code make_error_code(error_code_enum e)
|
||||
{
|
||||
return {e, sig_category()};
|
||||
}
|
||||
|
||||
std::error_condition make_error_condition(error_code_enum e)
|
||||
{
|
||||
return {e, sig_category()};
|
||||
}
|
||||
|
||||
} // namespace errors
|
||||
|
||||
std::error_category& sig_category()
|
||||
{
|
||||
static signal_error_category signal_category;
|
||||
return signal_category;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
namespace {
|
||||
sig::errors::error_code_enum map_exception_code(int const ev)
|
||||
{
|
||||
switch (ev)
|
||||
{
|
||||
case seh_errors::error_code_enum::access_violation:
|
||||
case seh_errors::error_code_enum::array_bounds_exceeded:
|
||||
case seh_errors::error_code_enum::guard_page:
|
||||
case seh_errors::error_code_enum::stack_overflow:
|
||||
case seh_errors::error_code_enum::flt_stack_check:
|
||||
case seh_errors::error_code_enum::in_page_error:
|
||||
return sig::errors::segmentation;
|
||||
case seh_errors::error_code_enum::breakpoint:
|
||||
case seh_errors::error_code_enum::single_step:
|
||||
return sig::errors::trap;
|
||||
case seh_errors::error_code_enum::datatype_misalignment:
|
||||
return sig::errors::bus;
|
||||
case seh_errors::error_code_enum::flt_denormal_operand:
|
||||
case seh_errors::error_code_enum::flt_divide_by_zero:
|
||||
case seh_errors::error_code_enum::flt_inexact_result:
|
||||
case seh_errors::error_code_enum::flt_invalid_operation:
|
||||
case seh_errors::error_code_enum::flt_overflow:
|
||||
case seh_errors::error_code_enum::flt_underflow:
|
||||
case seh_errors::error_code_enum::int_divide_by_zero:
|
||||
case seh_errors::error_code_enum::int_overflow:
|
||||
return sig::errors::arithmetic_exception;
|
||||
case seh_errors::error_code_enum::illegal_instruction:
|
||||
case seh_errors::error_code_enum::invalid_disposition:
|
||||
case seh_errors::error_code_enum::priv_instruction:
|
||||
case seh_errors::error_code_enum::noncontinuable_exception:
|
||||
case seh_errors::error_code_enum::status_unwind_consolidate:
|
||||
return sig::errors::illegal;
|
||||
case seh_errors::error_code_enum::invalid_handle:
|
||||
return sig::errors::pipe;
|
||||
default:
|
||||
return sig::errors::illegal;
|
||||
}
|
||||
}
|
||||
|
||||
struct seh_error_category : std::error_category
|
||||
{
|
||||
const char* name() const noexcept override
|
||||
{ return "SEH"; }
|
||||
std::string message(int ev) const noexcept override
|
||||
{
|
||||
#define SIGNAL_CASE(x) case sig::seh_errors::error_code_enum:: x: return #x;
|
||||
switch (ev)
|
||||
{
|
||||
SIGNAL_CASE(access_violation)
|
||||
SIGNAL_CASE(array_bounds_exceeded)
|
||||
SIGNAL_CASE(guard_page)
|
||||
SIGNAL_CASE(stack_overflow)
|
||||
SIGNAL_CASE(flt_stack_check)
|
||||
SIGNAL_CASE(in_page_error)
|
||||
SIGNAL_CASE(breakpoint)
|
||||
SIGNAL_CASE(single_step)
|
||||
SIGNAL_CASE(datatype_misalignment)
|
||||
SIGNAL_CASE(flt_denormal_operand)
|
||||
SIGNAL_CASE(flt_divide_by_zero)
|
||||
SIGNAL_CASE(flt_inexact_result)
|
||||
SIGNAL_CASE(flt_invalid_operation)
|
||||
SIGNAL_CASE(flt_overflow)
|
||||
SIGNAL_CASE(flt_underflow)
|
||||
SIGNAL_CASE(int_divide_by_zero)
|
||||
SIGNAL_CASE(int_overflow)
|
||||
SIGNAL_CASE(illegal_instruction)
|
||||
SIGNAL_CASE(invalid_disposition)
|
||||
SIGNAL_CASE(priv_instruction)
|
||||
SIGNAL_CASE(noncontinuable_exception)
|
||||
SIGNAL_CASE(status_unwind_consolidate)
|
||||
SIGNAL_CASE(invalid_handle)
|
||||
default: return "unknown";
|
||||
}
|
||||
#undef SIGNAL_CASE
|
||||
}
|
||||
std::error_condition default_error_condition(int ev) const noexcept override
|
||||
{ return std::error_condition(map_exception_code(ev), sig_category()); }
|
||||
};
|
||||
} // anonymous namespace
|
||||
|
||||
namespace seh_errors {
|
||||
|
||||
std::error_code make_error_code(error_code_enum e)
|
||||
{
|
||||
return {static_cast<int>(e), seh_category()};
|
||||
}
|
||||
|
||||
} // namespace errors
|
||||
|
||||
std::error_category& seh_category()
|
||||
{
|
||||
static seh_error_category seh_category;
|
||||
return seh_category;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace sig
|
||||
|
162
rblibtorrent/src/deps/try_signal/signal_error_code.hpp
Normal file
162
rblibtorrent/src/deps/try_signal/signal_error_code.hpp
Normal file
@ -0,0 +1,162 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2016, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef SIGNAL_ERROR_CODE_HPP_INCLUDED
|
||||
#define SIGNAL_ERROR_CODE_HPP_INCLUDED
|
||||
|
||||
#include <signal.h>
|
||||
#include <system_error>
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#include <excpt.h>
|
||||
#else
|
||||
#include <eh.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace sig {
|
||||
namespace errors {
|
||||
|
||||
#ifdef _WIN32
|
||||
#define SIG_ENUM(name, sig) name,
|
||||
#else
|
||||
#define SIG_ENUM(name, sig) name = sig,
|
||||
#endif
|
||||
|
||||
enum error_code_enum: int
|
||||
{
|
||||
SIG_ENUM(abort, SIGABRT)
|
||||
SIG_ENUM(alarm, SIGALRM)
|
||||
SIG_ENUM(arithmetic_exception, SIGFPE)
|
||||
SIG_ENUM(hangup, SIGHUP)
|
||||
SIG_ENUM(illegal, SIGILL)
|
||||
SIG_ENUM(interrupt, SIGINT)
|
||||
SIG_ENUM(kill, SIGKILL)
|
||||
SIG_ENUM(pipe, SIGPIPE)
|
||||
SIG_ENUM(quit, SIGQUIT)
|
||||
SIG_ENUM(segmentation, SIGSEGV)
|
||||
SIG_ENUM(terminate, SIGTERM)
|
||||
SIG_ENUM(user1, SIGUSR1)
|
||||
SIG_ENUM(user2, SIGUSR2)
|
||||
SIG_ENUM(child, SIGCHLD)
|
||||
SIG_ENUM(cont, SIGCONT)
|
||||
SIG_ENUM(stop, SIGSTOP)
|
||||
SIG_ENUM(terminal_stop, SIGTSTP)
|
||||
SIG_ENUM(terminal_in, SIGTTIN)
|
||||
SIG_ENUM(terminal_out, SIGTTOU)
|
||||
SIG_ENUM(bus, SIGBUS)
|
||||
#ifdef SIGPOLL
|
||||
SIG_ENUM(poll, SIGPOLL)
|
||||
#endif
|
||||
SIG_ENUM(profiler, SIGPROF)
|
||||
SIG_ENUM(system_call, SIGSYS)
|
||||
SIG_ENUM(trap, SIGTRAP)
|
||||
SIG_ENUM(urgent_data, SIGURG)
|
||||
SIG_ENUM(virtual_timer, SIGVTALRM)
|
||||
SIG_ENUM(cpu_limit, SIGXCPU)
|
||||
SIG_ENUM(file_size_limit, SIGXFSZ)
|
||||
};
|
||||
|
||||
#undef SIG_ENUM
|
||||
|
||||
std::error_code make_error_code(error_code_enum e);
|
||||
std::error_condition make_error_condition(error_code_enum e);
|
||||
|
||||
} // namespace errors
|
||||
|
||||
std::error_category& sig_category();
|
||||
|
||||
#ifdef _WIN32
|
||||
namespace seh_errors {
|
||||
|
||||
// standard error codes are "int", the win32 exceptions are DWORD (i.e.
|
||||
// unsigned int). We coerce them into int here for compatibility, and we're
|
||||
// not concerned about their arithmetic
|
||||
enum error_code_enum: int
|
||||
{
|
||||
access_violation = int(EXCEPTION_ACCESS_VIOLATION),
|
||||
array_bounds_exceeded = int(EXCEPTION_ARRAY_BOUNDS_EXCEEDED),
|
||||
guard_page = int(EXCEPTION_GUARD_PAGE),
|
||||
stack_overflow = int(EXCEPTION_STACK_OVERFLOW),
|
||||
flt_stack_check = int(EXCEPTION_FLT_STACK_CHECK),
|
||||
in_page_error = int(EXCEPTION_IN_PAGE_ERROR),
|
||||
breakpoint = int(EXCEPTION_BREAKPOINT),
|
||||
single_step = int(EXCEPTION_SINGLE_STEP),
|
||||
datatype_misalignment = int(EXCEPTION_DATATYPE_MISALIGNMENT),
|
||||
flt_denormal_operand = int(EXCEPTION_FLT_DENORMAL_OPERAND),
|
||||
flt_divide_by_zero = int(EXCEPTION_FLT_DIVIDE_BY_ZERO),
|
||||
flt_inexact_result = int(EXCEPTION_FLT_INEXACT_RESULT),
|
||||
flt_invalid_operation = int(EXCEPTION_FLT_INVALID_OPERATION),
|
||||
flt_overflow = int(EXCEPTION_FLT_OVERFLOW),
|
||||
flt_underflow = int(EXCEPTION_FLT_UNDERFLOW),
|
||||
int_divide_by_zero = int(EXCEPTION_INT_DIVIDE_BY_ZERO),
|
||||
int_overflow = int(EXCEPTION_INT_OVERFLOW),
|
||||
illegal_instruction = int(EXCEPTION_ILLEGAL_INSTRUCTION),
|
||||
invalid_disposition = int(EXCEPTION_INVALID_DISPOSITION),
|
||||
priv_instruction = int(EXCEPTION_PRIV_INSTRUCTION),
|
||||
noncontinuable_exception = int(EXCEPTION_NONCONTINUABLE_EXCEPTION),
|
||||
status_unwind_consolidate = int(STATUS_UNWIND_CONSOLIDATE),
|
||||
invalid_handle = int(EXCEPTION_INVALID_HANDLE),
|
||||
};
|
||||
|
||||
std::error_code make_error_code(error_code_enum e);
|
||||
}
|
||||
|
||||
std::error_category& seh_category();
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
} // namespace sig
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<>
|
||||
struct is_error_code_enum<sig::errors::error_code_enum> : std::true_type {};
|
||||
|
||||
template<>
|
||||
struct is_error_condition_enum<sig::errors::error_code_enum> : std::true_type {};
|
||||
|
||||
#ifdef _WIN32
|
||||
template<>
|
||||
struct is_error_code_enum<sig::seh_errors::error_code_enum> : std::true_type {};
|
||||
#endif
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif
|
||||
|
47
rblibtorrent/src/deps/try_signal/test.cpp
Normal file
47
rblibtorrent/src/deps/try_signal/test.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
#include <stdexcept>
|
||||
#include <array>
|
||||
#include <cstring> // for memcpy
|
||||
|
||||
#include "try_signal.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
char const buf[] = "test...test";
|
||||
char dest[sizeof(buf)];
|
||||
|
||||
{
|
||||
sig::try_signal([&]{
|
||||
std::memcpy(dest, buf, sizeof(buf));
|
||||
});
|
||||
if (!std::equal(buf, buf + sizeof(buf), dest)) {
|
||||
fprintf(stderr, "ERROR: buffer not copied correctly\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
void* invalid_pointer = nullptr;
|
||||
sig::try_signal([&]{
|
||||
std::memcpy(dest, buf, sizeof(buf));
|
||||
std::memcpy(dest, invalid_pointer, sizeof(buf));
|
||||
});
|
||||
}
|
||||
catch (std::system_error const& e)
|
||||
{
|
||||
if (e.code() != std::error_condition(sig::errors::segmentation)) {
|
||||
fprintf(stderr, "ERROR: expected segmentaiton violation error\n");
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "OK\n");
|
||||
}
|
||||
fprintf(stderr, "exited with expected system_error exception: %s\n", e.what());
|
||||
|
||||
// we expect this to happen, so return 0
|
||||
return e.code() == std::error_condition(sig::errors::segmentation) ? 0 : 1;
|
||||
}
|
||||
|
||||
// return non-zero here because we don't expect this
|
||||
fprintf(stderr, "ERROR: expected exit through exception\n");
|
||||
return 1;
|
||||
}
|
||||
|
144
rblibtorrent/src/deps/try_signal/try_signal.cpp
Normal file
144
rblibtorrent/src/deps/try_signal/try_signal.cpp
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2016, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
#include <system_error>
|
||||
#include <atomic>
|
||||
#include <csetjmp>
|
||||
#include <csignal>
|
||||
|
||||
#include "try_signal.hpp"
|
||||
|
||||
#if !defined _WIN32
|
||||
// linux
|
||||
|
||||
namespace sig {
|
||||
namespace detail {
|
||||
|
||||
namespace {
|
||||
thread_local sigjmp_buf* jmpbuf = nullptr;
|
||||
}
|
||||
|
||||
std::atomic_flag once = ATOMIC_FLAG_INIT;
|
||||
|
||||
scoped_jmpbuf::scoped_jmpbuf(sigjmp_buf* ptr)
|
||||
{
|
||||
_previous_ptr = jmpbuf;
|
||||
jmpbuf = ptr;
|
||||
std::atomic_signal_fence(std::memory_order_release);
|
||||
}
|
||||
|
||||
scoped_jmpbuf::~scoped_jmpbuf() { jmpbuf = _previous_ptr; }
|
||||
|
||||
void handler(int const signo, siginfo_t*, void*)
|
||||
{
|
||||
std::atomic_signal_fence(std::memory_order_acquire);
|
||||
if (jmpbuf)
|
||||
siglongjmp(*jmpbuf, signo);
|
||||
|
||||
// this signal was not caused within the scope of a try_signal object,
|
||||
// invoke the default handler
|
||||
signal(signo, SIG_DFL);
|
||||
raise(signo);
|
||||
}
|
||||
|
||||
void setup_handler()
|
||||
{
|
||||
struct sigaction sa;
|
||||
sa.sa_sigaction = &sig::detail::handler;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = SA_SIGINFO;
|
||||
sigaction(SIGSEGV, &sa, nullptr);
|
||||
sigaction(SIGBUS, &sa, nullptr);
|
||||
}
|
||||
|
||||
} // detail namespace
|
||||
} // sig namespace
|
||||
|
||||
#elif __GNUC__
|
||||
// mingw
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
namespace sig {
|
||||
namespace detail {
|
||||
|
||||
thread_local jmp_buf* jmpbuf = nullptr;
|
||||
|
||||
long CALLBACK handler(EXCEPTION_POINTERS* pointers)
|
||||
{
|
||||
std::atomic_signal_fence(std::memory_order_acquire);
|
||||
if (jmpbuf)
|
||||
longjmp(*jmpbuf, pointers->ExceptionRecord->ExceptionCode);
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
scoped_handler::scoped_handler(jmp_buf* ptr)
|
||||
{
|
||||
_previous_ptr = jmpbuf;
|
||||
jmpbuf = ptr;
|
||||
std::atomic_signal_fence(std::memory_order_release);
|
||||
_handle = AddVectoredExceptionHandler(1, sig::detail::handler);
|
||||
}
|
||||
scoped_handler::~scoped_handler()
|
||||
{
|
||||
RemoveVectoredExceptionHandler(_handle);
|
||||
jmpbuf = _previous_ptr;
|
||||
}
|
||||
|
||||
} // detail namespace
|
||||
} // sig namespace
|
||||
|
||||
#else
|
||||
// windows
|
||||
|
||||
#include <winnt.h> // for EXCEPTION_*
|
||||
|
||||
namespace sig {
|
||||
namespace detail {
|
||||
|
||||
// these are the kinds of SEH exceptions we'll translate into C++ exceptions
|
||||
bool catch_error(int const code)
|
||||
{
|
||||
return code == EXCEPTION_IN_PAGE_ERROR
|
||||
|| code == EXCEPTION_ACCESS_VIOLATION
|
||||
|| code == EXCEPTION_ARRAY_BOUNDS_EXCEEDED;
|
||||
}
|
||||
} // detail namespace
|
||||
} // namespace sig
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
|
49
rblibtorrent/src/deps/try_signal/try_signal.hpp
Normal file
49
rblibtorrent/src/deps/try_signal/try_signal.hpp
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2017, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TRY_SIGNAL_HPP_INCLUDED
|
||||
#define TRY_SIGNAL_HPP_INCLUDED
|
||||
|
||||
#if !defined _WIN32
|
||||
// linux
|
||||
#include "try_signal_posix.hpp"
|
||||
#elif __GNUC__
|
||||
// mingw
|
||||
#include "try_signal_mingw.hpp"
|
||||
#else
|
||||
// windows
|
||||
#include "try_signal_msvc.hpp"
|
||||
#endif
|
||||
|
||||
|
||||
#endif // TRY_SIGNAL_HPP_INCLUDED
|
||||
|
78
rblibtorrent/src/deps/try_signal/try_signal_mingw.hpp
Normal file
78
rblibtorrent/src/deps/try_signal/try_signal_mingw.hpp
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2017, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TRY_SIGNAL_MINGW_HPP_INCLUDED
|
||||
#define TRY_SIGNAL_MINGW_HPP_INCLUDED
|
||||
|
||||
#include "signal_error_code.hpp"
|
||||
|
||||
#include <setjmp.h> // for jmp_buf
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
namespace sig {
|
||||
namespace detail {
|
||||
|
||||
struct scoped_handler
|
||||
{
|
||||
scoped_handler(jmp_buf* ptr);
|
||||
~scoped_handler();
|
||||
scoped_handler(scoped_handler const&) = delete;
|
||||
scoped_handler& operator=(scoped_handler const&) = delete;
|
||||
private:
|
||||
void* _handle;
|
||||
jmp_buf* _previous_ptr;
|
||||
};
|
||||
|
||||
} // detail namespace
|
||||
|
||||
template <typename Fun>
|
||||
void try_signal(Fun&& f)
|
||||
{
|
||||
jmp_buf buf;
|
||||
int const code = setjmp(buf);
|
||||
// set the thread local jmpbuf pointer, and make sure it's cleared when we
|
||||
// leave the scope
|
||||
sig::detail::scoped_handler scope(&buf);
|
||||
if (code != 0)
|
||||
throw std::system_error(std::error_code(code, seh_category()));
|
||||
|
||||
f();
|
||||
}
|
||||
|
||||
} // sig namespace
|
||||
|
||||
#endif
|
||||
|
61
rblibtorrent/src/deps/try_signal/try_signal_msvc.hpp
Normal file
61
rblibtorrent/src/deps/try_signal/try_signal_msvc.hpp
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2017, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TRY_SIGNAL_MSVC_HPP_INCLUDED
|
||||
#define TRY_SIGNAL_MSVC_HPP_INCLUDED
|
||||
|
||||
#include "signal_error_code.hpp"
|
||||
|
||||
namespace sig {
|
||||
namespace detail {
|
||||
|
||||
bool catch_error(int const code);
|
||||
|
||||
} // detail namespace
|
||||
|
||||
template <typename Fun>
|
||||
void try_signal(Fun&& f)
|
||||
{
|
||||
__try
|
||||
{
|
||||
f();
|
||||
}
|
||||
__except (detail::catch_error(GetExceptionCode()))
|
||||
{
|
||||
throw std::system_error(std::error_code(GetExceptionCode(), seh_category()));
|
||||
}
|
||||
}
|
||||
|
||||
} // sig namespace
|
||||
|
||||
#endif
|
||||
|
82
rblibtorrent/src/deps/try_signal/try_signal_posix.hpp
Normal file
82
rblibtorrent/src/deps/try_signal/try_signal_posix.hpp
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2017, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TRY_SIGNAL_POSIX_HPP_INCLUDED
|
||||
#define TRY_SIGNAL_POSIX_HPP_INCLUDED
|
||||
|
||||
#include "signal_error_code.hpp"
|
||||
#include <setjmp.h> // for sigjmp_buf
|
||||
#include <atomic>
|
||||
|
||||
namespace sig {
|
||||
|
||||
namespace detail {
|
||||
|
||||
extern std::atomic_flag once;
|
||||
|
||||
struct scoped_jmpbuf
|
||||
{
|
||||
explicit scoped_jmpbuf(sigjmp_buf* ptr);
|
||||
~scoped_jmpbuf();
|
||||
scoped_jmpbuf(scoped_jmpbuf const&) = delete;
|
||||
scoped_jmpbuf& operator=(scoped_jmpbuf const&) = delete;
|
||||
private:
|
||||
sigjmp_buf* _previous_ptr;
|
||||
};
|
||||
|
||||
void handler(int const signo, siginfo_t* si, void*);
|
||||
void setup_handler();
|
||||
|
||||
} // detail namespace
|
||||
|
||||
template <typename Fun>
|
||||
void try_signal(Fun&& f)
|
||||
{
|
||||
if (sig::detail::once.test_and_set() == false) {
|
||||
sig::detail::setup_handler();
|
||||
}
|
||||
|
||||
sigjmp_buf buf;
|
||||
int const sig = sigsetjmp(buf, 1);
|
||||
// set the thread local jmpbuf pointer, and make sure it's cleared when we
|
||||
// leave the scope
|
||||
sig::detail::scoped_jmpbuf scope(&buf);
|
||||
if (sig != 0)
|
||||
throw std::system_error(static_cast<sig::errors::error_code_enum>(sig));
|
||||
|
||||
f();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user