This commit is contained in:
Hennadii Stepanov 2024-05-16 03:17:38 +02:00 committed by GitHub
commit 45767ed000
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 62 additions and 32 deletions

View File

@ -41,6 +41,9 @@
/* Define this symbol to enable ZMQ functions */
#define ENABLE_ZMQ 1
/* Define if external signer support is enabled */
#define ENABLE_EXTERNAL_SIGNER 1
/* Define to 1 if you have the declaration of `fork', and to 0 if you don't.
*/
#define HAVE_DECL_FORK 0

View File

@ -84,7 +84,7 @@
<ReplaceInFile FilePath="$(ConfigIniOut)"
Replace="@ENABLE_ZMQ_TRUE@" By=""></ReplaceInFile>
<ReplaceInFile FilePath="$(ConfigIniOut)"
Replace="@ENABLE_EXTERNAL_SIGNER_TRUE@" By="#"></ReplaceInFile>
Replace="@ENABLE_EXTERNAL_SIGNER_TRUE@" By=""></ReplaceInFile>
<ReplaceInFile FilePath="$(ConfigIniOut)"
Replace="@ENABLE_USDT_TRACEPOINTS_TRUE@" By="#"></ReplaceInFile>
</Target>

View File

@ -90,7 +90,7 @@
<AdditionalOptions>/utf-8 /Zc:preprocessor /Zc:__cplusplus /std:c++20 %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>4018;4244;4267;4715;4805</DisableSpecificWarnings>
<TreatWarningAsError>true</TreatWarningAsError>
<PreprocessorDefinitions>_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;SECP256K1_STATIC;ZMQ_STATIC;NOMINMAX;WIN32;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_WIN32_WINNT=0x0601;_WIN32_IE=0x0501;WIN32_LEAN_AND_MEAN;PROVIDE_FUZZ_MAIN_FUNCTION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;SECP256K1_STATIC;ZMQ_STATIC;NOMINMAX;WIN32;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_WIN32_WINNT=0x0601;_WIN32_IE=0x0501;WIN32_LEAN_AND_MEAN;PROVIDE_FUZZ_MAIN_FUNCTION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\src;..\..\src\minisketch\include;..\..\src\univalue\include;..\..\src\secp256k1\include;..\..\src\leveldb\include;..\..\src\leveldb\helpers\memenv;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>

View File

@ -119,7 +119,7 @@ if [ -n "$ANDROID_TOOLS_URL" ]; then
exit 0
fi
BITCOIN_CONFIG_ALL="${BITCOIN_CONFIG_ALL} --enable-external-signer --prefix=$BASE_OUTDIR"
BITCOIN_CONFIG_ALL="${BITCOIN_CONFIG_ALL} --prefix=$BASE_OUTDIR"
if [ -n "$CONFIG_SHELL" ]; then
"$CONFIG_SHELL" -c "./autogen.sh"

View File

@ -1397,12 +1397,6 @@ if test "$use_boost" = "yes"; then
fi
fi
case $host in
dnl Re-enable it after enabling Windows support in cpp-subprocess.
*mingw*)
use_external_signer="no"
;;
esac
if test "$use_external_signer" = "yes"; then
AC_DEFINE([ENABLE_EXTERNAL_SIGNER], [1], [Define if external signer support is enabled])
fi

View File

@ -27,12 +27,23 @@ BOOST_AUTO_TEST_CASE(dummy)
BOOST_AUTO_TEST_CASE(run_command)
{
#ifdef WIN32
// https://www.winehq.org/pipermail/wine-devel/2008-September/069387.html
auto hntdll = GetModuleHandleA("ntdll.dll");
assert(hntdll);
const bool wine_runtime = GetProcAddress(hntdll, "wine_get_version");
#endif
{
const UniValue result = RunCommandParseJSON("");
BOOST_CHECK(result.isNull());
}
{
#ifdef WIN32
const UniValue result = RunCommandParseJSON("cmd.exe /c echo {\"success\": true}");
#else
const UniValue result = RunCommandParseJSON("echo {\"success\": true}");
#endif
BOOST_CHECK(result.isObject());
const UniValue& success = result.find_value("success");
BOOST_CHECK(!success.isNull());
@ -40,12 +51,20 @@ BOOST_AUTO_TEST_CASE(run_command)
}
{
// An invalid command is handled by cpp-subprocess
#ifdef WIN32
const std::string expected{"CreateProcess failed: "};
#else
const std::string expected{"execve failed: "};
#endif
BOOST_CHECK_EXCEPTION(RunCommandParseJSON("invalid_command"), subprocess::CalledProcessError, HasReason(expected));
}
{
// Return non-zero exit code, no output to stderr
#ifdef WIN32
const std::string command{"cmd.exe /c exit 1"};
#else
const std::string command{"false"};
#endif
BOOST_CHECK_EXCEPTION(RunCommandParseJSON(command), std::runtime_error, [&](const std::runtime_error& e) {
const std::string what{e.what()};
BOOST_CHECK(what.find(strprintf("RunCommandParseJSON error: process(%s) returned 1: \n", command)) != std::string::npos);
@ -54,8 +73,13 @@ BOOST_AUTO_TEST_CASE(run_command)
}
{
// Return non-zero exit code, with error message for stderr
#ifdef WIN32
const std::string command{"cmd.exe /c dir nosuchfile"};
const std::string expected{wine_runtime ? "File not found." : "File Not Found"};
#else
const std::string command{"ls nosuchfile"};
const std::string expected{"No such file or directory"};
#endif
BOOST_CHECK_EXCEPTION(RunCommandParseJSON(command), std::runtime_error, [&](const std::runtime_error& e) {
const std::string what(e.what());
BOOST_CHECK(what.find(strprintf("RunCommandParseJSON error: process(%s) returned", command)) != std::string::npos);
@ -65,17 +89,23 @@ BOOST_AUTO_TEST_CASE(run_command)
}
{
// Unable to parse JSON
#ifdef WIN32
const std::string command{"cmd.exe /c echo {"};
#else
const std::string command{"echo {"};
#endif
BOOST_CHECK_EXCEPTION(RunCommandParseJSON(command), std::runtime_error, HasReason("Unable to parse JSON: {"));
}
// Test std::in
#ifndef WIN32
{
// Test std::in
const UniValue result = RunCommandParseJSON("cat", "{\"success\": true}");
BOOST_CHECK(result.isObject());
const UniValue& success = result.find_value("success");
BOOST_CHECK(!success.isNull());
BOOST_CHECK_EQUAL(success.get_bool(), true);
}
#endif
}
#endif // ENABLE_EXTERNAL_SIGNER

View File

@ -55,17 +55,13 @@ Documentation for C++ subprocessing library.
#include <string>
#include <vector>
#if (defined _MSC_VER) || (defined __MINGW32__)
#define __USING_WINDOWS__
#endif
#ifdef __USING_WINDOWS__
#ifdef WIN32
#include <codecvt>
#endif
extern "C" {
#ifdef __USING_WINDOWS__
#include <Windows.h>
#ifdef WIN32
#include <windows.h>
#include <io.h>
#include <cwchar>
@ -169,7 +165,7 @@ namespace util
//
if (force == false && argument.empty() == false &&
argument.find_first_of(L" \t\n\v\"") == argument.npos) {
argument.find_first_of(L" \t\n\v") == argument.npos) {
command_line.append(argument);
}
else {
@ -219,7 +215,7 @@ namespace util
}
}
#ifdef __USING_WINDOWS__
#ifdef WIN32
inline std::string get_last_error(DWORD errorMessageID)
{
if (errorMessageID == 0)
@ -320,7 +316,7 @@ namespace util
}
#ifndef __USING_WINDOWS__
#ifndef WIN32
/*!
* Function: set_clo_on_exec
* Sets/Resets the FD_CLOEXEC flag on the provided file descriptor
@ -408,7 +404,7 @@ namespace util
static inline
int read_atmost_n(FILE* fp, char* buf, size_t read_upto)
{
#ifdef __USING_WINDOWS__
#ifdef WIN32
return (int)fread(buf, 1, read_upto, fp);
#else
int fd = fileno(fp);
@ -481,7 +477,7 @@ namespace util
return total_bytes_read;
}
#ifndef __USING_WINDOWS__
#ifndef WIN32
/*!
* Function: wait_for_child_exit
* Waits for the process with pid `pid` to exit
@ -582,7 +578,7 @@ struct input
}
explicit input(IOTYPE typ) {
assert (typ == PIPE && "STDOUT/STDERR not allowed");
#ifndef __USING_WINDOWS__
#ifndef WIN32
std::tie(rd_ch_, wr_ch_) = util::pipe_cloexec();
#endif
}
@ -615,7 +611,7 @@ struct output
}
explicit output(IOTYPE typ) {
assert (typ == PIPE && "STDOUT/STDERR not allowed");
#ifndef __USING_WINDOWS__
#ifndef WIN32
std::tie(rd_ch_, wr_ch_) = util::pipe_cloexec();
#endif
}
@ -647,7 +643,7 @@ struct error
explicit error(IOTYPE typ) {
assert ((typ == PIPE || typ == STDOUT) && "STDERR not allowed");
if (typ == PIPE) {
#ifndef __USING_WINDOWS__
#ifndef WIN32
std::tie(rd_ch_, wr_ch_) = util::pipe_cloexec();
#endif
} else {
@ -858,7 +854,7 @@ public:// Yes they are public
std::shared_ptr<FILE> output_ = nullptr;
std::shared_ptr<FILE> error_ = nullptr;
#ifdef __USING_WINDOWS__
#ifdef WIN32
HANDLE g_hChildStd_IN_Rd = nullptr;
HANDLE g_hChildStd_IN_Wr = nullptr;
HANDLE g_hChildStd_OUT_Rd = nullptr;
@ -999,7 +995,7 @@ private:
private:
detail::Streams stream_;
#ifdef __USING_WINDOWS__
#ifdef WIN32
HANDLE process_handle_;
std::future<void> cleanup_future_;
#endif
@ -1040,10 +1036,17 @@ inline void Popen::populate_c_argv()
inline int Popen::wait() noexcept(false)
{
#ifdef __USING_WINDOWS__
#ifdef WIN32
int ret = WaitForSingleObject(process_handle_, INFINITE);
if (ret != WAIT_OBJECT_0) return -1;
return 0;
DWORD dretcode_;
if (FALSE == GetExitCodeProcess(process_handle_, &dretcode_))
throw OSError("GetExitCodeProcess", 0);
CloseHandle(process_handle_);
return (int)dretcode_;
#else
int ret, status;
std::tie(ret, status) = util::wait_for_child_exit(child_pid_);
@ -1061,7 +1064,7 @@ inline int Popen::wait() noexcept(false)
inline void Popen::execute_process() noexcept(false)
{
#ifdef __USING_WINDOWS__
#ifdef WIN32
if (exe_name_.length()) {
this->vargs_.insert(this->vargs_.begin(), this->exe_name_);
this->populate_c_argv();
@ -1235,7 +1238,7 @@ namespace detail {
inline void Child::execute_child() {
#ifndef __USING_WINDOWS__
#ifndef WIN32
int sys_ret = -1;
auto& stream = parent_->stream_;
@ -1301,7 +1304,7 @@ namespace detail {
inline void Streams::setup_comm_channels()
{
#ifdef __USING_WINDOWS__
#ifdef WIN32
util::configure_pipe(&this->g_hChildStd_IN_Rd, &this->g_hChildStd_IN_Wr, &this->g_hChildStd_IN_Wr);
this->input(util::file_from_handle(this->g_hChildStd_IN_Wr, "w"));
this->write_to_child_ = _fileno(this->input());