diff --git a/build_msvc/bitcoin_config.h b/build_msvc/bitcoin_config.h index ab13f73539..66cc1208a1 100644 --- a/build_msvc/bitcoin_config.h +++ b/build_msvc/bitcoin_config.h @@ -421,4 +421,14 @@ /* Define for large files, on AIX-style hosts. */ /* #undef _LARGE_FILES */ +/* Windows Universal Platform constraints */ +#if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP) +/* Either a desktop application without API restrictions, or and older system + before these macros were defined. */ + +/* ::wsystem is available */ +#define HAVE_SYSTEM 1 + +#endif // !WINAPI_FAMILY || WINAPI_FAMILY_DESKTOP_APP + #endif //BITCOIN_BITCOIN_CONFIG_H diff --git a/configure.ac b/configure.ac index 5e1a5e14a1..1d5a41ab9a 100644 --- a/configure.ac +++ b/configure.ac @@ -925,6 +925,29 @@ if test x$use_reduce_exports = xyes; then [AC_MSG_ERROR([Cannot set default symbol visibility. Use --disable-reduce-exports.])]) fi +AC_MSG_CHECKING([for std::system]) +AC_LINK_IFELSE( + [ AC_LANG_PROGRAM( + [[ #include ]], + [[ int nErr = std::system(""); ]] + )], + [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_STD__SYSTEM, 1, Define to 1 if you have the `std::system' function.)], + [ AC_MSG_RESULT(no) ] +) + +AC_MSG_CHECKING([for ::_wsystem]) +AC_LINK_IFELSE( + [ AC_LANG_PROGRAM( + [[ ]], + [[ int nErr = ::_wsystem(""); ]] + )], + [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_WSYSTEM, 1, Define to 1 if you have the `::wsystem' function.)], + [ AC_MSG_RESULT(no) ] +) + +# Define to 1 if std::system or ::wsystem (Windows) is available +AC_DEFINE([HAVE_SYSTEM], [HAVE_STD__SYSTEM || HAVE_WSYSTEM], [std::system or ::wsystem]) + LEVELDB_CPPFLAGS= LIBLEVELDB= LIBMEMENV= diff --git a/src/init.cpp b/src/init.cpp index 6625080c6e..e2a1b99e37 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -376,10 +376,14 @@ void SetupServerArgs() "-allowselfsignedrootcertificates", "-choosedatadir", "-lang=", "-min", "-resetguisettings", "-rootcertificates=", "-splash", "-uiplatform"}; gArgs.AddArg("-version", "Print version and exit", false, OptionsCategory::OPTIONS); +#if defined(HAVE_SYSTEM) gArgs.AddArg("-alertnotify=", "Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)", false, OptionsCategory::OPTIONS); +#endif gArgs.AddArg("-assumevalid=", strprintf("If this block is in the chain assume that it and its ancestors are valid and potentially skip their script verification (0 to verify all, default: %s, testnet: %s)", defaultChainParams->GetConsensus().defaultAssumeValid.GetHex(), testnetChainParams->GetConsensus().defaultAssumeValid.GetHex()), false, OptionsCategory::OPTIONS); gArgs.AddArg("-blocksdir=", "Specify directory to hold blocks subdirectory for *.dat files (default: )", false, OptionsCategory::OPTIONS); +#if defined(HAVE_SYSTEM) gArgs.AddArg("-blocknotify=", "Execute command when the best block changes (%s in cmd is replaced by block hash)", false, OptionsCategory::OPTIONS); +#endif gArgs.AddArg("-blockreconstructionextratxn=", strprintf("Extra transactions to keep in memory for compact block reconstructions (default: %u)", DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN), false, OptionsCategory::OPTIONS); gArgs.AddArg("-blocksonly", strprintf("Whether to reject transactions from network peers. Transactions from the wallet or RPC are not affected. (default: %u)", DEFAULT_BLOCKSONLY), false, OptionsCategory::OPTIONS); gArgs.AddArg("-conf=", strprintf("Specify configuration file. Relative paths will be prefixed by datadir location. (default: %s)", BITCOIN_CONF_FILENAME), false, OptionsCategory::OPTIONS); @@ -579,6 +583,7 @@ std::string LicenseInfo() "\n"; } +#if defined(HAVE_SYSTEM) static void BlockNotifyCallback(bool initialSync, const CBlockIndex *pBlockIndex) { if (initialSync || !pBlockIndex) @@ -591,6 +596,7 @@ static void BlockNotifyCallback(bool initialSync, const CBlockIndex *pBlockIndex t.detach(); // thread runs free } } +#endif static bool fHaveGenesis = false; static Mutex g_genesis_wait_mutex; @@ -1708,8 +1714,10 @@ bool AppInitMain(InitInterfaces& interfaces) fHaveGenesis = true; } +#if defined(HAVE_SYSTEM) if (gArgs.IsArgSet("-blocknotify")) uiInterface.NotifyBlockTip_connect(BlockNotifyCallback); +#endif std::vector vImportFiles; for (const std::string& strFile : gArgs.GetArgs("-loadblock")) { diff --git a/src/util/system.cpp b/src/util/system.cpp index 87ff6e62ba..0f599b85f1 100644 --- a/src/util/system.cpp +++ b/src/util/system.cpp @@ -1114,6 +1114,7 @@ fs::path GetSpecialFolderPath(int nFolder, bool fCreate) } #endif +#if defined(HAVE_SYSTEM) void runCommand(const std::string& strCommand) { if (strCommand.empty()) return; @@ -1125,6 +1126,7 @@ void runCommand(const std::string& strCommand) if (nErr) LogPrintf("runCommand error: system(%s) returned %d\n", strCommand, nErr); } +#endif void SetupEnvironment() { diff --git a/src/util/system.h b/src/util/system.h index 15d7b1b402..fd0583658b 100644 --- a/src/util/system.h +++ b/src/util/system.h @@ -89,7 +89,9 @@ fs::path GetConfigFile(const std::string& confPath); #ifdef WIN32 fs::path GetSpecialFolderPath(int nFolder, bool fCreate = true); #endif +#if defined(HAVE_SYSTEM) void runCommand(const std::string& strCommand); +#endif /** * Most paths passed as configuration arguments are treated as relative to diff --git a/src/validation.cpp b/src/validation.cpp index c6995ed24b..76bbb7920b 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1050,6 +1050,7 @@ static CBlockIndex *pindexBestForkTip = nullptr, *pindexBestForkBase = nullptr; static void AlertNotify(const std::string& strMessage) { uiInterface.NotifyAlertChanged(); +#if defined(HAVE_SYSTEM) std::string strCmd = gArgs.GetArg("-alertnotify", ""); if (strCmd.empty()) return; @@ -1063,6 +1064,7 @@ static void AlertNotify(const std::string& strMessage) std::thread t(runCommand, strCmd); t.detach(); // thread runs free +#endif } static void CheckForkWarningConditions() EXCLUSIVE_LOCKS_REQUIRED(cs_main) diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp index 0265433863..0085c3bac9 100644 --- a/src/wallet/init.cpp +++ b/src/wallet/init.cpp @@ -57,7 +57,9 @@ void WalletInit::AddWalletOptions() const gArgs.AddArg("-wallet=", "Specify wallet database path. Can be specified multiple times to load multiple wallets. Path is interpreted relative to if it is not absolute, and will be created if it does not exist (as a directory containing a wallet.dat file and log files). For backwards compatibility this will also accept names of existing data files in .)", false, OptionsCategory::WALLET); gArgs.AddArg("-walletbroadcast", strprintf("Make the wallet broadcast transactions (default: %u)", DEFAULT_WALLETBROADCAST), false, OptionsCategory::WALLET); gArgs.AddArg("-walletdir=", "Specify directory to hold wallets (default: /wallets if it exists, otherwise )", false, OptionsCategory::WALLET); +#if defined(HAVE_SYSTEM) gArgs.AddArg("-walletnotify=", "Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)", false, OptionsCategory::WALLET); +#endif gArgs.AddArg("-walletrbf", strprintf("Send transactions with full-RBF opt-in enabled (RPC only, default: %u)", DEFAULT_WALLET_RBF), false, OptionsCategory::WALLET); gArgs.AddArg("-zapwallettxes=", "Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup" " (1 = keep tx meta data e.g. payment request information, 2 = drop tx meta data)", false, OptionsCategory::WALLET); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 8807acb6b7..70fc06a7e7 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1050,6 +1050,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose) // Notify UI of new or updated transaction NotifyTransactionChanged(this, hash, fInsertedNew ? CT_NEW : CT_UPDATED); +#if defined(HAVE_SYSTEM) // notify an external script when a wallet transaction comes in or is updated std::string strCmd = gArgs.GetArg("-walletnotify", ""); @@ -1059,6 +1060,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose) std::thread t(runCommand, strCmd); t.detach(); // thread runs free } +#endif return true; }