mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-08-10 11:08:08 +02:00
windows: remove deprecated codecvt via UTF-8 narrow APIs
Drop wstring_convert/codecvt and the related wide process calls (_wsystem, _wexecvp, CreateProcessW) in favor of ::system, _execvp, and CreateProcess.
This commit is contained in:
@@ -471,7 +471,6 @@ if(MSVC)
|
||||
try_append_cxx_flags("/wd4805" TARGET warn_interface SKIP_LINK)
|
||||
target_compile_definitions(warn_interface INTERFACE
|
||||
_CRT_SECURE_NO_WARNINGS
|
||||
_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING
|
||||
)
|
||||
else()
|
||||
try_append_cxx_flags("-Wall" TARGET warn_interface SKIP_LINK)
|
||||
|
||||
@@ -24,8 +24,7 @@ endif()
|
||||
# Even though ::system is part of the standard library, we still check
|
||||
# for it, to support building targets that don't have it, such as iOS.
|
||||
check_cxx_symbol_exists(std::system "cstdlib" HAVE_STD_SYSTEM)
|
||||
check_cxx_symbol_exists(::_wsystem "stdlib.h" HAVE__WSYSTEM)
|
||||
if(HAVE_STD_SYSTEM OR HAVE__WSYSTEM)
|
||||
if(HAVE_STD_SYSTEM)
|
||||
set(HAVE_SYSTEM 1)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#ifdef WIN32
|
||||
#include <compat/compat.h>
|
||||
#include <util/check.h>
|
||||
#include <codecvt>
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/stat.h>
|
||||
@@ -49,11 +48,7 @@ std::string ShellEscape(const std::string& arg)
|
||||
void runCommand(const std::string& strCommand)
|
||||
{
|
||||
if (strCommand.empty()) return;
|
||||
#ifndef WIN32
|
||||
int nErr = ::system(strCommand.c_str());
|
||||
#else
|
||||
int nErr = ::_wsystem(std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>,wchar_t>().from_bytes(strCommand).c_str());
|
||||
#endif
|
||||
if (nErr) {
|
||||
LogWarning("runCommand error: system(%s) returned %d", strCommand, nErr);
|
||||
}
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
#include <system_error>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <codecvt>
|
||||
#include <locale>
|
||||
#include <process.h>
|
||||
#include <windows.h>
|
||||
#else
|
||||
@@ -28,17 +26,16 @@ int ExecVp(const char* file, char* const argv[])
|
||||
#ifndef WIN32
|
||||
return execvp(file, argv);
|
||||
#else
|
||||
std::vector<std::wstring> escaped_args;
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
||||
std::vector<std::string> escaped_args;
|
||||
for (char* const* arg_ptr{argv}; *arg_ptr; ++arg_ptr) {
|
||||
subprocess::util::quote_argument(converter.from_bytes(*arg_ptr), escaped_args.emplace_back(), false);
|
||||
subprocess::util::quote_argument(std::string{*arg_ptr}, escaped_args.emplace_back(), /*force=*/false);
|
||||
}
|
||||
|
||||
std::vector<const wchar_t*> new_argv;
|
||||
std::vector<const char*> new_argv;
|
||||
new_argv.reserve(escaped_args.size() + 1);
|
||||
for (const auto& s : escaped_args) new_argv.push_back(s.c_str());
|
||||
new_argv.push_back(nullptr);
|
||||
return _wexecvp(converter.from_bytes(file).c_str(), new_argv.data());
|
||||
return _execvp(file, new_argv.data());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -48,22 +48,16 @@ Documentation for C++ subprocessing library.
|
||||
#include <future>
|
||||
#include <initializer_list>
|
||||
#include <iostream>
|
||||
#include <locale>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <codecvt>
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#include <io.h>
|
||||
#include <cwchar>
|
||||
#else
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
@@ -168,9 +162,12 @@ public:
|
||||
namespace util
|
||||
{
|
||||
#ifdef WIN32
|
||||
inline void quote_argument(const std::wstring &argument, std::wstring &command_line,
|
||||
inline void quote_argument(const std::string &argument, std::string &command_line,
|
||||
bool force)
|
||||
{
|
||||
constexpr char quote = '"';
|
||||
constexpr char backslash = '\\';
|
||||
|
||||
//
|
||||
// Unless we're told otherwise, don't quote unless we actually
|
||||
// need to do so --- hopefully avoid problems if programs won't
|
||||
@@ -178,16 +175,16 @@ namespace util
|
||||
//
|
||||
|
||||
if (force == false && argument.empty() == false &&
|
||||
argument.find_first_of(L" \t\n\v") == argument.npos) {
|
||||
argument.find_first_of(" \t\n\v") == argument.npos) {
|
||||
command_line.append(argument);
|
||||
}
|
||||
else {
|
||||
command_line.push_back(L'"');
|
||||
command_line.push_back(quote);
|
||||
|
||||
for (auto it = argument.begin();; ++it) {
|
||||
unsigned number_backslashes = 0;
|
||||
|
||||
while (it != argument.end() && *it == L'\\') {
|
||||
while (it != argument.end() && *it == backslash) {
|
||||
++it;
|
||||
++number_backslashes;
|
||||
}
|
||||
@@ -200,17 +197,17 @@ namespace util
|
||||
// as a metacharacter.
|
||||
//
|
||||
|
||||
command_line.append(number_backslashes * 2, L'\\');
|
||||
command_line.append(number_backslashes * 2, backslash);
|
||||
break;
|
||||
}
|
||||
else if (*it == L'"') {
|
||||
else if (*it == quote) {
|
||||
|
||||
//
|
||||
// Escape all backslashes and the following
|
||||
// double quotation mark.
|
||||
//
|
||||
|
||||
command_line.append(number_backslashes * 2 + 1, L'\\');
|
||||
command_line.append(number_backslashes * 2 + 1, backslash);
|
||||
command_line.push_back(*it);
|
||||
}
|
||||
else {
|
||||
@@ -219,12 +216,12 @@ namespace util
|
||||
// Backslashes aren't special here.
|
||||
//
|
||||
|
||||
command_line.append(number_backslashes, L'\\');
|
||||
command_line.append(number_backslashes, backslash);
|
||||
command_line.push_back(*it);
|
||||
}
|
||||
}
|
||||
|
||||
command_line.push_back(L'"');
|
||||
command_line.push_back(quote);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1085,37 +1082,36 @@ inline void Popen::execute_process() noexcept(false)
|
||||
}
|
||||
this->exe_name_ = vargs_[0];
|
||||
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
||||
std::wstring argument;
|
||||
std::wstring command_line;
|
||||
std::string argument;
|
||||
std::string command_line;
|
||||
bool first_arg = true;
|
||||
|
||||
for (auto arg : this->vargs_) {
|
||||
if (!first_arg) {
|
||||
command_line += L" ";
|
||||
command_line += " ";
|
||||
} else {
|
||||
first_arg = false;
|
||||
}
|
||||
argument = converter.from_bytes(arg);
|
||||
util::quote_argument(argument, command_line, false);
|
||||
argument = arg;
|
||||
util::quote_argument(argument, command_line, /*force=*/false);
|
||||
}
|
||||
|
||||
// CreateProcessW can modify szCmdLine so we allocate needed memory
|
||||
wchar_t *szCmdline = new wchar_t[command_line.size() + 1];
|
||||
wcscpy_s(szCmdline, command_line.size() + 1, command_line.c_str());
|
||||
// CreateProcessA can modify szCmdLine so we allocate needed memory
|
||||
char *szCmdline = new char[command_line.size() + 1];
|
||||
strcpy_s(szCmdline, command_line.size() + 1, command_line.c_str());
|
||||
PROCESS_INFORMATION piProcInfo;
|
||||
STARTUPINFOW siStartInfo;
|
||||
STARTUPINFOA siStartInfo;
|
||||
BOOL bSuccess = FALSE;
|
||||
DWORD creation_flags = CREATE_UNICODE_ENVIRONMENT | CREATE_NO_WINDOW;
|
||||
DWORD creation_flags = CREATE_NO_WINDOW;
|
||||
|
||||
// Set up members of the PROCESS_INFORMATION structure.
|
||||
ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));
|
||||
|
||||
// Set up members of the STARTUPINFOW structure.
|
||||
// Set up members of the STARTUPINFOA structure.
|
||||
// This structure specifies the STDIN and STDOUT handles for redirection.
|
||||
|
||||
ZeroMemory(&siStartInfo, sizeof(STARTUPINFOW));
|
||||
siStartInfo.cb = sizeof(STARTUPINFOW);
|
||||
ZeroMemory(&siStartInfo, sizeof(STARTUPINFOA));
|
||||
siStartInfo.cb = sizeof(STARTUPINFOA);
|
||||
|
||||
siStartInfo.hStdError = this->stream_.g_hChildStd_ERR_Wr;
|
||||
siStartInfo.hStdOutput = this->stream_.g_hChildStd_OUT_Wr;
|
||||
@@ -1124,7 +1120,7 @@ inline void Popen::execute_process() noexcept(false)
|
||||
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
|
||||
|
||||
// Create the child process.
|
||||
bSuccess = CreateProcessW(NULL,
|
||||
bSuccess = CreateProcessA(NULL,
|
||||
szCmdline, // command line
|
||||
NULL, // process security attributes
|
||||
NULL, // primary thread security attributes
|
||||
@@ -1132,7 +1128,7 @@ inline void Popen::execute_process() noexcept(false)
|
||||
creation_flags, // creation flags
|
||||
NULL, // use parent's environment
|
||||
NULL, // use parent's current directory
|
||||
&siStartInfo, // STARTUPINFOW pointer
|
||||
&siStartInfo, // STARTUPINFOA pointer
|
||||
&piProcInfo); // receives PROCESS_INFORMATION
|
||||
|
||||
// If an error occurs, exit the application.
|
||||
|
||||
Reference in New Issue
Block a user