Browse Source

Merge remote-tracking branch 'upstream/develop' into newTests

cl-refactor
CJentzsch 10 years ago
parent
commit
bc55a9b7f4
  1. 9
      .gitignore
  2. 4
      .gitmodules
  3. 162
      CMakeLists.txt
  4. 0
      EthereumMacOSXBundleInfo.plist.in
  5. 6
      README.md
  6. 130
      alethzero/CMakeLists.txt
  7. 108
      alethzero/MainWin.cpp
  8. 10
      alethzero/MainWin.h
  9. 4
      alethzero/OurWebThreeStubServer.cpp
  10. 4
      alethzero/OurWebThreeStubServer.h
  11. BIN
      alethzero/alethzero.ico
  12. 1
      alethzero/alethzero.rc
  13. 50
      boost/process.hpp
  14. 200
      boost/process/child.hpp
  15. 41
      boost/process/config.hpp
  16. 209
      boost/process/context.hpp
  17. 406
      boost/process/detail/file_handle.hpp
  18. 187
      boost/process/detail/pipe.hpp
  19. 495
      boost/process/detail/posix_ops.hpp
  20. 176
      boost/process/detail/stream_info.hpp
  21. 231
      boost/process/detail/systembuf.hpp
  22. 355
      boost/process/detail/win32_ops.hpp
  23. 50
      boost/process/environment.hpp
  24. 583
      boost/process/operations.hpp
  25. 116
      boost/process/pistream.hpp
  26. 178
      boost/process/posix_child.hpp
  27. 118
      boost/process/posix_context.hpp
  28. 81
      boost/process/posix_operations.hpp
  29. 128
      boost/process/posix_status.hpp
  30. 117
      boost/process/postream.hpp
  31. 130
      boost/process/process.hpp
  32. 134
      boost/process/self.hpp
  33. 105
      boost/process/status.hpp
  34. 234
      boost/process/stream_behavior.hpp
  35. 128
      boost/process/win32_child.hpp
  36. 61
      boost/process/win32_context.hpp
  37. 77
      boost/process/win32_operations.hpp
  38. 27
      build.py
  39. 66
      cmake/EthCompilerSettings.cmake
  40. 148
      cmake/EthDependencies.cmake
  41. 210
      cmake/EthDependenciesDeprecated.cmake
  42. 152
      cmake/EthExecutableHelper.cmake
  43. 49
      cmake/FindCURL.cmake
  44. 108
      cmake/FindCryptoPP.cmake
  45. 34
      cmake/FindGmp.cmake
  46. 99
      cmake/FindJsonRpcCpp.cmake
  47. 48
      cmake/FindJsoncpp.cmake
  48. 48
      cmake/FindLevelDB.cmake
  49. 34
      cmake/FindMiniupnpc.cmake
  50. 34
      cmake/FindReadline.cmake
  51. 2364
      doc/Doxyfile
  52. 15
      docker/Dockerfile
  53. 47
      eth/CMakeLists.txt
  54. 31
      eth/main.cpp
  55. 1
      evmjit
  56. 30
      exp/CMakeLists.txt
  57. 92
      exp/main.cpp
  58. 55
      extdep/CMakeLists.txt
  59. 16
      extdep/Readme.md
  60. 9
      extdep/cmake/FindCURL.cmake
  61. 13
      extdep/compile/argtable2.cmake
  62. 19
      extdep/compile/boost.cmake
  63. 33
      extdep/compile/cryptopp.cmake
  64. 29
      extdep/compile/curl.cmake
  65. 17
      extdep/compile/icu.cmake
  66. 16
      extdep/compile/jom.cmake
  67. 40
      extdep/compile/json-rpc-cpp.cmake
  68. 16
      extdep/compile/jsoncpp.cmake
  69. 23
      extdep/compile/leveldb.cmake
  70. 18
      extdep/compile/leveldb_osx.patch
  71. 32
      extdep/compile/qt.cmake
  72. 111
      extdep/compile/qt_configure.bat
  73. 11
      extdep/compile/qt_osx.patch
  74. 2
      extdep/compile/qt_tools.bat
  75. 14
      extdep/compile/snappy.cmake
  76. 74
      extdep/eth_download.cmake
  77. 11
      extdep/miniupnpc.cmake
  78. 29
      extdep/scripts/json-rpc-cpp_osx.sh
  79. 12
      extdep/scripts/leveldb_osx.sh
  80. 8
      extdep/scripts/snappy_osx.sh
  81. 117
      iethxi/CMakeLists.txt
  82. 38
      iethxi/EthereumMacOSXBundleInfo.plist.in
  83. 168
      iethxi/Main.ui
  84. 59
      iethxi/MainWin.cpp
  85. 18
      iethxi/MainWin.h
  86. 5
      iethxi/Resources.qrc
  87. 9
      iethxi/Simple.qml
  88. 9
      iethxi/main.cpp
  89. 8
      libdevcore/All.h
  90. 41
      libdevcore/CMakeLists.txt
  91. 2
      libdevcore/Common.cpp
  92. 3
      libdevcore/Common.h
  93. 201
      libdevcore/CommonData.cpp
  94. 5
      libdevcore/CommonData.h
  95. 2
      libdevcore/CommonIO.cpp
  96. 60
      libdevcore/CommonJS.cpp
  97. 7
      libdevcore/CommonJS.h
  98. 35
      libdevcore/Diff.h
  99. 8
      libdevcore/RLP.h
  100. 2
      libdevcore/RangeMask.h

9
.gitignore

@ -18,18 +18,23 @@ ipch
*.sdf
*.opensdf
*.suo
*.vcxproj
*.vcxproj.filters
*.sln
# VIM stuff
*.swp
#Xcode stuff
# Xcode stuff
build_xc
*.user
*.user.*
*~
# build system
build.*/
extdep/install
*.pyc
@ -59,3 +64,5 @@ profile
DerivedData
project.pbxproj
evmjit

4
.gitmodules

@ -0,0 +1,4 @@
[submodule "evmjit"]
path = evmjit
url = https://github.com/ethereum/evmjit
branch = develop

162
CMakeLists.txt

@ -1,5 +1,8 @@
# cmake global
cmake_minimum_required(VERSION 2.8.9)
cmake_minimum_required(VERSION 2.8.12)
# let cmake autolink dependencies on windows
# it's specified globally, cause qt libraries requires that on windows and they are also found globally
cmake_policy(SET CMP0020 NEW)
project(ethereum)
@ -12,18 +15,15 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
# Normally, set(...CACHE...) creates cache variables, but does not modify them.
function(createDefaultCacheConfig)
set(HEADLESS OFF CACHE BOOL "Do not compile GUI (AlethZero)")
set(LANGUAGES OFF CACHE BOOL "Limit build to Serpent/LLL tools")
set(VMTRACE OFF CACHE BOOL "VM tracing and run-time checks (useful for cross-implementation VM debugging)")
set(PARANOIA OFF CACHE BOOL "Additional run-time checks")
set(JSONRPC ON CACHE BOOL "Build with jsonprc. default on")
set(EVMJIT OFF CACHE BOOL "Build a just-in-time compiler for EVM code (requires LLVM)")
endfunction()
# propagates CMake configuration options to the compiler
function(configureProject)
if (LANGUAGES)
add_definitions(-DETH_LANGUAGES)
endif ()
if (PARANOIA)
if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
add_definitions(-DETH_PARANOIA)
@ -39,9 +39,14 @@ function(configureProject)
message(FATAL_ERROR "VM tracing requires debug.")
endif ()
endif ()
if (EVMJIT)
add_definitions(-DETH_EVMJIT)
endif()
endfunction()
function(createBuildInfo)
# Set build platform; to be written to BuildInfo.h
if (CMAKE_COMPILER_IS_MINGW)
@ -50,7 +55,7 @@ function(createBuildInfo)
set(ETH_BUILD_PLATFORM "${ETH_BUILD_PLATFORM}/msys")
elseif (CMAKE_COMPILER_IS_GNUCXX)
set(ETH_BUILD_PLATFORM "${ETH_BUILD_PLATFORM}/g++")
elseif (CMAKE_COMPILER_IS_MSVC)
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
set(ETH_BUILD_PLATFORM "${ETH_BUILD_PLATFORM}/msvc")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set(ETH_BUILD_PLATFORM "${ETH_BUILD_PLATFORM}/clang")
@ -58,14 +63,23 @@ function(createBuildInfo)
set(ETH_BUILD_PLATFORM "${ETH_BUILD_PLATFORM}/unknown")
endif ()
#cmake build type may be not specified when using msvc
if (${CMAKE_BUILD_TYPE})
set(_cmake_build_type ${CMAKE_BUILD_TYPE})
else()
set(_cmake_build_type "undefined")
endif()
# Generate header file containing useful build information
add_custom_target(BuildInfo.h ALL COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/BuildInfo.sh ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_BUILD_TYPE} ${ETH_BUILD_PLATFORM})
add_custom_target(BuildInfo.h ALL COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/BuildInfo.sh ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${_cmake_build_type} ${ETH_BUILD_PLATFORM})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SRC_LIST BuildInfo.h)
endfunction()
######################################################################################################
@ -75,7 +89,7 @@ cmake_policy(SET CMP0015 NEW)
createDefaultCacheConfig()
configureProject()
message("-- LANGUAGES: ${LANGUAGES}; VMTRACE: ${VMTRACE}; PARANOIA: ${PARANOIA}; HEADLESS: ${HEADLESS}")
message("-- VMTRACE: ${VMTRACE}; PARANOIA: ${PARANOIA}; HEADLESS: ${HEADLESS}; JSONRPC: ${JSONRPC}; EVMJIT: ${EVMJIT}")
# Default TARGET_PLATFORM to "linux".
@ -88,88 +102,98 @@ if ("${TARGET_PLATFORM}" STREQUAL "linux")
set(CMAKE_THREAD_LIBS_INIT pthread)
endif ()
# Set default build type to Release w/debug info
# if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
# set(CMAKE_BUILD_TYPE RelWithDebInfo)
# endif()
include(EthCompilerSettings)
message("-- CXXFLAGS: ${CMAKE_CXX_FLAGS}")
#add_definitions("-DETH_BUILD_TYPE=${ETH_BUILD_TYPE}")
#add_definitions("-DETH_BUILD_PLATFORM=${ETH_BUILD_PLATFORM}")
include(EthDependenciesDeprecated)
# this must be an include, as a function it would messs up with variable scope!
include(EthDependencies)
include(EthExecutableHelper)
createBuildInfo()
if (EVMJIT)
# Workaround for Ubuntu broken LLVM package
link_directories(/usr/lib/llvm-3.5/lib)
add_subdirectory(evmjit)
endif()
add_subdirectory(libdevcore)
add_subdirectory(libevmcore)
add_subdirectory(liblll)
add_subdirectory(libserpent)
add_subdirectory(libsolidity)
if(NOT APPLE)
if(PYTHON_LS)
add_subdirectory(libpyserpent)
endif()
endif()
add_subdirectory(lllc)
add_subdirectory(solc)
add_subdirectory(sc)
if (JSONRPC_LS)
if (JSONRPC)
add_subdirectory(libweb3jsonrpc)
endif()
if (NOT LANGUAGES)
add_subdirectory(secp256k1)
add_subdirectory(libp2p)
add_subdirectory(libdevcrypto)
add_subdirectory(libwhisper)
add_subdirectory(libethcore)
add_subdirectory(libevm)
add_subdirectory(libethereum)
# add_subdirectory(libethereumx) # TODO remove
add_subdirectory(libwebthree)
add_subdirectory(test)
add_subdirectory(eth)
if("x${CMAKE_BUILD_TYPE}" STREQUAL "xDebug")
add_subdirectory(exp)
endif ()
if(NOT ("${TARGET_PLATFORM}" STREQUAL "w64"))
add_subdirectory(neth)
endif ()
if(QTQML)
add_definitions(-DETH_QTQML)
endif()
if(NOT HEADLESS)
if ("${TARGET_PLATFORM}" STREQUAL "w64")
cmake_policy(SET CMP0020 NEW)
endif ()
if (NOT JSONRPC_LS)
message(FATAL_ERROR "Alethzero requires jsonrpc.")
endif()
add_subdirectory(libjsqrc)
add_subdirectory(libqethereum)
add_subdirectory(alethzero)
add_subdirectory(third)
add_subdirectory(mix)
if(QTQML)
#add_subdirectory(iethxi)
#add_subdirectory(walleth) // resurect once we want to submit ourselves to QML.
endif()
endif()
endif()
add_subdirectory(secp256k1)
add_subdirectory(libp2p)
add_subdirectory(libdevcrypto)
add_subdirectory(libwhisper)
add_subdirectory(libethcore)
add_subdirectory(libevm)
add_subdirectory(libethereum)
add_subdirectory(libwebthree)
add_subdirectory(test)
add_subdirectory(eth)
if("x${CMAKE_BUILD_TYPE}" STREQUAL "xDebug")
add_subdirectory(exp)
endif ()
# TODO check msvc
if(NOT ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC"))
add_subdirectory(neth)
endif ()
if (NOT HEADLESS)
add_subdirectory(libjsqrc)
add_subdirectory(libqethereum)
add_subdirectory(alethzero)
add_subdirectory(third)
add_subdirectory(mix)
endif()
enable_testing()
add_test(NAME alltests WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/test COMMAND testeth)
#unset(TARGET_PLATFORM CACHE)
if (WIN32)
# packaging stuff
include(InstallRequiredSystemLibraries)
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "ethereum")
set(CPACK_PACKAGE_VENDOR "ethereum.org")
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
set(CPACK_PACKAGE_VERSION "0.7")
set(CPACK_GENERATOR "NSIS")
# seems to be not working
# set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/alethzero/alethzero.bmp")
# our stuff
set(CPACK_COMPONENT_ALETHZERO_GROUP "Applications")
set(CPACK_COMPONENT_THIRD_GROUP "Applications")
set(CPACK_COMPONENT_MIX_GROUP "Applications")
set(CPACK_COMPONENTS_ALL alethzero third mix)
# nsis specific stuff
set(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} ethereum")
set(CPACK_NSIS_HELP_LINK "https://github.com/ethereum/cpp-ethereum")
set(CPACK_NSIS_URL_INFO_ABOUT "https://github.com/ethereum/cpp-ethereum")
set(CPACK_NSIS_CONTACT "ethereum.org")
set(CPACK_NSIS_MODIFY_PATH ON)
set(CPACK_NSIS_MUI_ICON "${CMAKE_CURRENT_SOURCE_DIR}/alethzero/alethzero.ico")
set(CPACK_NSIS_MUI_UNIICON "${CMAKE_CURRENT_SOURCE_DIR}/alethzero/alethzero.ico")
include(CPack)
endif (WIN32)

0
alethzero/EthereumMacOSXBundleInfo.plist.in → EthereumMacOSXBundleInfo.plist.in

6
README.md

@ -1,5 +1,9 @@
## Ethereum C++ Client.
[![Build
Status](http://build.ethdev.com/buildstatusimage?builder=Linux%20C%2B%2B%20master%20branch)](http://build.ethdev.com/builders/Linux%20C%2B%2B%20master%20branch/builds/-1) master [![Build
Status](http://build.ethdev.com/buildstatusimage?builder=Linux%20C%2B%2B%20develop%20branch)](http://build.ethdev.com/builders/Linux%20C%2B%2B%20develop%20branch/builds/-1) develop
By Gav Wood, 2014.
[![Build
@ -36,5 +40,5 @@ Please read [CodingStandards.txt](CodingStandards.txt) thoroughly before making
libweb3jsonrpc/abstractwebthreestubserver.h is autogenerated from the jsonrpcstub executable that comes with the libjsonrpc library (json-rpc-cpp project). It shouldn't be maually altered.
```bash
jsonrpcstub -s -c spec.json WebThreeStub
jsonrpcstub spec.json --cpp-server=AbstractWebThreeStubServer
```

130
alethzero/CMakeLists.txt

@ -1,101 +1,53 @@
cmake_policy(SET CMP0015 NEW)
# let cmake autolink dependencies on windows
cmake_policy(SET CMP0020 NEW)
# this policy was introduced in cmake 3.0
# remove if, once 3.0 will be used on unix
if (${CMAKE_MAJOR_VERSION} GREATER 2)
cmake_policy(SET CMP0043 OLD)
endif()
set(CMAKE_INCLUDE_CURRENT_DIR ON)
aux_source_directory(. SRC_LIST)
include_directories(..)
if (APPLE)
# Add homebrew path for qt5
set(CMAKE_PREFIX_PATH /usr/local/opt/qt5)
include_directories(/usr/local/opt/qt5/include /usr/local/include)
elseif ("${TARGET_PLATFORM}" STREQUAL "w64")
set(SRC_LIST ${SRC_LIST} ../windows/qt_plugin_import.cpp)
include_directories(/usr/x86_64-w64-mingw32/include /usr/x86_64-w64-mingw32/include/QtCore /usr/x86_64-w64-mingw32/include/QtGui /usr/x86_64-w64-mingw32/include/QtQuick /usr/x86_64-w64-mingw32/include/QtQml /usr/x86_64-w64-mingw32/include/QtNetwork /usr/x86_64-w64-mingw32/include/QtWidgets /usr/x86_64-w64-mingw32/include/QtWebKit /usr/x86_64-w64-mingw32/include/QtWebKitWidgets)
elseif (UNIX)
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ";$ENV{QTDIR}/lib/cmake")
endif ()
find_package(Qt5Core REQUIRED)
find_package(Qt5Gui REQUIRED)
find_package(Qt5Quick REQUIRED)
find_package(Qt5Qml REQUIRED)
find_package(Qt5Network REQUIRED)
find_package(Qt5Widgets REQUIRED)
find_package(Qt5WebKit REQUIRED)
find_package(Qt5WebKitWidgets REQUIRED)
include_directories(${JSON_RPC_CPP_INCLUDE_DIRS})
include_directories(..)
qt5_wrap_ui(ui_Main.h Main.ui)
# Set name of binary and add_executable()
file(GLOB HEADERS "*.h")
if (APPLE)
set(EXECUTEABLE AlethZero)
set(BIN_INSTALL_DIR ".")
set(DOC_INSTALL_DIR ".")
set(PROJECT_VERSION "${ETH_VERSION}")
set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME} ${PROJECT_VERSION}")
set(MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_NAME} ${PROJECT_VERSION}")
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME} ${PROJECT_VERSION}")
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}")
set(MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT_YEAR} ${PROJECT_VENDOR}")
set(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_DOMAIN_SECOND}.${PROJECT_DOMAIN_FIRST}")
set(MACOSX_BUNDLE_BUNDLE_NAME ${EXECUTEABLE})
set(MACOSX_BUNDLE_ICON_FILE alethzero)
include(BundleUtilities)
add_executable(${EXECUTEABLE} MACOSX_BUNDLE alethzero.icns Main.ui ${SRC_LIST} ${HEADERS})
set_target_properties(${EXECUTEABLE} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/EthereumMacOSXBundleInfo.plist.in")
SET_SOURCE_FILES_PROPERTIES(${EXECUTEABLE} PROPERTIES MACOSX_PACKAGE_LOCATION MacOS)
SET_SOURCE_FILES_PROPERTIES(${MACOSX_BUNDLE_ICON_FILE}.icns PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
else ()
set(EXECUTEABLE alethzero)
add_executable(${EXECUTEABLE} Main.ui ${SRC_LIST} ${HEADERS})
endif ()
qt5_use_modules(${EXECUTEABLE} Core)# Gui Widgets Network WebKit WebKitWidgets)
target_link_libraries(${EXECUTEABLE} webthree qethereum ethereum evm ethcore devcrypto secp256k1 gmp ${CRYPTOPP_LS} serpent lll solidity evmcore devcore web3jsonrpc jsqrc)
if (APPLE)
# First have qt5 install plugins and frameworks
add_custom_command(TARGET ${EXECUTEABLE} POST_BUILD
COMMAND /usr/local/opt/qt5/bin/macdeployqt ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTEABLE}.app
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
# This tool and next will inspect linked libraries in order to determine which dependencies are required
if (${CMAKE_CFG_INTDIR} STREQUAL ".")
set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${EXECUTEABLE}.app")
else ()
set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/\$ENV{CONFIGURATION}/${EXECUTEABLE}.app")
endif ()
install(CODE "
include(BundleUtilities)
set(BU_CHMOD_BUNDLE_ITEMS 1)
fixup_bundle(\"${APP_BUNDLE_PATH}\" \"${BUNDLELIBS}\" \"../libqethereum ../libethereum ../secp256k1\")
" COMPONENT RUNTIME )
# Cleanup duplicate libs from macdeployqt
install(CODE "
file(GLOB LINGER_RM \"${APP_BUNDLE_PATH}/Contents/Frameworks/*.dylib\")
if (LINGER_RM)
file(REMOVE \${LINGER_RM})
endif ()
")
elseif ("${TARGET_PLATFORM}" STREQUAL "w64")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-keep-inline-dllexport -static-libgcc -static-libstdc++ -static")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-s -Wl,-subsystem,windows -mthreads -L/usr/x86_64-w64-mingw32/plugins/platforms")
target_link_libraries(${EXECUTEABLE} gcc)
target_link_libraries(${EXECUTEABLE} mingw32 qtmain mswsock iphlpapi qwindows shlwapi Qt5PlatformSupport opengl32 gdi32 comdlg32 oleaut32 imm32 winmm ole32 uuid ws2_32)
target_link_libraries(${EXECUTEABLE} boost_system-mt-s)
target_link_libraries(${EXECUTEABLE} boost_filesystem-mt-s)
target_link_libraries(${EXECUTEABLE} boost_thread_win32-mt-s)
target_link_libraries(${EXECUTEABLE} crypt32)
target_link_libraries(${EXECUTEABLE} Qt5PlatformSupport)
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS)
elseif (UNIX)
set(EXECUTABLE AlethZero)
else ()
target_link_libraries(${EXECUTEABLE} boost_system)
target_link_libraries(${EXECUTEABLE} boost_filesystem)
find_package(Threads REQUIRED)
target_link_libraries(${EXECUTEABLE} ${CMAKE_THREAD_LIBS_INIT})
install( TARGETS ${EXECUTEABLE} RUNTIME DESTINATION bin )
set(EXECUTABLE alethzero)
endif ()
# eth_add_executable is defined in cmake/EthExecutableHelper.cmake
eth_add_executable(${EXECUTABLE}
ICON alethzero
UI_RESOURCES alethzero.icns Main.ui
WIN_RESOURCES alethzero.rc
)
add_dependencies(${EXECUTABLE} BuildInfo.h)
target_link_libraries(${EXECUTABLE} Qt5::Core)
target_link_libraries(${EXECUTABLE} webthree)
target_link_libraries(${EXECUTABLE} qethereum)
target_link_libraries(${EXECUTABLE} ethereum)
target_link_libraries(${EXECUTABLE} evm)
target_link_libraries(${EXECUTABLE} ethcore)
target_link_libraries(${EXECUTABLE} devcrypto)
target_link_libraries(${EXECUTABLE} secp256k1)
target_link_libraries(${EXECUTABLE} serpent)
target_link_libraries(${EXECUTABLE} lll)
target_link_libraries(${EXECUTABLE} solidity)
target_link_libraries(${EXECUTABLE} evmcore)
target_link_libraries(${EXECUTABLE} devcore)
target_link_libraries(${EXECUTABLE} web3jsonrpc)
target_link_libraries(${EXECUTABLE} jsqrc)
# eth_install_executable is defined in cmake/EthExecutableHelper.cmake
eth_install_executable(${EXECUTABLE})

108
alethzero/MainWin.cpp

@ -65,7 +65,7 @@ static void initUnits(QComboBox* _b)
_b->addItem(QString::fromStdString(units()[n].second), n);
}
static QString fromRaw(dev::h256 _n, unsigned* _inc = nullptr)
QString Main::fromRaw(dev::h256 _n, unsigned* _inc)
{
if (_n)
{
@ -106,6 +106,8 @@ static QString contentsOfQResource(std::string const& res)
}
Address c_config = Address("661005d2720d855f1d9976f88bb10c1a3398c77f");
Address c_newConfig = Address("d5f9d8d94886e70b06e474c3fb14fd43e2f23970");
Address c_nameReg = Address("ddd1cea741d548f90d86fb87a3ae6492e18c03a1");
Main::Main(QWidget *parent) :
QMainWindow(parent),
@ -149,14 +151,13 @@ Main::Main(QWidget *parent) :
statusBar()->addPermanentWidget(ui->peerCount);
statusBar()->addPermanentWidget(ui->mineStatus);
statusBar()->addPermanentWidget(ui->blockCount);
connect(ui->ourAccounts->model(), SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), SLOT(ourAccountsRowsMoved()));
m_webThree.reset(new WebThreeDirect(string("AlethZero/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), getDataDir() + "/AlethZero", false, {"eth", "shh"}));
// w3stubserver, on dealloc, deletes m_qwebConnector
m_qwebConnector = new QWebThreeConnector(); // owned by WebThreeStubServer
m_server.reset(new OurWebThreeStubServer(m_qwebConnector, *web3(), keysAsVector(m_myKeys)));
m_qwebConnector.reset(new QWebThreeConnector());
m_server.reset(new OurWebThreeStubServer(*m_qwebConnector, *web3(), keysAsVector(m_myKeys)));
connect(&*m_server, SIGNAL(onNewId(QString)), SLOT(addNewId(QString)));
m_server->setIdentities(keysAsVector(owned()));
m_server->StartListening();
@ -174,17 +175,17 @@ Main::Main(QWidget *parent) :
connect(f, &QWebFrame::javaScriptWindowObjectCleared, QETH_INSTALL_JS_NAMESPACE(f, this, qweb));
connect(m_qweb, SIGNAL(onNewId(QString)), this, SLOT(addNewId(QString)));
});
connect(ui->webView, &QWebView::loadFinished, [=]()
{
m_qweb->poll();
});
connect(ui->webView, &QWebView::titleChanged, [=]()
{
ui->tabWidget->setTabText(0, ui->webView->title());
});
readSettings();
installWatches();
startTimer(100);
@ -449,8 +450,29 @@ static Public stringToPublic(QString const& _a)
return Public();
}
static Address g_newNameReg;
QString Main::pretty(dev::Address _a) const
{
static std::map<Address, QString> s_memos;
if (!s_memos.count(_a))
{
if (!g_newNameReg)
g_newNameReg = abiOut<Address>(ethereum()->call(c_newConfig, abiIn(1, (u256)1)));
if (g_newNameReg)
{
QString s = QString::fromStdString(toString(abiOut<string32>(ethereum()->call(g_newNameReg, abiIn(2, _a)))));
s_memos[_a] = s;
if (s.size())
return s;
}
}
else
if (s_memos[_a].size())
return s_memos[_a];
h256 n;
if (h160 nameReg = (u160)ethereum()->stateAt(c_config, 0))
@ -470,19 +492,47 @@ QString Main::render(dev::Address _a) const
return QString::fromStdString(_a.abridged());
}
Address Main::fromString(QString const& _a) const
string32 fromString(std::string const& _s)
{
if (_a == "(Create Contract)")
string32 ret;
for (unsigned i = 0; i < 32 && i <= _s.size(); ++i)
ret[i] = i < _s.size() ? _s[i] : 0;
return ret;
}
Address Main::fromString(QString const& _n) const
{
if (_n == "(Create Contract)")
return Address();
string sn = _a.toStdString();
static std::map<QString, Address> s_memos;
if (!s_memos.count(_n))
{
if (!g_newNameReg)
g_newNameReg = abiOut<Address>(ethereum()->call(c_newConfig, abiIn(1, (u256)1)));
if (g_newNameReg)
{
Address a = abiOut<Address>(ethereum()->call(g_newNameReg, abiIn(0, ::fromString(_n.toStdString()))));
s_memos[_n] = a;
if (a)
return a;
}
}
else
if (s_memos[_n])
return s_memos[_n];
string sn = _n.toStdString();
if (sn.size() > 32)
sn.resize(32);
h256 n;
memcpy(n.data(), sn.data(), sn.size());
memset(n.data() + sn.size(), 0, 32 - sn.size());
if (_a.size())
if (_n.size())
{
if (h160 nameReg = (u160)ethereum()->stateAt(c_config, 0))
if (h256 a = ethereum()->stateAt(nameReg, n))
return right160(a);
@ -490,8 +540,9 @@ Address Main::fromString(QString const& _a) const
if (h256 a = ethereum()->stateAt(m_nameReg, n))
return right160(a);
}
if (_a.size() == 40)
return Address(fromHex(_a.toStdString()));
if (_n.size() == 40)
return Address(fromHex(_n.toStdString()));
else
return Address();
}
@ -1068,7 +1119,7 @@ void Main::timerEvent(QTimerEvent*)
// 7/18, Alex: aggregating timers, prelude to better threading?
// Runs much faster on slower dual-core processors
static int interval = 100;
// refresh mining every 200ms
if (interval / 100 % 2 == 0)
refreshMining();
@ -1094,7 +1145,7 @@ void Main::timerEvent(QTimerEvent*)
}
else
interval += 100;
if (m_qweb)
m_qweb->poll();
@ -1113,7 +1164,7 @@ string Main::renderDiff(dev::eth::StateDiff const& _d) const
s << "<hr/>";
dev::eth::AccountDiff const& ad = i.second;
s << "<code style=\"white-space: pre; font-weight: bold\">" << ad.lead() << " </code>" << " <b>" << render(i.first).toStdString() << "</b>";
s << "<code style=\"white-space: pre; font-weight: bold\">" << lead(ad.changeType()) << " </code>" << " <b>" << render(i.first).toStdString() << "</b>";
if (!ad.exist.to())
continue;
@ -1134,7 +1185,7 @@ string Main::renderDiff(dev::eth::StateDiff const& _d) const
s << " (" << ad.code.from().size() << " bytes)";
}
for (pair<u256, dev::eth::Diff<u256>> const& i: ad.storage)
for (pair<u256, dev::Diff<u256>> const& i: ad.storage)
{
s << "<br/><code style=\"white-space: pre\">";
if (!i.second.from())
@ -1351,7 +1402,7 @@ void Main::on_debugCurrent_triggered()
{
unsigned txi = item->data(Qt::UserRole + 1).toInt();
m_executiveState = ethereum()->state(txi + 1, h);
m_currentExecution = unique_ptr<Executive>(new Executive(m_executiveState, 0));
m_currentExecution = unique_ptr<Executive>(new Executive(m_executiveState, ethereum()->blockChain(), 0));
Transaction t = m_executiveState.pending()[txi];
m_executiveState = m_executiveState.fromPending(txi);
auto r = t.rlp();
@ -1712,7 +1763,7 @@ void Main::on_net_triggered()
{
ui->port->setEnabled(!ui->net->isChecked());
ui->clientName->setEnabled(!ui->net->isChecked());
string n = string("AlethZero/v") + dev::Version;
string n = string("AlethZero/v") + dev::Version;
if (ui->clientName->text().size())
n += "/" + ui->clientName->text().toStdString();
n += "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM);
@ -1804,7 +1855,7 @@ void Main::on_debug_clicked()
{
Secret s = i.secret();
m_executiveState = ethereum()->postState();
m_currentExecution = unique_ptr<Executive>(new Executive(m_executiveState, 0));
m_currentExecution = unique_ptr<Executive>(new Executive(m_executiveState, ethereum()->blockChain(), 0));
Transaction t = isCreation() ?
Transaction(value(), gasPrice(), ui->gas->value(), m_data, m_executiveState.transactionsFrom(dev::toAddress(s)), s) :
Transaction(value(), gasPrice(), ui->gas->value(), fromString(ui->destination->currentText()), m_data, m_executiveState.transactionsFrom(dev::toAddress(s)), s);
@ -2192,18 +2243,3 @@ void Main::refreshWhispers()
ui->whispers->addItem(item);
}
}
// extra bits needed to link on VS
#ifdef _MSC_VER
// include moc file, ofuscated to hide from automoc
#include\
"moc_MainWin.cpp"
#include\
"moc_MiningView.cpp"
#include\
"moc_DownloadView.cpp"
#endif

10
alethzero/MainWin.h

@ -69,7 +69,7 @@ struct WorldState
class Main : public QMainWindow
{
Q_OBJECT
public:
explicit Main(QWidget *parent = 0);
~Main();
@ -79,7 +79,7 @@ public:
std::shared_ptr<dev::shh::WhisperHost> whisper() const { return m_webThree->whisper(); }
QList<dev::KeyPair> owned() const { return m_myIdentities + m_myKeys; }
public slots:
void load(QString _file);
void note(QString _entry);
@ -146,7 +146,7 @@ private slots:
void on_debugDumpState_triggered(int _add = 1);
void on_debugDumpStatePre_triggered();
void on_refresh_triggered();
void on_usePrivate_triggered();
void on_usePrivate_triggered();
void on_enableOptimizer_triggered();
void on_turboMining_triggered();
void on_go_triggered();
@ -256,7 +256,9 @@ private:
QString m_logHistory;
bool m_logChanged = true;
QWebThreeConnector* m_qwebConnector;
std::unique_ptr<QWebThreeConnector> m_qwebConnector;
std::unique_ptr<OurWebThreeStubServer> m_server;
QWebThree* m_qweb = nullptr;
static QString fromRaw(dev::h256 _n, unsigned* _inc = nullptr);
};

4
alethzero/OurWebThreeStubServer.cpp

@ -14,7 +14,7 @@
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file OurWebThreeStubServer.h
/** @file OurWebThreeStubServer.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
@ -24,7 +24,7 @@ using namespace std;
using namespace dev;
using namespace dev::eth;
OurWebThreeStubServer::OurWebThreeStubServer(jsonrpc::AbstractServerConnector* _conn, dev::WebThreeDirect& _web3, std::vector<dev::KeyPair> const& _accounts):
OurWebThreeStubServer::OurWebThreeStubServer(jsonrpc::AbstractServerConnector& _conn, dev::WebThreeDirect& _web3, std::vector<dev::KeyPair> const& _accounts):
WebThreeStubServer(_conn, _web3, _accounts)
{}

4
alethzero/OurWebThreeStubServer.h

@ -14,7 +14,7 @@
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file OurWebThreeStubServer.cpp
/** @file OurWebThreeStubServer.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
@ -29,7 +29,7 @@ class OurWebThreeStubServer: public QObject, public WebThreeStubServer
Q_OBJECT
public:
OurWebThreeStubServer(jsonrpc::AbstractServerConnector* _conn, dev::WebThreeDirect& _web3, std::vector<dev::KeyPair> const& _accounts);
OurWebThreeStubServer(jsonrpc::AbstractServerConnector& _conn, dev::WebThreeDirect& _web3, std::vector<dev::KeyPair> const& _accounts);
virtual std::string shh_newIdentity() override;

BIN
alethzero/alethzero.ico

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 KiB

1
alethzero/alethzero.rc

@ -0,0 +1 @@
APP_ICON ICON DISCARDABLE "alethzero.ico"

50
boost/process.hpp

@ -1,50 +0,0 @@
//
// Boost.Process
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
// Copyright (c) 2008, 2009 Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
/**
* \file boost/process.hpp
*
* Convenience header that includes all other Boost.Process public header
* files. It is important to note that those headers that are specific to
* a given platform are only included if the library is being used in that
* same platform.
*/
#ifndef BOOST_PROCESS_HPP
#define BOOST_PROCESS_HPP
#include <boost/process/config.hpp>
#if defined(BOOST_POSIX_API)
# include <boost/process/posix_child.hpp>
# include <boost/process/posix_context.hpp>
# include <boost/process/posix_operations.hpp>
# include <boost/process/posix_status.hpp>
#elif defined(BOOST_WINDOWS_API)
# include <boost/process/win32_child.hpp>
# include <boost/process/win32_context.hpp>
# include <boost/process/win32_operations.hpp>
#else
# error "Unsupported platform."
#endif
#include <boost/process/child.hpp>
#include <boost/process/context.hpp>
#include <boost/process/environment.hpp>
#include <boost/process/operations.hpp>
#include <boost/process/pistream.hpp>
#include <boost/process/postream.hpp>
#include <boost/process/process.hpp>
#include <boost/process/self.hpp>
#include <boost/process/status.hpp>
#include <boost/process/stream_behavior.hpp>
#endif

200
boost/process/child.hpp

@ -1,200 +0,0 @@
//
// Boost.Process
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
// Copyright (c) 2008, 2009 Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
/**
* \file boost/process/child.hpp
*
* Includes the declaration of the child class.
*/
#ifndef BOOST_PROCESS_CHILD_HPP
#define BOOST_PROCESS_CHILD_HPP
#include <boost/process/config.hpp>
#if defined(BOOST_POSIX_API)
# include <sys/types.h>
# include <sys/wait.h>
# include <cerrno>
#elif defined(BOOST_WINDOWS_API)
# include <windows.h>
#else
# error "Unsupported platform."
#endif
#include <boost/process/process.hpp>
#include <boost/process/pistream.hpp>
#include <boost/process/postream.hpp>
#include <boost/process/status.hpp>
#include <boost/process/detail/file_handle.hpp>
#include <boost/system/system_error.hpp>
#include <boost/throw_exception.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/assert.hpp>
#include <vector>
namespace boost {
namespace process {
/**
* Generic implementation of the Child concept.
*
* The child class implements the Child concept in an operating system
* agnostic way.
*/
class child : public process
{
public:
/**
* Gets a reference to the child's standard input stream.
*
* Returns a reference to a postream object that represents the
* standard input communication channel with the child process.
*/
postream &get_stdin() const
{
BOOST_ASSERT(stdin_);
return *stdin_;
}
/**
* Gets a reference to the child's standard output stream.
*
* Returns a reference to a pistream object that represents the
* standard output communication channel with the child process.
*/
pistream &get_stdout() const
{
BOOST_ASSERT(stdout_);
return *stdout_;
}
/**
* Gets a reference to the child's standard error stream.
*
* Returns a reference to a pistream object that represents the
* standard error communication channel with the child process.
*/
pistream &get_stderr() const
{
BOOST_ASSERT(stderr_);
return *stderr_;
}
/**
* Blocks and waits for the child process to terminate.
*
* Returns a status object that represents the child process'
* finalization condition. The child process object ceases to be
* valid after this call.
*
* \remark Blocking remarks: This call blocks if the child
* process has not finalized execution and waits until
* it terminates.
*/
status wait()
{
#if defined(BOOST_POSIX_API)
int s;
if (::waitpid(get_id(), &s, 0) == -1)
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::child::wait: waitpid(2) failed"));
return status(s);
#elif defined(BOOST_WINDOWS_API)
::WaitForSingleObject(process_handle_.get(), INFINITE);
DWORD code;
if (!::GetExitCodeProcess(process_handle_.get(), &code))
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::child::wait: GetExitCodeProcess failed"));
return status(code);
#endif
}
/**
* Creates a new child object that represents the just spawned child
* process \a id.
*
* The \a fhstdin, \a fhstdout and \a fhstderr file handles represent
* the parent's handles used to communicate with the corresponding
* data streams. They needn't be valid but their availability must
* match the redirections configured by the launcher that spawned this
* process.
*
* The \a fhprocess handle represents a handle to the child process.
* It is only used on Windows as the implementation of wait() needs a
* process handle.
*/
child(id_type id, detail::file_handle fhstdin, detail::file_handle fhstdout, detail::file_handle fhstderr, detail::file_handle fhprocess = detail::file_handle())
: process(id)
#if defined(BOOST_WINDOWS_API)
, process_handle_(fhprocess.release(), ::CloseHandle)
#endif
{
if (fhstdin.valid())
stdin_.reset(new postream(fhstdin));
if (fhstdout.valid())
stdout_.reset(new pistream(fhstdout));
if (fhstderr.valid())
stderr_.reset(new pistream(fhstderr));
}
private:
/**
* The standard input stream attached to the child process.
*
* This postream object holds the communication channel with the
* child's process standard input. It is stored in a pointer because
* this field is only valid when the user requested to redirect this
* data stream.
*/
boost::shared_ptr<postream> stdin_;
/**
* The standard output stream attached to the child process.
*
* This postream object holds the communication channel with the
* child's process standard output. It is stored in a pointer because
* this field is only valid when the user requested to redirect this
* data stream.
*/
boost::shared_ptr<pistream> stdout_;
/**
* The standard error stream attached to the child process.
*
* This postream object holds the communication channel with the
* child's process standard error. It is stored in a pointer because
* this field is only valid when the user requested to redirect this
* data stream.
*/
boost::shared_ptr<pistream> stderr_;
#if defined(BOOST_WINDOWS_API)
/**
* Process handle owned by RAII object.
*/
boost::shared_ptr<void> process_handle_;
#endif
};
/**
* Collection of child objects.
*
* This convenience type represents a collection of child objects backed
* by a vector.
*/
typedef std::vector<child> children;
}
}
#endif

41
boost/process/config.hpp

@ -1,41 +0,0 @@
//
// Boost.Process
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
// Copyright (c) 2008, 2009 Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
/**
* \file boost/process/config.hpp
*
* Defines macros that are used by the library's code to determine the
* operating system it is running under and the features it supports.
*/
#ifndef BOOST_PROCESS_CONFIG_HPP
#define BOOST_PROCESS_CONFIG_HPP
#include <boost/config.hpp>
#include <boost/system/config.hpp>
#if defined(BOOST_POSIX_API) || defined(BOOST_PROCESS_DOXYGEN)
# if !defined(BOOST_PROCESS_POSIX_PATH_MAX)
/**
* The macro BOOST_PROCESS_POSIX_PATH_MAX is set to a positive integer
* value which specifies the system's maximal supported path length.
* By default it is set to 259. You should set the macro to PATH_MAX
* which should be defined in limits.h provided by your operating system
* if you experience problems when instantiating a context. The
* constructor of basic_work_directory_context tries to find out
* dynamically the maximal supported path length but uses
* BOOST_PROCESS_POSIX_PATH_MAX if it fails.
*/
# define BOOST_PROCESS_POSIX_PATH_MAX 259
# endif
#endif
#endif

209
boost/process/context.hpp

@ -1,209 +0,0 @@
//
// Boost.Process
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
// Copyright (c) 2008, 2009 Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
/**
* \file boost/process/context.hpp
*
* Includes the declaration of the context class and several accessory
* base classes.
*/
#ifndef BOOST_PROCESS_CONTEXT_HPP
#define BOOST_PROCESS_CONTEXT_HPP
#include <boost/process/config.hpp>
#if defined(BOOST_POSIX_API)
# include <boost/scoped_array.hpp>
# include <cerrno>
# include <unistd.h>
#elif defined(BOOST_WINDOWS_API)
# include <windows.h>
#else
# error "Unsupported platform."
#endif
#include <boost/process/environment.hpp>
#include <boost/process/stream_behavior.hpp>
#include <boost/system/system_error.hpp>
#include <boost/throw_exception.hpp>
#include <boost/assert.hpp>
#include <string>
#include <vector>
namespace boost {
namespace process {
/**
* Base context class that defines the child's work directory.
*
* Base context class that defines the necessary fields to configure a
* child's work directory. This class is useless on its own because no
* function in the library will accept it as a valid Context
* implementation.
*/
template <class Path>
class basic_work_directory_context
{
public:
/**
* Constructs a new work directory context.
*
* Constructs a new work directory context making the work directory
* described by the new object point to the caller's current working
* directory.
*/
basic_work_directory_context()
{
#if defined(BOOST_POSIX_API)
errno = 0;
long size = ::pathconf(".", _PC_PATH_MAX);
if (size == -1 && errno)
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::basic_work_directory_context::basic_work_directory_context: pathconf(2) failed"));
else if (size == -1)
size = BOOST_PROCESS_POSIX_PATH_MAX;
boost::scoped_array<char> cwd(new char[size]);
if (!::getcwd(cwd.get(), size))
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::basic_work_directory_context::basic_work_directory_context: getcwd(2) failed"));
work_directory = cwd.get();
#elif defined(BOOST_WINDOWS_API)
char cwd[MAX_PATH];
if (!::GetCurrentDirectoryA(sizeof(cwd), cwd))
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::basic_work_directory_context::basic_work_directory_context: GetCurrentDirectory failed"));
work_directory = cwd;
#endif
BOOST_ASSERT(!work_directory.empty());
}
/**
* The process' initial work directory.
*
* The work directory is the directory in which the process starts
* execution.
*/
Path work_directory;
};
/**
* Base context class that defines the child's environment.
*
* Base context class that defines the necessary fields to configure a
* child's environment variables. This class is useless on its own
* because no function in the library will accept it as a valid Context
* implementation.
*/
class environment_context
{
public:
/**
* The process' environment.
*
* Contains the list of environment variables, alongside with their
* values, that will be passed to the spawned child process.
*/
boost::process::environment environment;
};
/**
* Process startup execution context.
*
* The context class groups all the parameters needed to configure a
* process' environment during its creation.
*/
template <class Path>
class basic_context : public basic_work_directory_context<Path>, public environment_context
{
public:
/**
* Child's stdin behavior.
*/
stream_behavior stdin_behavior;
/**
* Child's stdout behavior.
*/
stream_behavior stdout_behavior;
/**
* Child's stderr behavior.
*/
stream_behavior stderr_behavior;
};
typedef basic_context<std::string> context;
/**
* Represents a child process in a pipeline.
*
* This convenience class is a triplet that holds all the data required
* to spawn a new child process in a pipeline.
*/
template <class Executable, class Arguments, class Context>
class basic_pipeline_entry
{
public:
/**
* The executable to launch.
*/
Executable executable;
/**
* The set of arguments to pass to the executable.
*/
Arguments arguments;
/**
* The child's execution context.
*/
Context context;
/**
* The type of the Executable concept used in this template
* instantiation.
*/
typedef Executable executable_type;
/**
* The type of the Arguments concept used in this template
* instantiation.
*/
typedef Arguments arguments_type;
/**
* The type of the Context concept used in this template
* instantiation.
*/
typedef Context context_type;
/**
* Constructs a new pipeline_entry object.
*
* Given the executable, set of arguments and execution triplet,
* constructs a new pipeline_entry object that holds the three
* values.
*/
basic_pipeline_entry(const Executable &exe, const Arguments &args, const Context &ctx)
: executable(exe),
arguments(args),
context(ctx)
{
}
};
/**
* Default instantiation of basic_pipeline_entry.
*/
typedef basic_pipeline_entry<std::string, std::vector<std::string>, context> pipeline_entry;
}
}
#endif

406
boost/process/detail/file_handle.hpp

@ -1,406 +0,0 @@
//
// Boost.Process
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
// Copyright (c) 2008, 2009 Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
/**
* \file boost/process/detail/file_handle.hpp
*
* Includes the declaration of the file_handle class. This file is for
* internal usage only and must not be included by the library user.
*/
#ifndef BOOST_PROCESS_DETAIL_FILE_HANDLE_HPP
#define BOOST_PROCESS_DETAIL_FILE_HANDLE_HPP
#include <boost/process/config.hpp>
#if defined(BOOST_POSIX_API)
# include <cerrno>
# include <unistd.h>
#elif defined(BOOST_WINDOWS_API)
# include <windows.h>
#else
# error "Unsupported platform."
#endif
#include <boost/assert.hpp>
#include <boost/system/system_error.hpp>
#include <boost/throw_exception.hpp>
namespace boost {
namespace process {
namespace detail {
/**
* Simple RAII model for system file handles.
*
* The \a file_handle class is a simple RAII model for native system file
* handles. This class wraps one of such handles grabbing its ownership,
* and automaticaly closes it upon destruction. It is basically used
* inside the library to avoid leaking open file handles, shall an
* unexpected execution trace occur.
*
* A \a file_handle object can be copied but doing so invalidates the
* source object. There can only be a single valid \a file_handle object
* for a given system file handle. This is similar to std::auto_ptr's
* semantics.
*
* This class also provides some convenience methods to issue special file
* operations under their respective platforms.
*/
class file_handle
{
public:
#if defined(BOOST_PROCESS_DOXYGEN)
/**
* Opaque name for the native handle type.
*
* Each operating system identifies file handles using a specific type.
* The \a handle_type type is used to transparently refer to file
* handles regarless of the operating system in which this class is
* used.
*
* If this class is used on a POSIX system, \a NativeSystemHandle is
* an integer type while it is a \a HANDLE on a Windows system.
*/
typedef NativeSystemHandle handle_type;
#elif defined(BOOST_POSIX_API)
typedef int handle_type;
#elif defined(BOOST_WINDOWS_API)
typedef HANDLE handle_type;
#endif
/**
* Constructs an invalid file handle.
*
* This constructor creates a new \a file_handle object that represents
* an invalid file handle. An invalid file handle can be copied but
* cannot be manipulated in any way (except checking for its validity).
*
* \see valid()
*/
file_handle()
: handle_(invalid_value())
{
}
/**
* Constructs a new file handle from a native file handle.
*
* This constructor creates a new \a file_handle object that takes
* ownership of the given \a h native file handle. The user must not
* close \a h on his own during the lifetime of the new object.
* Ownership can be reclaimed using release().
*
* \pre The native file handle must be valid; a close operation must
* succeed on it.
* \see release()
*/
file_handle(handle_type h)
: handle_(h)
{
BOOST_ASSERT(handle_ != invalid_value());
}
/**
* Copy constructor; invalidates the source handle.
*
* This copy constructor creates a new file handle from a given one.
* Ownership of the native file handle is transferred to the new
* object, effectively invalidating the source file handle. This
* avoids having two live \a file_handle objects referring to the
* same native file handle. The source file handle needs not be
* valid in the name of simplicity.
*
* \post The source file handle is invalid.
* \post The new file handle owns the source's native file handle.
*/
file_handle(const file_handle &fh)
: handle_(fh.handle_)
{
fh.handle_ = invalid_value();
}
/**
* Releases resources if the handle is valid.
*
* If the file handle is valid, the destructor closes it.
*
* \see valid()
*/
~file_handle()
{
if (valid())
close();
}
/**
* Assignment operator; invalidates the source handle.
*
* This assignment operator transfers ownership of the RHS file
* handle to the LHS one, effectively invalidating the source file
* handle. This avoids having two live \a file_handle objects
* referring to the same native file handle. The source file
* handle needs not be valid in the name of simplicity.
*
* \post The RHS file handle is invalid.
* \post The LHS file handle owns RHS' native file handle.
* \return A reference to the LHS file handle.
*/
file_handle &operator=(const file_handle &fh)
{
handle_ = fh.handle_;
fh.handle_ = invalid_value();
return *this;
}
/**
* Checks whether the file handle is valid or not.
*
* Returns a boolean indicating whether the file handle is valid or
* not. If the file handle is invalid, no other methods can be
* executed other than the destructor.
*
* \return true if the file handle is valid; false otherwise.
*/
bool valid() const
{
return handle_ != invalid_value();
}
/**
* Closes the file handle.
*
* Explicitly closes the file handle, which must be valid. Upon
* exit, the handle is not valid any more.
*
* \pre The file handle is valid.
* \post The file handle is invalid.
* \post The native file handle is closed.
*/
void close()
{
BOOST_ASSERT(valid());
#if defined(BOOST_POSIX_API)
::close(handle_);
#elif defined(BOOST_WINDOWS_API)
::CloseHandle(handle_);
#endif
handle_ = invalid_value();
}
/**
* Reclaims ownership of the native file handle.
*
* Explicitly reclaims ownership of the native file handle contained
* in the \a file_handle object, returning the native file handle.
* The caller is responsible of closing it later on.
*
* \pre The file handle is valid.
* \post The file handle is invalid.
* \return The native file handle.
*/
handle_type release()
{
BOOST_ASSERT(valid());
handle_type h = handle_;
handle_ = invalid_value();
return h;
}
/**
* Gets the native file handle.
*
* Returns the native file handle for the \a file_handle object.
* The caller can issue any operation on it except closing it.
* If closing is required, release() shall be used.
*
* \pre The file handle is valid.
* \post The file handle is valid.
* \return The native file handle.
*/
handle_type get() const
{
BOOST_ASSERT(valid());
return handle_;
}
#if defined(BOOST_POSIX_API) || defined(BOOST_PROCESS_DOXYGEN)
/**
* Changes the native file handle to the given one.
*
* Given a new native file handle \a h, this operation assigns this
* handle to the current object, closing its old native file handle.
* In other words, it first calls dup2() to remap the old handle to
* the new one and then closes the old handle.
*
* If \a h is open, it is automatically closed by dup2().
*
* This operation is only available in POSIX systems.
*
* \pre The file handle is valid.
* \pre The native file handle \a h is valid; i.e., it must be
* closeable.
* \post The file handle's native file handle is \a h.
* \throw boost::system::system_error If the internal remapping
* operation fails.
*/
void posix_remap(handle_type h)
{
BOOST_ASSERT(valid());
if (::dup2(handle_, h) == -1)
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::file_handle::posix_remap: dup2(2) failed"));
if (::close(handle_) == -1)
{
::close(h);
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::file_handle::posix_remap: close(2) failed"));
}
handle_ = h;
}
/**
* Duplicates an open native file handle.
*
* Given a native file handle \a h1, this routine duplicates it so
* that it ends up being identified by the native file handle \a h2
* and returns a new \a file_handle owning \a h2.
*
* This operation is only available in POSIX systems.
*
* \pre The native file handle \a h1 is open.
* \pre The native file handle \a h2 is valid (non-negative).
* \post The native file handle \a h1 is closed.
* \post The native file handle \a h2 is the same as the old \a h1
* from the operating system's point of view.
* \return A new \a file_handle object that owns \a h2.
* \throw boost::system::system_error If dup2() fails.
*/
static file_handle posix_dup(int h1, int h2)
{
if (::dup2(h1, h2) == -1)
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::file_handle::posix_dup: dup2(2) failed"));
return file_handle(h2);
}
#endif
#if defined(BOOST_WINDOWS_API) || defined(BOOST_PROCESS_DOXYGEN)
/**
* Duplicates the \a h native file handle.
*
* Given a native file handle \a h, this routine constructs a new
* \a file_handle object that owns a new duplicate of \a h. The
* duplicate's inheritable flag is set to the value of \a inheritable.
*
* This operation is only available in Windows systems.
*
* \pre The native file handle \a h is valid.
* \return A file handle owning a duplicate of \a h.
* \throw boost::system::system_error If DuplicateHandle() fails.
*/
static file_handle win32_dup(HANDLE h, bool inheritable)
{
HANDLE h2;
if (!::DuplicateHandle(::GetCurrentProcess(), h, ::GetCurrentProcess(), &h2, 0, inheritable ? TRUE : FALSE, DUPLICATE_SAME_ACCESS))
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::file_handle::win32_dup: DuplicateHandle failed"));
return file_handle(h2);
}
/**
* Creates a new duplicate of a standard file handle.
*
* Constructs a new \a file_handle object that owns a duplicate of a
* standard file handle. The \a d parameter specifies which standard
* file handle to duplicate and can be one of \a STD_INPUT_HANDLE,
* \a STD_OUTPUT_HANDLE or \a STD_ERROR_HANDLE. The duplicate's
* inheritable flag is set to the value of \a inheritable.
*
* This operation is only available in Windows systems.
*
* \pre \a d refers to one of the standard handles as described above.
* \return A file handle owning a duplicate of the standard handle
* referred to by \a d.
* \throw boost::system::system_error If GetStdHandle() or
* DuplicateHandle() fails.
*/
static file_handle win32_std(DWORD d, bool inheritable)
{
BOOST_ASSERT(d == STD_INPUT_HANDLE || d == STD_OUTPUT_HANDLE || d == STD_ERROR_HANDLE);
HANDLE h = ::GetStdHandle(d);
if (h == INVALID_HANDLE_VALUE)
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::file_handle::win32_std: GetStdHandle failed"));
return win32_dup(h, inheritable);
}
/**
* Changes the file handle's inheritable flag.
*
* Changes the file handle's inheritable flag to \a i. It is not
* necessary for the file handle's flag to be different than \a i.
*
* This operation is only available in Windows systems.
*
* \pre The file handle is valid.
* \post The native file handle's inheritable flag is set to \a i.
* \throw boost::system::system_error If the property change fails.
*/
void win32_set_inheritable(bool i)
{
BOOST_ASSERT(valid());
if (!::SetHandleInformation(handle_, HANDLE_FLAG_INHERIT, i ? HANDLE_FLAG_INHERIT : 0))
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::file_handle::win32_set_inheritable: SetHandleInformation failed"));
}
#endif
private:
/**
* Internal handle value.
*
* This variable holds the native handle value for the file handle
* hold by this object. It is interesting to note that this needs
* to be mutable because the copy constructor and the assignment
* operator invalidate the source object.
*/
mutable handle_type handle_;
/**
* Constant function representing an invalid handle value.
*
* Returns the platform-specific handle value that represents an
* invalid handle. This is a constant function rather than a regular
* constant because, in the latter case, we cannot define it under
* Windows due to the value being of a complex type.
*/
static handle_type invalid_value()
{
#if defined(BOOST_POSIX_API)
return -1;
#elif defined(BOOST_WINDOWS_API)
return INVALID_HANDLE_VALUE;
#endif
}
};
}
}
}
#endif

187
boost/process/detail/pipe.hpp

@ -1,187 +0,0 @@
//
// Boost.Process
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
// Copyright (c) 2008, 2009 Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
/**
* \file boost/process/detail/pipe.hpp
*
* Includes the declaration of the pipe class. This file is for
* internal usage only and must not be included by the library user.
*/
#ifndef BOOST_PROCESS_DETAIL_PIPE_HPP
#define BOOST_PROCESS_DETAIL_PIPE_HPP
#include <boost/process/config.hpp>
#if defined(BOOST_POSIX_API)
# include <unistd.h>
# include <cerrno>
#elif defined(BOOST_WINDOWS_API)
# if defined(BOOST_PROCESS_WINDOWS_USE_NAMED_PIPE)
# include <boost/lexical_cast.hpp>
# include <string>
# endif
# include <windows.h>
#else
# error "Unsupported platform."
#endif
#include <boost/process/detail/file_handle.hpp>
#include <boost/system/system_error.hpp>
#include <boost/throw_exception.hpp>
namespace boost {
namespace process {
namespace detail {
/**
* Simple RAII model for anonymous pipes.
*
* The pipe class is a simple RAII model for anonymous pipes. It
* provides a portable constructor that allocates a new %pipe and creates
* a pipe object that owns the two file handles associated to it: the
* read end and the write end.
*
* These handles can be retrieved for modification according to
* file_handle semantics. Optionally, their ownership can be transferred
* to external \a file_handle objects which comes handy when the two
* ends need to be used in different places (i.e. after a POSIX fork()
* system call).
*
* Pipes can be copied following the same semantics as file handles.
* In other words, copying a %pipe object invalidates the source one.
*
* \see file_handle
*/
class pipe
{
public:
/**
* Creates a new %pipe.
*
* The default pipe constructor allocates a new anonymous %pipe
* and assigns its ownership to the created pipe object. On Windows
* when the macro BOOST_PROCESS_WINDOWS_USE_NAMED_PIPE is defined
* a named pipe is created. This is required if asynchronous I/O
* should be used as asynchronous I/O is only supported by named
* pipes on Windows.
*
* \throw boost::system::system_error If the anonymous %pipe
* creation fails.
*/
pipe()
{
file_handle::handle_type hs[2];
#if defined(BOOST_POSIX_API)
if (::pipe(hs) == -1)
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::pipe::pipe: pipe(2) failed"));
#elif defined(BOOST_WINDOWS_API)
SECURITY_ATTRIBUTES sa;
ZeroMemory(&sa, sizeof(sa));
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = FALSE;
# if defined(BOOST_PROCESS_WINDOWS_USE_NAMED_PIPE)
static unsigned int nextid = 0;
std::string pipe = "\\\\.\\pipe\\boost_process_" + boost::lexical_cast<std::string>(::GetCurrentProcessId()) + "_" + boost::lexical_cast<std::string>(nextid++);
hs[0] = ::CreateNamedPipeA(pipe.c_str(), PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, 0, 1, 8192, 8192, 0, &sa);
if (hs[0] == INVALID_HANDLE_VALUE)
boost::throw_exception(boost::system::system_error(::GetLastError(), boost::system::system_category(), "boost::process::detail::pipe::pipe: CreateNamedPipe failed"));
hs[1] = ::CreateFileA(pipe.c_str(), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (hs[1] == INVALID_HANDLE_VALUE)
boost::throw_exception(boost::system::system_error(::GetLastError(), boost::system::system_category(), "boost::process::detail::pipe::pipe: CreateFile failed"));
OVERLAPPED overlapped;
ZeroMemory(&overlapped, sizeof(overlapped));
overlapped.hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
if (!overlapped.hEvent)
boost::throw_exception(boost::system::system_error(::GetLastError(), boost::system::system_category(), "boost::process::detail::pipe::pipe: CreateEvent failed"));
BOOL b = ::ConnectNamedPipe(hs[0], &overlapped);
if (!b)
{
if (::GetLastError() == ERROR_IO_PENDING)
{
if (::WaitForSingleObject(overlapped.hEvent, INFINITE) == WAIT_FAILED)
{
::CloseHandle(overlapped.hEvent);
boost::throw_exception(boost::system::system_error(::GetLastError(), boost::system::system_category(), "boost::process::detail::pipe::pipe: WaitForSingleObject failed"));
}
}
else if (::GetLastError() != ERROR_PIPE_CONNECTED)
{
::CloseHandle(overlapped.hEvent);
boost::throw_exception(boost::system::system_error(::GetLastError(), boost::system::system_category(), "boost::process::detail::pipe::pipe: ConnectNamedPipe failed"));
}
}
::CloseHandle(overlapped.hEvent);
# else
if (!::CreatePipe(&hs[0], &hs[1], &sa, 0))
boost::throw_exception(boost::system::system_error(::GetLastError(), boost::system::system_category(), "boost::process::detail::pipe::pipe: CreatePipe failed"));
# endif
#endif
read_end_ = file_handle(hs[0]);
write_end_ = file_handle(hs[1]);
}
/**
* Returns the %pipe's read end file handle.
*
* Obtains a reference to the %pipe's read end file handle. Care
* should be taken to not duplicate the returned object if ownership
* shall remain to the %pipe.
*
* Duplicating the returned object invalidates its corresponding file
* handle in the %pipe.
*
* \return A reference to the %pipe's read end file handle.
*/
file_handle &rend()
{
return read_end_;
}
/**
* Returns the %pipe's write end file handle.
*
* Obtains a reference to the %pipe's write end file handle. Care
* should be taken to not duplicate the returned object if ownership
* shall remain to the %pipe.
*
* Duplicating the returned object invalidates its corresponding file
* handle in the %pipe.
*
* \return A reference to the %pipe's write end file handle.
*/
file_handle &wend()
{
return write_end_;
}
private:
/**
* The %pipe's read end file handle.
*/
file_handle read_end_;
/**
* The %pipe's write end file handle.
*/
file_handle write_end_;
};
}
}
}
#endif

495
boost/process/detail/posix_ops.hpp

@ -1,495 +0,0 @@
//
// Boost.Process
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
// Copyright (c) 2008, 2009 Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
/**
* \file boost/process/detail/posix_ops.hpp
*
* Provides some convenience functions to start processes under POSIX
* operating systems.
*/
#ifndef BOOST_PROCESS_DETAIL_POSIX_OPS_HPP
#define BOOST_PROCESS_DETAIL_POSIX_OPS_HPP
#include <boost/process/environment.hpp>
#include <boost/process/detail/file_handle.hpp>
#include <boost/process/detail/pipe.hpp>
#include <boost/process/detail/stream_info.hpp>
#include <boost/scoped_array.hpp>
#include <boost/assert.hpp>
#include <boost/system/system_error.hpp>
#include <boost/throw_exception.hpp>
#include <map>
#include <utility>
#include <string>
#include <cerrno>
#include <cstdlib>
#include <cstring>
#include <fcntl.h>
#include <unistd.h>
namespace boost {
namespace process {
namespace detail {
/**
* Converts the command line to an array of C strings.
*
* Converts the command line's list of arguments to the format expected
* by the \a argv parameter in the POSIX execve() system call.
*
* This operation is only available on POSIX systems.
*
* \return The first argument of the pair is an integer that indicates
* how many strings are stored in the second argument. The
* second argument is a NULL-terminated, dynamically allocated
* array of dynamically allocated strings holding the arguments
* to the executable. The caller is responsible of freeing them.
*/
template <class Arguments>
inline std::pair<std::size_t, char**> collection_to_posix_argv(const Arguments &args)
{
std::size_t nargs = args.size();
BOOST_ASSERT(nargs > 0);
char **argv = new char*[nargs + 1];
typename Arguments::size_type i = 0;
for (typename Arguments::const_iterator it = args.begin(); it != args.end(); ++it)
{
argv[i] = new char[it->size() + 1];
std::strncpy(argv[i], it->c_str(), it->size() + 1);
++i;
}
argv[nargs] = 0;
return std::pair<std::size_t, char**>(nargs, argv);
}
/**
* Converts an environment to a char** table as used by execve().
*
* Converts the environment's contents to the format used by the
* execve() system call. The returned char** array is allocated
* in dynamic memory; the caller must free it when not used any
* more. Each entry is also allocated in dynamic memory and is a
* NULL-terminated string of the form var=value; these must also be
* released by the caller.
*
* \return A dynamically allocated char** array that represents
* the environment's content. Each array entry is a
* NULL-terminated string of the form var=value.
*/
inline char **environment_to_envp(const environment &env)
{
char **envp = new char*[env.size() + 1];
environment::size_type i = 0;
for (environment::const_iterator it = env.begin(); it != env.end(); ++it)
{
std::string s = it->first + "=" + it->second;
envp[i] = new char[s.size() + 1];
std::strncpy(envp[i], s.c_str(), s.size() + 1);
++i;
}
envp[i] = 0;
return envp;
}
/**
* Holds a mapping between native file descriptors and their corresponding
* pipes to set up communication between the parent and the %child process.
*/
typedef std::map<int, stream_info> info_map;
/**
* Helper class to configure a POSIX %child.
*
* This helper class is used to hold all the attributes that configure a
* new POSIX %child process and to centralize all the actions needed to
* make them effective.
*
* All its fields are public for simplicity. It is only intended for
* internal use and it is heavily coupled with the Context
* implementations.
*/
struct posix_setup
{
/**
* The work directory.
*
* This string specifies the directory in which the %child process
* starts execution. It cannot be empty.
*/
std::string work_directory;
/**
* The chroot directory, if any.
*
* Specifies the directory in which the %child process is chrooted
* before execution. Empty if this feature is not desired.
*/
std::string chroot;
/**
* The user credentials.
*
* UID that specifies the user credentials to use to run the %child
* process. Defaults to the current UID.
*/
uid_t uid;
/**
* The effective user credentials.
*
* EUID that specifies the effective user credentials to use to run
* the %child process. Defaults to the current EUID.
*/
uid_t euid;
/**
* The group credentials.
*
* GID that specifies the group credentials to use to run the %child
* process. Defaults to the current GID.
*/
gid_t gid;
/**
* The effective group credentials.
*
* EGID that specifies the effective group credentials to use to run
* the %child process. Defaults to the current EGID.
*/
gid_t egid;
/**
* Creates a new properties set.
*
* Creates a new object that has sensible default values for all the
* properties.
*/
posix_setup()
: uid(::getuid()),
euid(::geteuid()),
gid(::getgid()),
egid(::getegid())
{
}
/**
* Sets up the execution environment.
*
* Modifies the current execution environment (that of the %child) so
* that the properties become effective.
*
* \throw boost::system::system_error If any error ocurred during
* environment configuration. The child process should abort
* execution if this happens because its start conditions
* cannot be met.
*/
void operator()() const
{
if (!chroot.empty() && ::chroot(chroot.c_str()) == -1)
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::posix_setup: chroot(2) failed"));
if (gid != ::getgid() && ::setgid(gid) == -1)
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::posix_setup: setgid(2) failed"));
if (egid != ::getegid() && ::setegid(egid) == -1)
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::posix_setup: setegid(2) failed"));
if (uid != ::getuid() && ::setuid(uid) == -1)
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::posix_setup: setuid(2) failed"));
if (euid != ::geteuid() && ::seteuid(euid) == -1)
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::posix_setup: seteuid(2) failed"));
BOOST_ASSERT(!work_directory.empty());
if (::chdir(work_directory.c_str()) == -1)
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::posix_setup: chdir(2) failed"));
}
};
/**
* Configures child process' input streams.
*
* Sets up the current process' input streams to behave according to the
* information in the \a info map. \a closeflags is modified to reflect
* those descriptors that should not be closed because they where modified
* by the function.
*
* Modifies the current execution environment, so this should only be run
* on the child process after the fork(2) has happened.
*
* \throw boost::system::system_error If any error occurs during the
* configuration.
*/
inline void setup_input(info_map &info, bool *closeflags, int maxdescs)
{
for (info_map::iterator it = info.begin(); it != info.end(); ++it)
{
int d = it->first;
stream_info &si = it->second;
BOOST_ASSERT(d < maxdescs);
closeflags[d] = false;
switch (si.type_)
{
case stream_info::use_file:
{
int fd = ::open(si.file_.c_str(), O_RDONLY);
if (fd == -1)
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::setup_input: open(2) of " + si.file_ + " failed"));
if (fd != d)
{
file_handle h(fd);
h.posix_remap(d);
h.release();
}
break;
}
case stream_info::use_handle:
{
if (si.handle_.get() != d)
si.handle_.posix_remap(d);
break;
}
case stream_info::use_pipe:
{
si.pipe_->wend().close();
if (d != si.pipe_->rend().get())
si.pipe_->rend().posix_remap(d);
break;
}
default:
{
BOOST_ASSERT(si.type_ == stream_info::inherit);
break;
}
}
}
}
/**
* Configures child process' output streams.
*
* Sets up the current process' output streams to behave according to the
* information in the \a info map. \a closeflags is modified to reflect
* those descriptors that should not be closed because they where
* modified by the function.
*
* Modifies the current execution environment, so this should only be run
* on the child process after the fork(2) has happened.
*
* \throw boost::system::system_error If any error occurs during the
* configuration.
*/
inline void setup_output(info_map &info, bool *closeflags, int maxdescs)
{
for (info_map::iterator it = info.begin(); it != info.end(); ++it)
{
int d = it->first;
stream_info &si = it->second;
BOOST_ASSERT(d < maxdescs);
closeflags[d] = false;
switch (si.type_)
{
case stream_info::redirect:
{
break;
}
case stream_info::use_file:
{
int fd = ::open(si.file_.c_str(), O_WRONLY);
if (fd == -1)
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::setup_output: open(2) of " + si.file_ + " failed"));
if (fd != d)
{
file_handle h(fd);
h.posix_remap(d);
h.release();
}
break;
}
case stream_info::use_handle:
{
if (si.handle_.get() != d)
si.handle_.posix_remap(d);
break;
}
case stream_info::use_pipe:
{
si.pipe_->rend().close();
if (d != si.pipe_->wend().get())
si.pipe_->wend().posix_remap(d);
break;
}
default:
{
BOOST_ASSERT(si.type_ == stream_info::inherit);
break;
}
}
}
for (info_map::const_iterator it = info.begin(); it != info.end(); ++it)
{
int d = it->first;
const stream_info &si = it->second;
if (si.type_ == stream_info::redirect)
file_handle::posix_dup(si.desc_to_, d).release();
}
}
/**
* Starts a new child process in a POSIX operating system.
*
* This helper functions is provided to simplify the Context's task when
* it comes to starting up a new process in a POSIX operating system.
* The function hides all the details of the fork/exec pair of calls as
* well as all the setup of communication pipes and execution environment.
*
* \param exe The executable to spawn the child process.
* \param args The arguments for the executable.
* \param env The environment variables that the new child process
* receives.
* \param infoin A map describing all input file descriptors to be
* redirected.
* \param infoout A map describing all output file descriptors to be
* redirected.
* \param setup A helper object used to configure the child's execution
* environment.
* \return The new process' PID. The caller is responsible of creating
* an appropriate Child representation for it.
*/
template <class Executable, class Arguments>
inline pid_t posix_start(const Executable &exe, const Arguments &args, const environment &env, info_map &infoin, info_map &infoout, const posix_setup &setup)
{
pid_t pid = ::fork();
if (pid == -1)
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::posix_start: fork(2) failed"));
else if (pid == 0)
{
#if defined(F_MAXFD)
int maxdescs = ::fcntl(-1, F_MAXFD, 0);
if (maxdescs == -1)
maxdescs = ::sysconf(_SC_OPEN_MAX);
#else
int maxdescs = ::sysconf(_SC_OPEN_MAX);
#endif
if (maxdescs == -1)
maxdescs = 1024;
try
{
boost::scoped_array<bool> closeflags(new bool[maxdescs]);
for (int i = 0; i < maxdescs; ++i)
closeflags[i] = true;
setup_input(infoin, closeflags.get(), maxdescs);
setup_output(infoout, closeflags.get(), maxdescs);
for (int i = 0; i < maxdescs; ++i)
{
if (closeflags[i])
::close(i);
}
setup();
}
catch (const boost::system::system_error &e)
{
::write(STDERR_FILENO, e.what(), std::strlen(e.what()));
::write(STDERR_FILENO, "\n", 1);
std::exit(EXIT_FAILURE);
}
std::pair<std::size_t, char**> argcv = collection_to_posix_argv(args);
char **envp = environment_to_envp(env);
::execve(exe.c_str(), argcv.second, envp);
boost::system::system_error e(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::posix_start: execve(2) failed");
for (std::size_t i = 0; i < argcv.first; ++i)
delete[] argcv.second[i];
delete[] argcv.second;
for (std::size_t i = 0; i < env.size(); ++i)
delete[] envp[i];
delete[] envp;
::write(STDERR_FILENO, e.what(), std::strlen(e.what()));
::write(STDERR_FILENO, "\n", 1);
std::exit(EXIT_FAILURE);
}
BOOST_ASSERT(pid > 0);
for (info_map::iterator it = infoin.begin(); it != infoin.end(); ++it)
{
stream_info &si = it->second;
if (si.type_ == stream_info::use_pipe)
si.pipe_->rend().close();
}
for (info_map::iterator it = infoout.begin(); it != infoout.end(); ++it)
{
stream_info &si = it->second;
if (si.type_ == stream_info::use_pipe)
si.pipe_->wend().close();
}
return pid;
}
/**
* Locates a communication pipe and returns one of its endpoints.
*
* Given a \a info map, and a file descriptor \a desc, searches for its
* communicataion pipe in the map and returns one of its endpoints as
* indicated by the \a out flag. This is intended to be used by a
* parent process after a fork(2) call.
*
* \pre If the info map contains the given descriptor, it is configured
* to use a pipe.
* \post The info map does not contain the given descriptor.
* \return If the file descriptor is found in the map, returns the pipe's
* read end if out is true; otherwise its write end. If the
* descriptor is not found returns an invalid file handle.
*/
inline file_handle posix_info_locate_pipe(info_map &info, int desc, bool out)
{
file_handle fh;
info_map::iterator it = info.find(desc);
if (it != info.end())
{
stream_info &si = it->second;
if (si.type_ == stream_info::use_pipe)
{
fh = out ? si.pipe_->rend().release() : si.pipe_->wend().release();
BOOST_ASSERT(fh.valid());
}
info.erase(it);
}
return fh;
}
}
}
}
#endif

176
boost/process/detail/stream_info.hpp

@ -1,176 +0,0 @@
//
// Boost.Process
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
// Copyright (c) 2008, 2009 Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
/**
* \file boost/process/detail/stream_info.hpp
*
* Provides the definition of the stream_info structure.
*/
#ifndef BOOST_PROCESS_DETAIL_STREAM_INFO_HPP
#define BOOST_PROCESS_DETAIL_STREAM_INFO_HPP
#include <boost/process/config.hpp>
#if defined(BOOST_POSIX_API)
# include <unistd.h>
#elif defined(BOOST_WINDOWS_API)
#else
# error "Unsupported platform."
#endif
#include <boost/process/stream_behavior.hpp>
#include <boost/process/detail/file_handle.hpp>
#include <boost/process/detail/pipe.hpp>
#include <boost/optional.hpp>
#include <boost/assert.hpp>
#include <string>
namespace boost {
namespace process {
namespace detail {
/**
* Configuration data for a file descriptor.
*
* This convenience structure provides a compact way to pass information
* around on how to configure a file descriptor. It is a lower-level
* representation of stream_behavior, as it can hold the same information
* but in a way that can be used by the underlying operating system.
*/
struct stream_info
{
/**
* Supported stream types.
*/
enum type
{
/**
* Matches stream_behavior::close.
*/
close,
/**
* Matches stream_behavior::inherit.
*/
inherit,
/**
* Matches stream_behavior::redirect_to_stdout and
* stream_behavior::posix_redirect.
*/
redirect,
/**
* Matches stream_behavior::silence.
*/
use_file,
/**
* TODO: Matches nothing yet ...
*/
use_handle,
/**
* Matches stream_behavior::capture.
*/
use_pipe
};
/**
* Stream type.
*/
type type_;
/**
* Descriptor to use when stream type is set to \a redirect.
*/
int desc_to_;
/**
* File to use when stream type is set to \a use_file.
*/
std::string file_;
/**
* Handle to use when stream type is set to \a use_handle.
*/
file_handle handle_;
/**
* Pipe to use when stream type is set to \a use_pipe.
*/
boost::optional<pipe> pipe_;
/**
* Constructs a new stream_info object.
*/
stream_info(const stream_behavior &sb, bool out)
{
switch (sb.type_)
{
case stream_behavior::close:
{
type_ = close;
break;
}
case stream_behavior::inherit:
{
type_ = inherit;
break;
}
case stream_behavior::redirect_to_stdout:
{
type_ = redirect;
#if defined(BOOST_POSIX_API)
desc_to_ = STDOUT_FILENO;
#elif defined(BOOST_WINDOWS_API)
desc_to_ = 1;
#endif
break;
}
#if defined(BOOST_POSIX_API)
case stream_behavior::posix_redirect:
{
type_ = redirect;
desc_to_ = sb.desc_to_;
break;
}
#endif
case stream_behavior::silence:
{
type_ = use_file;
#if defined(BOOST_POSIX_API)
file_ = out ? "/dev/null" : "/dev/zero";
#elif defined(BOOST_WINDOWS_API)
file_ = "NUL";
#endif
break;
}
case stream_behavior::capture:
{
type_ = use_pipe;
pipe_ = pipe();
break;
}
default:
{
BOOST_ASSERT(false);
}
}
}
};
}
}
}
#endif

231
boost/process/detail/systembuf.hpp

@ -1,231 +0,0 @@
//
// Boost.Process
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
// Copyright (c) 2008, 2009 Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
/**
* \file boost/process/detail/systembuf.hpp
*
* Includes the declaration of the systembuf class. This file is for
* internal usage only and must not be included by the library user.
*/
#ifndef BOOST_PROCESS_DETAIL_SYSTEMBUF_HPP
#define BOOST_PROCESS_DETAIL_SYSTEMBUF_HPP
#include <boost/process/config.hpp>
#if defined(BOOST_POSIX_API)
# include <sys/types.h>
# include <unistd.h>
#elif defined(BOOST_WINDOWS_API)
# include <windows.h>
#else
# error "Unsupported platform."
#endif
#include <boost/noncopyable.hpp>
#include <boost/scoped_array.hpp>
#include <boost/assert.hpp>
#include <streambuf>
#include <cstddef>
namespace boost {
namespace process {
class postream;
namespace detail {
/**
* std::streambuf implementation for system file handles.
*
* systembuf provides a std::streambuf implementation for system file
* handles. Contrarywise to file_handle, this class does \b not take
* ownership of the native file handle; this should be taken care of
* somewhere else.
*
* This class follows the expected semantics of a std::streambuf object.
* However, it is not copyable to avoid introducing inconsistences with
* the on-disk file and the in-memory buffers.
*/
class systembuf : public std::streambuf, public boost::noncopyable
{
friend class ::boost::process::postream;
public:
#if defined(BOOST_PROCESS_DOXYGEN)
/**
* Opaque name for the native handle type.
*/
typedef NativeHandleType handle_type;
#elif defined(BOOST_POSIX_API)
typedef int handle_type;
#elif defined(BOOST_WINDOWS_API)
typedef HANDLE handle_type;
#endif
/**
* Constructs a new systembuf for the given file handle.
*
* This constructor creates a new systembuf object that reads or
* writes data from/to the \a h native file handle. This handle
* is \b not owned by the created systembuf object; the code
* should take care of it externally.
*
* This class buffers input and output; the buffer size may be
* tuned through the \a bufsize parameter, which defaults to 8192
* bytes.
*
* \see pistream and postream
*/
explicit systembuf(handle_type h, std::size_t bufsize = 8192)
: handle_(h),
bufsize_(bufsize),
read_buf_(new char[bufsize]),
write_buf_(new char[bufsize])
{
#if defined(BOOST_POSIX_API)
BOOST_ASSERT(handle_ >= 0);
#elif defined(BOOST_WINDOWS_API)
BOOST_ASSERT(handle_ != INVALID_HANDLE_VALUE);
#endif
BOOST_ASSERT(bufsize_ > 0);
setp(write_buf_.get(), write_buf_.get() + bufsize_);
}
protected:
/**
* Reads new data from the native file handle.
*
* This operation is called by input methods when there is no more
* data in the input buffer. The function fills the buffer with new
* data, if available.
*
* \pre All input positions are exhausted (gptr() >= egptr()).
* \post The input buffer has new data, if available.
* \returns traits_type::eof() if a read error occurrs or there are
* no more data to be read. Otherwise returns
* traits_type::to_int_type(*gptr()).
*/
virtual int_type underflow()
{
BOOST_ASSERT(gptr() >= egptr());
bool ok;
#if defined(BOOST_POSIX_API)
ssize_t cnt = ::read(handle_, read_buf_.get(), bufsize_);
ok = (cnt != -1 && cnt != 0);
#elif defined(BOOST_WINDOWS_API)
DWORD cnt;
BOOL res = ::ReadFile(handle_, read_buf_.get(), bufsize_, &cnt, NULL);
ok = (res && cnt > 0);
#endif
if (!ok)
return traits_type::eof();
else
{
setg(read_buf_.get(), read_buf_.get(), read_buf_.get() + cnt);
return traits_type::to_int_type(*gptr());
}
}
/**
* Makes room in the write buffer for additional data.
*
* This operation is called by output methods when there is no more
* space in the output buffer to hold a new element. The function
* first flushes the buffer's contents to disk and then clears it to
* leave room for more characters. The given \a c character is
* stored at the beginning of the new space.
*
* \pre All output positions are exhausted (pptr() >= epptr()).
* \post The output buffer has more space if no errors occurred
* during the write to disk.
* \post *(pptr() - 1) is \a c.
* \returns traits_type::eof() if a write error occurrs. Otherwise
* returns traits_type::not_eof(c).
*/
virtual int_type overflow(int c)
{
BOOST_ASSERT(pptr() >= epptr());
if (sync() == -1)
return traits_type::eof();
if (!traits_type::eq_int_type(c, traits_type::eof()))
{
traits_type::assign(*pptr(), c);
pbump(1);
}
return traits_type::not_eof(c);
}
/**
* Flushes the output buffer to disk.
*
* Synchronizes the systembuf buffers with the contents of the file
* associated to this object through the native file handle. The
* output buffer is flushed to disk and cleared to leave new room
* for more data.
*
* \returns 0 on success, -1 if an error occurred.
*/
virtual int sync()
{
#if defined(BOOST_POSIX_API)
ssize_t cnt = pptr() - pbase();
#elif defined(BOOST_WINDOWS_API)
long cnt = pptr() - pbase();
#endif
bool ok;
#if defined(BOOST_POSIX_API)
ok = ::write(handle_, pbase(), cnt) == cnt;
#elif defined(BOOST_WINDOWS_API)
DWORD rcnt;
BOOL res = ::WriteFile(handle_, pbase(), cnt, &rcnt, NULL);
ok = (res && static_cast<long>(rcnt) == cnt);
#endif
if (ok)
pbump(-cnt);
return ok ? 0 : -1;
}
private:
/**
* Native file handle used by the systembuf object.
*/
handle_type handle_;
/**
* Internal buffer size used during read and write operations.
*/
std::size_t bufsize_;
/**
* Internal buffer used during read operations.
*/
boost::scoped_array<char> read_buf_;
/**
* Internal buffer used during write operations.
*/
boost::scoped_array<char> write_buf_;
};
}
}
}
#endif

355
boost/process/detail/win32_ops.hpp

@ -1,355 +0,0 @@
//
// Boost.Process
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
// Copyright (c) 2008, 2009 Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
/**
* \file boost/process/detail/win32_ops.hpp
*
* Provides some convenience functions to start processes under
* Windows-compatible operating systems.
*/
#ifndef BOOST_PROCESS_DETAIL_WIN32_OPS_HPP
#define BOOST_PROCESS_DETAIL_WIN32_OPS_HPP
#include <boost/process/environment.hpp>
#include <boost/process/detail/file_handle.hpp>
#include <boost/process/detail/pipe.hpp>
#include <boost/process/detail/stream_info.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/shared_array.hpp>
#include <boost/scoped_array.hpp>
#include <boost/assert.hpp>
#include <boost/system/system_error.hpp>
#include <boost/throw_exception.hpp>
#include <vector>
#include <string>
#include <cstddef>
#include <string.h>
#include <windows.h>
namespace boost {
namespace process {
namespace detail {
/**
* Converts the command line to a plain string. Converts the command line's
* list of arguments to the format expected by the \a lpCommandLine parameter
* in the CreateProcess() system call.
*
* This operation is only available on Windows systems.
*
* \return A dynamically allocated string holding the command line
* to be passed to the executable. It is returned in a
* shared_array object to ensure its release at some point.
*/
template <class Arguments>
inline boost::shared_array<char> collection_to_win32_cmdline(const Arguments &args)
{
typedef std::vector<std::string> arguments_t;
arguments_t args2;
typename Arguments::size_type i = 0;
std::size_t size = 0;
for (typename Arguments::const_iterator it = args.begin(); it != args.end(); ++it)
{
std::string arg = *it;
std::string::size_type pos = 0;
while ( (pos = arg.find('"', pos)) != std::string::npos)
{
arg.replace(pos, 1, "\\\"");
pos += 2;
}
if (arg.find(' ') != std::string::npos)
arg = '\"' + arg + '\"';
if (i++ != args.size() - 1)
arg += ' ';
args2.push_back(arg);
size += arg.size() + 1;
}
boost::shared_array<char> cmdline(new char[size]);
cmdline.get()[0] = '\0';
for (arguments_t::size_type i = 0; i < args.size(); ++i)
#if defined(__CYGWIN__)
::strncat(cmdline.get(), args2[i].c_str(), args2[i].size());
#else
::strcat_s(cmdline.get(), size, args2[i].c_str());
#endif
return cmdline;
}
/**
* Converts an environment to a string used by CreateProcess().
*
* Converts the environment's contents to the format used by the
* CreateProcess() system call. The returned char* string is
* allocated in dynamic memory; the caller must free it when not
* used any more. This is enforced by the use of a shared pointer.
*
* \return A dynamically allocated char* string that represents
* the environment's content. This string is of the form
* var1=value1\\0var2=value2\\0\\0.
*/
inline boost::shared_array<char> environment_to_win32_strings(const environment &env)
{
boost::shared_array<char> envp;
if (env.empty())
{
envp.reset(new char[2]);
::ZeroMemory(envp.get(), 2);
}
else
{
std::string s;
for (environment::const_iterator it = env.begin(); it != env.end(); ++it)
{
s += it->first + "=" + it->second;
s.push_back(0);
}
envp.reset(new char[s.size() + 1]);
#if defined(__CYGWIN__)
::memcpy(envp.get(), s.c_str(), s.size() + 1);
#else
::memcpy_s(envp.get(), s.size() + 1, s.c_str(), s.size() + 1);
#endif
}
return envp;
}
/**
* Helper class to configure a Win32 %child.
*
* This helper class is used to hold all the attributes that configure a
* new Win32 %child process.
*
* All its fields are public for simplicity. It is only intended for
* internal use and it is heavily coupled with the Context
* implementations.
*/
struct win32_setup
{
/**
* The work directory.
*
* This string specifies the directory in which the %child process
* starts execution. It cannot be empty.
*/
std::string work_directory;
/**
* The process startup properties.
*
* This Win32-specific object holds a list of properties that describe
* how the new process should be started. The \a STARTF_USESTDHANDLES
* flag should not be set in it because it is automatically configured
* by win32_start().
*/
STARTUPINFOA *startupinfo;
};
/**
* Starts a new child process in a Win32 operating system.
*
* This helper functions is provided to simplify the Context's task when
* it comes to starting up a new process in a Win32 operating system.
*
* \param exe The executable to spawn the child process.
* \param args The arguments for the executable.
* \param env The environment variables that the new child process
* receives.
* \param infoin Information that describes stdin's behavior.
* \param infoout Information that describes stdout's behavior.
* \param infoerr Information that describes stderr's behavior.
* \param setup A helper object holding extra child information.
* \return The new process' information as returned by the CreateProcess()
* system call. The caller is responsible of creating an
* appropriate Child representation for it.
* \pre \a setup.startupinfo_ cannot have the \a STARTF_USESTDHANDLES set
* in the \a dwFlags field.
*/
template <class Executable, class Arguments>
inline PROCESS_INFORMATION win32_start(const Executable &exe, const Arguments &args, const environment &env, stream_info &infoin, stream_info &infoout, stream_info &infoerr, const win32_setup &setup)
{
file_handle chin, chout, cherr;
BOOST_ASSERT(setup.startupinfo->cb >= sizeof(STARTUPINFOA));
BOOST_ASSERT(!(setup.startupinfo->dwFlags & STARTF_USESTDHANDLES));
boost::scoped_ptr<STARTUPINFOA> si(new STARTUPINFOA);
::CopyMemory(si.get(), setup.startupinfo, sizeof(*setup.startupinfo));
si->dwFlags |= STARTF_USESTDHANDLES;
switch (infoin.type_)
{
case stream_info::close:
{
break;
}
case stream_info::inherit:
{
chin = file_handle::win32_std(STD_INPUT_HANDLE, true);
break;
}
case stream_info::use_file:
{
HANDLE h = ::CreateFileA(infoin.file_.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (h == INVALID_HANDLE_VALUE)
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::win32_start: CreateFile failed"));
chin = file_handle(h);
break;
}
case stream_info::use_handle:
{
chin = infoin.handle_;
chin.win32_set_inheritable(true);
break;
}
case stream_info::use_pipe:
{
infoin.pipe_->rend().win32_set_inheritable(true);
chin = infoin.pipe_->rend();
break;
}
default:
{
BOOST_ASSERT(false);
break;
}
}
si->hStdInput = chin.valid() ? chin.get() : INVALID_HANDLE_VALUE;
switch (infoout.type_)
{
case stream_info::close:
{
break;
}
case stream_info::inherit:
{
chout = file_handle::win32_std(STD_OUTPUT_HANDLE, true);
break;
}
case stream_info::use_file:
{
HANDLE h = ::CreateFileA(infoout.file_.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (h == INVALID_HANDLE_VALUE)
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::win32_start: CreateFile failed"));
chout = file_handle(h);
break;
}
case stream_info::use_handle:
{
chout = infoout.handle_;
chout.win32_set_inheritable(true);
break;
}
case stream_info::use_pipe:
{
infoout.pipe_->wend().win32_set_inheritable(true);
chout = infoout.pipe_->wend();
break;
}
default:
{
BOOST_ASSERT(false);
break;
}
}
si->hStdOutput = chout.valid() ? chout.get() : INVALID_HANDLE_VALUE;
switch (infoerr.type_)
{
case stream_info::close:
{
break;
}
case stream_info::inherit:
{
cherr = file_handle::win32_std(STD_ERROR_HANDLE, true);
break;
}
case stream_info::redirect:
{
BOOST_ASSERT(infoerr.desc_to_ == 1);
BOOST_ASSERT(chout.valid());
cherr = file_handle::win32_dup(chout.get(), true);
break;
}
case stream_info::use_file:
{
HANDLE h = ::CreateFileA(infoerr.file_.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (h == INVALID_HANDLE_VALUE)
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::win32_start: CreateFile failed"));
cherr = file_handle(h);
break;
}
case stream_info::use_handle:
{
cherr = infoerr.handle_;
cherr.win32_set_inheritable(true);
break;
}
case stream_info::use_pipe:
{
infoerr.pipe_->wend().win32_set_inheritable(true);
cherr = infoerr.pipe_->wend();
break;
}
default:
{
BOOST_ASSERT(false);
break;
}
}
si->hStdError = cherr.valid() ? cherr.get() : INVALID_HANDLE_VALUE;
PROCESS_INFORMATION pi;
::ZeroMemory(&pi, sizeof(pi));
boost::shared_array<char> cmdline = collection_to_win32_cmdline(args);
boost::scoped_array<char> executable(new char[exe.size() + 1]);
#if defined(__CYGWIN__)
::strcpy(executable.get(), exe.c_str());
#else
::strcpy_s(executable.get(), exe.size() + 1, exe.c_str());
#endif
boost::scoped_array<char> workdir(new char[setup.work_directory.size() + 1]);
#if defined(__CYGWIN__)
::strcpy(workdir.get(), setup.work_directory.c_str());
#else
::strcpy_s(workdir.get(), setup.work_directory.size() + 1, setup.work_directory.c_str());
#endif
boost::shared_array<char> envstrs = environment_to_win32_strings(env);
if (!::CreateProcessA(executable.get()[0] ? executable.get() : NULL, cmdline.get(), NULL, NULL, TRUE, CREATE_NO_WINDOW, envstrs.get(), workdir.get(), si.get(), &pi))
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::win32_start: CreateProcess failed"));
return pi;
}
}
}
}
#endif

50
boost/process/environment.hpp

@ -1,50 +0,0 @@
//
// Boost.Process
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
// Copyright (c) 2008, 2009 Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
/**
* \file boost/process/environment.hpp
*
* Includes the declaration of the environment class.
*/
#ifndef BOOST_PROCESS_ENVIRONMENT_HPP
#define BOOST_PROCESS_ENVIRONMENT_HPP
#include <string>
#include <map>
namespace boost {
namespace process {
/**
* Representation of a process' environment variables.
*
* The environment is a map that stablishes an unidirectional
* association between variable names and their values and is
* represented by a string to string map.
*
* Variables may be defined to the empty string. Be aware that doing so
* is not portable: POSIX systems will treat such variables as being
* defined to the empty value, but Windows systems are not able to
* distinguish them from undefined variables.
*
* Neither POSIX nor Windows systems support a variable with no name.
*
* It is worthy to note that the environment is sorted alphabetically.
* This is provided for-free by the map container used to implement this
* type, and this behavior is required by Windows systems.
*/
typedef std::map<std::string, std::string> environment;
}
}
#endif

583
boost/process/operations.hpp

@ -1,583 +0,0 @@
//
// Boost.Process
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
// Copyright (c) 2008, 2009 Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
/**
* \file boost/process/operations.hpp
*
* Provides miscellaneous free functions.
*/
#ifndef BOOST_PROCESS_OPERATIONS_HPP
#define BOOST_PROCESS_OPERATIONS_HPP
#include <boost/process/config.hpp>
#if defined(BOOST_POSIX_API)
# include <boost/process/detail/posix_ops.hpp>
# include <stdlib.h>
# include <unistd.h>
# if defined(__CYGWIN__)
# include <boost/scoped_array.hpp>
# include <sys/cygwin.h>
# endif
#elif defined(BOOST_WINDOWS_API)
# include <boost/process/detail/win32_ops.hpp>
# include <boost/algorithm/string/predicate.hpp>
# include <windows.h>
#else
# error "Unsupported platform."
#endif
#include <boost/process/child.hpp>
#include <boost/process/stream_behavior.hpp>
#include <boost/process/status.hpp>
#include <boost/process/detail/file_handle.hpp>
#include <boost/process/detail/pipe.hpp>
#include <boost/process/detail/stream_info.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/system/system_error.hpp>
#include <boost/throw_exception.hpp>
#include <boost/scoped_array.hpp>
#include <boost/assert.hpp>
#include <string>
#include <vector>
#include <stdexcept>
#include <cstddef>
namespace boost {
namespace process {
/**
* Locates the executable program \a file in all the directory components
* specified in \a path. If \a path is empty, the value of the PATH
* environment variable is used.
*
* The path variable is interpreted following the same conventions used
* to parse the PATH environment variable in the underlying platform.
*
* \throw boost::filesystem::filesystem_error If the file cannot be found
* in the path.
*/
inline std::string find_executable_in_path(const std::string &file, std::string path = "")
{
#if defined(BOOST_POSIX_API)
BOOST_ASSERT(file.find('/') == std::string::npos);
#elif defined(BOOST_WINDOWS_API)
BOOST_ASSERT(file.find_first_of("\\/") == std::string::npos);
#endif
std::string result;
#if defined(BOOST_POSIX_API)
if (path.empty())
{
const char *envpath = ::getenv("PATH");
// if (!envpath)
// boost::throw_exception(boost::filesystem::filesystem_error("boost::process::find_executable_in_path: retrieving PATH failed", file, boost::system::errc::make_error_code(boost::system::errc::no_such_file_or_directory)));
path = envpath;
}
BOOST_ASSERT(!path.empty());
#if defined(__CYGWIN__)
if (!::cygwin_posix_path_list_p(path.c_str()))
{
int size = ::cygwin_win32_to_posix_path_list_buf_size(path.c_str());
boost::scoped_array<char> cygpath(new char[size]);
::cygwin_win32_to_posix_path_list(path.c_str(), cygpath.get());
path = cygpath.get();
}
#endif
std::string::size_type pos1 = 0, pos2;
do
{
pos2 = path.find(':', pos1);
std::string dir = (pos2 != std::string::npos) ? path.substr(pos1, pos2 - pos1) : path.substr(pos1);
std::string f = dir + (boost::algorithm::ends_with(dir, "/") ? "" : "/") + file;
if (!::access(f.c_str(), X_OK))
result = f;
pos1 = pos2 + 1;
} while (pos2 != std::string::npos && result.empty());
#elif defined(BOOST_WINDOWS_API)
const char *exts[] = { "", ".exe", ".com", ".bat", NULL };
const char **ext = exts;
while (*ext)
{
char buf[MAX_PATH];
char *dummy;
DWORD size = ::SearchPathA(path.empty() ? NULL : path.c_str(), file.c_str(), *ext, MAX_PATH, buf, &dummy);
BOOST_ASSERT(size < MAX_PATH);
if (size > 0)
{
result = buf;
break;
}
++ext;
}
#endif
// if (result.empty())
// boost::throw_exception(boost::filesystem::filesystem_error("boost::process::find_executable_in_path: file not found", file, boost::system::errc::make_error_code(boost::system::errc::no_such_file_or_directory)));
return result;
}
/**
* Extracts the program name from a given executable.
*
* \return The program name. On Windows the program name
* is returned without a file extension.
*/
inline std::string executable_to_progname(const std::string &exe)
{
std::string::size_type begin = 0;
std::string::size_type end = std::string::npos;
#if defined(BOOST_POSIX_API)
std::string::size_type slash = exe.rfind('/');
#elif defined(BOOST_WINDOWS_API)
std::string::size_type slash = exe.find_last_of("/\\");
#endif
if (slash != std::string::npos)
begin = slash + 1;
#if defined(BOOST_WINDOWS_API)
if (exe.size() > 4 &&
(boost::algorithm::iends_with(exe, ".exe") || boost::algorithm::iends_with(exe, ".com") || boost::algorithm::iends_with(exe, ".bat")))
end = exe.size() - 4;
#endif
return exe.substr(begin, end - begin);
}
/**
* Starts a new child process.
*
* Launches a new process based on the binary image specified by the
* executable, the set of arguments to be passed to it and several
* parameters that describe the execution context.
*
* \remark Blocking remarks: This function may block if the device
* holding the executable blocks when loading the image. This might
* happen if, e.g., the binary is being loaded from a network share.
*
* \return A handle to the new child process.
*/
template <class Executable, class Arguments, class Context>
inline child launch(const Executable &exe, const Arguments &args, const Context &ctx)
{
detail::file_handle fhstdin, fhstdout, fhstderr;
BOOST_ASSERT(!args.empty());
BOOST_ASSERT(!ctx.work_directory.empty());
#if defined(BOOST_POSIX_API)
detail::info_map infoin, infoout;
if (ctx.stdin_behavior.get_type() != stream_behavior::close)
{
detail::stream_info si = detail::stream_info(ctx.stdin_behavior, false);
infoin.insert(detail::info_map::value_type(STDIN_FILENO, si));
}
if (ctx.stdout_behavior.get_type() != stream_behavior::close)
{
detail::stream_info si = detail::stream_info(ctx.stdout_behavior, true);
infoout.insert(detail::info_map::value_type(STDOUT_FILENO, si));
}
if (ctx.stderr_behavior.get_type() != stream_behavior::close)
{
detail::stream_info si = detail::stream_info(ctx.stderr_behavior, true);
infoout.insert(detail::info_map::value_type(STDERR_FILENO, si));
}
detail::posix_setup s;
s.work_directory = ctx.work_directory;
child::id_type pid = detail::posix_start(exe, args, ctx.environment, infoin, infoout, s);
if (ctx.stdin_behavior.get_type() == stream_behavior::capture)
{
fhstdin = detail::posix_info_locate_pipe(infoin, STDIN_FILENO, false);
BOOST_ASSERT(fhstdin.valid());
}
if (ctx.stdout_behavior.get_type() == stream_behavior::capture)
{
fhstdout = detail::posix_info_locate_pipe(infoout, STDOUT_FILENO, true);
BOOST_ASSERT(fhstdout.valid());
}
if (ctx.stderr_behavior.get_type() == stream_behavior::capture)
{
fhstderr = detail::posix_info_locate_pipe(infoout, STDERR_FILENO, true);
BOOST_ASSERT(fhstderr.valid());
}
return child(pid, fhstdin, fhstdout, fhstderr);
#elif defined(BOOST_WINDOWS_API)
detail::stream_info behin = detail::stream_info(ctx.stdin_behavior, false);
if (behin.type_ == detail::stream_info::use_pipe)
fhstdin = behin.pipe_->wend();
detail::stream_info behout = detail::stream_info(ctx.stdout_behavior, true);
if (behout.type_ == detail::stream_info::use_pipe)
fhstdout = behout.pipe_->rend();
detail::stream_info beherr = detail::stream_info(ctx.stderr_behavior, true);
if (beherr.type_ == detail::stream_info::use_pipe)
fhstderr = beherr.pipe_->rend();
STARTUPINFOA si;
::ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
detail::win32_setup s;
s.work_directory = ctx.work_directory;
s.startupinfo = &si;
PROCESS_INFORMATION pi = detail::win32_start(exe, args, ctx.environment, behin, behout, beherr, s);
if (!::CloseHandle(pi.hThread))
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::launch: CloseHandle failed"));
return child(pi.dwProcessId, fhstdin, fhstdout, fhstderr, detail::file_handle(pi.hProcess));
#endif
}
/**
* Launches a shell-based command.
*
* Executes the given command through the default system shell. The
* command is subject to pattern expansion, redirection and pipelining.
* The shell is launched as described by the parameters in the execution
* context.
*
* This function behaves similarly to the system(3) system call. In a
* POSIX system, the command is fed to /bin/sh whereas under a Windows
* system, it is fed to cmd.exe. It is difficult to write portable
* commands as the first parameter, but this function comes in handy in
* multiple situations.
*/
template <class Context>
inline child launch_shell(const std::string &command, const Context &ctx)
{
std::string exe;
std::vector<std::string> args;
#if defined(BOOST_POSIX_API)
exe = "/bin/sh";
args.push_back("sh");
args.push_back("-c");
args.push_back(command);
#elif defined(BOOST_WINDOWS_API)
char sysdir[MAX_PATH];
UINT size = ::GetSystemDirectoryA(sysdir, sizeof(sysdir));
if (!size)
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::launch_shell: GetWindowsDirectory failed"));
BOOST_ASSERT(size < MAX_PATH);
exe = std::string(sysdir) + (sysdir[size - 1] != '\\' ? "\\cmd.exe" : "cmd.exe");
args.push_back("cmd");
args.push_back("/c");
args.push_back(command);
#endif
return launch(exe, args, ctx);
}
/**
* Launches a pipelined set of child processes.
*
* Given a collection of pipeline_entry objects describing how to launch
* a set of child processes, spawns them all and connects their inputs and
* outputs in a way that permits pipelined communication.
*
* \pre Let 1..N be the processes in the collection: the input behavior of
* the 2..N processes must be set to close_stream().
* \pre Let 1..N be the processes in the collection: the output behavior of
* the 1..N-1 processes must be set to close_stream().
* \remark Blocking remarks: This function may block if the device holding
* the executable of one of the entries blocks when loading the
* image. This might happen if, e.g., the binary is being loaded
* from a network share.
* \return A set of Child objects that represent all the processes spawned
* by this call. You should use wait_children() to wait for their
* termination.
*/
template <class Entries>
inline children launch_pipeline(const Entries &entries)
{
BOOST_ASSERT(entries.size() >= 2);
children cs;
detail::file_handle fhinvalid;
boost::scoped_array<detail::pipe> pipes(new detail::pipe[entries.size() - 1]);
#if defined(BOOST_POSIX_API)
{
typename Entries::size_type i = 0;
const typename Entries::value_type::context_type &ctx = entries[i].context;
detail::info_map infoin, infoout;
if (ctx.stdin_behavior.get_type() != stream_behavior::close)
{
detail::stream_info si = detail::stream_info(ctx.stdin_behavior, false);
infoin.insert(detail::info_map::value_type(STDIN_FILENO, si));
}
BOOST_ASSERT(ctx.stdout_behavior.get_type() == stream_behavior::close);
detail::stream_info si2(close_stream(), true);
si2.type_ = detail::stream_info::use_handle;
si2.handle_ = pipes[i].wend().release();
infoout.insert(detail::info_map::value_type(STDOUT_FILENO, si2));
if (ctx.stderr_behavior.get_type() != stream_behavior::close)
{
detail::stream_info si = detail::stream_info(ctx.stderr_behavior, true);
infoout.insert(detail::info_map::value_type(STDERR_FILENO, si));
}
detail::posix_setup s;
s.work_directory = ctx.work_directory;
pid_t pid = detail::posix_start(entries[i].executable, entries[i].arguments, ctx.environment, infoin, infoout, s);
detail::file_handle fhstdin;
if (ctx.stdin_behavior.get_type() == stream_behavior::capture)
{
fhstdin = detail::posix_info_locate_pipe(infoin, STDIN_FILENO, false);
BOOST_ASSERT(fhstdin.valid());
}
cs.push_back(child(pid, fhstdin, fhinvalid, fhinvalid));
}
for (typename Entries::size_type i = 1; i < entries.size() - 1; ++i)
{
const typename Entries::value_type::context_type &ctx = entries[i].context;
detail::info_map infoin, infoout;
BOOST_ASSERT(ctx.stdin_behavior.get_type() == stream_behavior::close);
detail::stream_info si1(close_stream(), false);
si1.type_ = detail::stream_info::use_handle;
si1.handle_ = pipes[i - 1].rend().release();
infoin.insert(detail::info_map::value_type(STDIN_FILENO, si1));
BOOST_ASSERT(ctx.stdout_behavior.get_type() == stream_behavior::close);
detail::stream_info si2(close_stream(), true);
si2.type_ = detail::stream_info::use_handle;
si2.handle_ = pipes[i].wend().release();
infoout.insert(detail::info_map::value_type(STDOUT_FILENO, si2));
if (ctx.stderr_behavior.get_type() != stream_behavior::close)
{
detail::stream_info si = detail::stream_info(ctx.stderr_behavior, true);
infoout.insert(detail::info_map::value_type(STDERR_FILENO, si));
}
detail::posix_setup s;
s.work_directory = ctx.work_directory;
pid_t pid = detail::posix_start(entries[i].executable, entries[i].arguments, ctx.environment, infoin, infoout, s);
cs.push_back(child(pid, fhinvalid, fhinvalid, fhinvalid));
}
{
typename Entries::size_type i = entries.size() - 1;
const typename Entries::value_type::context_type &ctx = entries[i].context;
detail::info_map infoin, infoout;
BOOST_ASSERT(ctx.stdin_behavior.get_type() == stream_behavior::close);
detail::stream_info si1(close_stream(), false);
si1.type_ = detail::stream_info::use_handle;
si1.handle_ = pipes[i - 1].rend().release();
infoin.insert(detail::info_map::value_type(STDIN_FILENO, si1));
if (ctx.stdout_behavior.get_type() != stream_behavior::close)
{
detail::stream_info si = detail::stream_info(ctx.stdout_behavior, true);
infoout.insert(detail::info_map::value_type(STDOUT_FILENO, si));
}
if (ctx.stderr_behavior.get_type() != stream_behavior::close)
{
detail::stream_info si = detail::stream_info(ctx.stderr_behavior, true);
infoout.insert(detail::info_map::value_type(STDERR_FILENO, si));
}
detail::posix_setup s;
s.work_directory = ctx.work_directory;
pid_t pid = detail::posix_start(entries[i].executable, entries[i].arguments, ctx.environment, infoin, infoout, s);
detail::file_handle fhstdout, fhstderr;
if (ctx.stdout_behavior.get_type() == stream_behavior::capture)
{
fhstdout = detail::posix_info_locate_pipe(infoout, STDOUT_FILENO, true);
BOOST_ASSERT(fhstdout.valid());
}
if (ctx.stderr_behavior.get_type() == stream_behavior::capture)
{
fhstderr = detail::posix_info_locate_pipe(infoout, STDERR_FILENO, true);
BOOST_ASSERT(fhstderr.valid());
}
cs.push_back(child(pid, fhinvalid, fhstdout, fhstderr));
}
#elif defined(BOOST_WINDOWS_API)
STARTUPINFOA si;
detail::win32_setup s;
s.startupinfo = &si;
{
typename Entries::size_type i = 0;
const typename Entries::value_type::context_type &ctx = entries[i].context;
detail::stream_info sii = detail::stream_info(ctx.stdin_behavior, false);
detail::file_handle fhstdin;
if (sii.type_ == detail::stream_info::use_pipe)
fhstdin = sii.pipe_->wend();
BOOST_ASSERT(ctx.stdout_behavior.get_type() == stream_behavior::close);
detail::stream_info sio(close_stream(), true);
sio.type_ = detail::stream_info::use_handle;
sio.handle_ = pipes[i].wend().release();
detail::stream_info sie(ctx.stderr_behavior, true);
s.work_directory = ctx.work_directory;
::ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
PROCESS_INFORMATION pi = detail::win32_start(entries[i].executable, entries[i].arguments, ctx.environment, sii, sio, sie, s);
if (!::CloseHandle(pi.hThread))
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::launch_pipeline: CloseHandle failed"));
cs.push_back(child(pi.dwProcessId, fhstdin, fhinvalid, fhinvalid, detail::file_handle(pi.hProcess)));
}
for (typename Entries::size_type i = 1; i < entries.size() - 1; ++i)
{
const typename Entries::value_type::context_type &ctx = entries[i].context;
BOOST_ASSERT(ctx.stdin_behavior.get_type() == stream_behavior::close);
detail::stream_info sii(close_stream(), false);
sii.type_ = detail::stream_info::use_handle;
sii.handle_ = pipes[i - 1].rend().release();
detail::stream_info sio(close_stream(), true);
sio.type_ = detail::stream_info::use_handle;
sio.handle_ = pipes[i].wend().release();
detail::stream_info sie(ctx.stderr_behavior, true);
s.work_directory = ctx.work_directory;
::ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
PROCESS_INFORMATION pi = detail::win32_start(entries[i].executable, entries[i].arguments, ctx.environment, sii, sio, sie, s);
if (!::CloseHandle(pi.hThread))
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::launch_pipeline: CloseHandle failed"));
cs.push_back(child(pi.dwProcessId, fhinvalid, fhinvalid, fhinvalid, detail::file_handle(pi.hProcess)));
}
{
typename Entries::size_type i = entries.size() - 1;
const typename Entries::value_type::context_type &ctx = entries[i].context;
BOOST_ASSERT(ctx.stdin_behavior.get_type() == stream_behavior::close);
detail::stream_info sii(close_stream(), false);
sii.type_ = detail::stream_info::use_handle;
sii.handle_ = pipes[i - 1].rend().release();
detail::file_handle fhstdout, fhstderr;
detail::stream_info sio(ctx.stdout_behavior, true);
if (sio.type_ == detail::stream_info::use_pipe)
fhstdout = sio.pipe_->rend();
detail::stream_info sie(ctx.stderr_behavior, true);
if (sie.type_ == detail::stream_info::use_pipe)
fhstderr = sie.pipe_->rend();
s.work_directory = ctx.work_directory;
::ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
PROCESS_INFORMATION pi = detail::win32_start(entries[i].executable, entries[i].arguments, ctx.environment, sii, sio, sie, s);
if (!::CloseHandle(pi.hThread))
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::launch_pipeline: CloseHandle failed"));
cs.push_back(child(pi.dwProcessId, fhinvalid, fhstdout, fhstderr, detail::file_handle(pi.hProcess)));
}
#endif
return cs;
}
/**
* Waits for a collection of children to terminate.
*
* Given a collection of Child objects (such as std::vector<child> or
* the convenience children type), waits for the termination of all of
* them.
*
* \remark Blocking remarks: This call blocks if any of the children
* processes in the collection has not finalized execution and
* waits until it terminates.
*
* \return The exit status of the first process that returns an error
* code or, if all of them executed correctly, the exit status
* of the last process in the collection.
*/
template <class Children>
inline status wait_children(Children &cs)
{
BOOST_ASSERT(cs.size() >= 2);
typename Children::iterator it = cs.begin();
while (it != cs.end())
{
const status s = it->wait();
++it;
if (it == cs.end())
return s;
else if (!s.exited() || s.exit_status() != EXIT_SUCCESS)
{
while (it != cs.end())
{
it->wait();
++it;
}
return s;
}
}
BOOST_ASSERT(false);
return cs.begin()->wait();
}
}
}
#endif

116
boost/process/pistream.hpp

@ -1,116 +0,0 @@
//
// Boost.Process
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
// Copyright (c) 2008, 2009 Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
/**
* \file boost/process/pistream.hpp
*
* Includes the declaration of the pistream class.
*/
#ifndef BOOST_PROCESS_PISTREAM_HPP
#define BOOST_PROCESS_PISTREAM_HPP
#include <boost/process/detail/file_handle.hpp>
#include <boost/process/detail/systembuf.hpp>
#include <boost/noncopyable.hpp>
#include <istream>
namespace boost {
namespace process {
/**
* Child process' output stream.
*
* The pistream class represents an output communication channel with the
* child process. The child process writes data to this stream and the
* parent process can read it through the pistream object. In other
* words, from the child's point of view, the communication channel is an
* output one, but from the parent's point of view it is an input one;
* hence the confusing pistream name.
*
* pistream objects cannot be copied because they own the file handle
* they use to communicate with the child and because they buffer data
* that flows through the communication channel.
*
* A pistream object behaves as a std::istream stream in all senses.
* The class is only provided because it must provide a method to let
* the caller explicitly close the communication channel.
*
* \remark Blocking remarks: Functions that read data from this
* stream can block if the associated file handle blocks during
* the read. As this class is used to communicate with child
* processes through anonymous pipes, the most typical blocking
* condition happens when the child has no more data to send to
* the pipe's system buffer. When this happens, the buffer
* eventually empties and the system blocks until the writer
* generates some data.
*/
class pistream : public std::istream, public boost::noncopyable
{
public:
/**
* Creates a new process' output stream.
*
* Given a file handle, this constructor creates a new pistream
* object that owns the given file handle \a fh. Ownership of
* \a fh is transferred to the created pistream object.
*
* \pre \a fh is valid.
* \post \a fh is invalid.
* \post The new pistream object owns \a fh.
*/
explicit pistream(detail::file_handle &fh)
: std::istream(0),
handle_(fh),
systembuf_(handle_.get())
{
rdbuf(&systembuf_);
}
/**
* Returns the file handle managed by this stream.
*
* The file handle must not be copied. Copying invalidates
* the source file handle making the pistream unusable.
*/
detail::file_handle &handle()
{
return handle_;
}
/**
* Closes the file handle managed by this stream.
*
* Explicitly closes the file handle managed by this stream. This
* function can be used by the user to tell the child process it's
* not willing to receive more data.
*/
void close()
{
handle_.close();
}
private:
/**
* The file handle managed by this stream.
*/
detail::file_handle handle_;
/**
* The systembuf object used to manage this stream's data.
*/
detail::systembuf systembuf_;
};
}
}
#endif

178
boost/process/posix_child.hpp

@ -1,178 +0,0 @@
//
// Boost.Process
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
// Copyright (c) 2008, 2009 Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
/**
* \file boost/process/posix_child.hpp
*
* Includes the declaration of the posix_child class.
*/
#ifndef BOOST_PROCESS_POSIX_CHILD_HPP
#define BOOST_PROCESS_POSIX_CHILD_HPP
#include <boost/process/child.hpp>
#include <boost/process/pistream.hpp>
#include <boost/process/postream.hpp>
#include <boost/process/detail/pipe.hpp>
#include <boost/process/detail/posix_ops.hpp>
#include <boost/process/detail/stream_info.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/assert.hpp>
#include <map>
#include <unistd.h>
namespace boost {
namespace process {
/**
* POSIX implementation of the Child concept.
*
* The posix_child class implements the Child concept in a POSIX
* operating system.
*
* A POSIX child differs from a regular child (represented by a
* child object) in that it supports more than three communication
* channels with its parent. These channels are identified by regular
* file descriptors (integers).
*
* This class is built on top of the generic child so as to allow its
* trivial adoption. When a program is changed to use the POSIX-specific
* context (posix_context), it will most certainly need to migrate its
* use of the child class to posix_child. Doing so is only a matter of
* redefining the appropriate object and later using the required extra
* features: there should be no need to modify the existing code (e.g.
* method calls) in any other way.
*/
class posix_child : public child
{
public:
/**
* Gets a reference to the child's input stream \a desc.
*
* Returns a reference to a postream object that represents one of
* the multiple input communication channels with the child process.
* The channel is identified by \a desc as seen from the child's
* point of view. The parent can use the returned stream to send
* data to the child.
*
* Giving this function the STDIN_FILENO constant (defined in
* unistd.h) is a synonym for the get_stdin() call inherited from
* child.
*/
postream &get_input(int desc) const
{
if (desc == STDIN_FILENO)
return posix_child::get_stdin();
else
{
input_map_t::const_iterator it = input_map_.find(desc);
BOOST_ASSERT(it != input_map_.end());
return *it->second;
}
}
/**
* Gets a reference to the child's output stream \a desc.
*
* Returns a reference to a pistream object that represents one of
* the multiple output communication channels with the child process.
* The channel is identified by \a desc as seen from the child's
* point of view. The parent can use the returned stream to retrieve
* data from the child.
*
* Giving this function the STDOUT_FILENO or STDERR_FILENO constants
* (both defined in unistd.h) are synonyms for the get_stdout() and
* get_stderr() calls inherited from child, respectively.
*/
pistream &get_output(int desc) const
{
if (desc == STDOUT_FILENO)
return posix_child::get_stdout();
else if (desc == STDERR_FILENO)
return posix_child::get_stderr();
else
{
output_map_t::const_iterator it = output_map_.find(desc);
BOOST_ASSERT(it != output_map_.end());
return *it->second;
}
}
/**
* Constructs a new POSIX child object representing a just
* spawned child process.
*
* Creates a new child object that represents the just spawned process
* \a id.
*
* The \a infoin and \a infoout maps contain the pipes used to handle
* the redirections of the child process; at the moment, no other
* stream_info types are supported. If the launcher was asked to
* redirect any of the three standard flows, their pipes must be
* present in these maps.
*/
posix_child(id_type id, detail::info_map &infoin, detail::info_map &infoout)
: child(id,
detail::posix_info_locate_pipe(infoin, STDIN_FILENO, false),
detail::posix_info_locate_pipe(infoout, STDOUT_FILENO, true),
detail::posix_info_locate_pipe(infoout, STDERR_FILENO, true))
{
for (detail::info_map::iterator it = infoin.begin(); it != infoin.end(); ++it)
{
detail::stream_info &si = it->second;
if (si.type_ == detail::stream_info::use_pipe)
{
BOOST_ASSERT(si.pipe_->wend().valid());
boost::shared_ptr<postream> st(new postream(si.pipe_->wend()));
input_map_.insert(input_map_t::value_type(it->first, st));
}
}
for (detail::info_map::iterator it = infoout.begin(); it != infoout.end(); ++it)
{
detail::stream_info &si = it->second;
if (si.type_ == detail::stream_info::use_pipe)
{
BOOST_ASSERT(si.pipe_->rend().valid());
boost::shared_ptr<pistream> st(new pistream(si.pipe_->rend()));
output_map_.insert(output_map_t::value_type(it->first, st));
}
}
}
private:
/**
* Maps child's file descriptors to postream objects.
*/
typedef std::map<int, boost::shared_ptr<postream> > input_map_t;
/**
* Contains all relationships between child's input file
* descriptors and their corresponding postream objects.
*/
input_map_t input_map_;
/**
* Maps child's file descriptors to pistream objects.
*/
typedef std::map<int, boost::shared_ptr<pistream> > output_map_t;
/**
* Contains all relationships between child's output file
* descriptors and their corresponding pistream objects.
*/
output_map_t output_map_;
};
}
}
#endif

118
boost/process/posix_context.hpp

@ -1,118 +0,0 @@
//
// Boost.Process
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
// Copyright (c) 2008, 2009 Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
/**
* \file boost/process/posix_context.hpp
*
* Includes the declaration of the posix_context class.
*/
#ifndef BOOST_PROCESS_POSIX_CONTEXT_HPP
#define BOOST_PROCESS_POSIX_CONTEXT_HPP
#include <boost/process/context.hpp>
#include <boost/process/stream_behavior.hpp>
#include <map>
#include <string>
#include <unistd.h>
namespace boost {
namespace process {
/**
* Holds a mapping between native file descriptors and their corresponding
* pipes to set up communication between the parent and the %child process.
*/
typedef std::map<int, stream_behavior> behavior_map;
template <class Path>
class posix_basic_context : public basic_work_directory_context<Path>, public environment_context
{
public:
/**
* Constructs a new POSIX-specific context.
*
* Constructs a new context. It is configured as follows:
* * All communcation channels with the child process are closed.
* * There are no channel mergings.
* * The initial work directory of the child processes is set to the
* current working directory.
* * The environment variables table is empty.
* * The credentials are the same as those of the current process.
*/
posix_basic_context()
: uid(::getuid()),
euid(::geteuid()),
gid(::getgid()),
egid(::getegid())
{
}
/**
* List of input streams that will be redirected.
*/
behavior_map input_behavior;
/**
* List of output streams that will be redirected.
*/
behavior_map output_behavior;
/**
* The user credentials.
*
* UID that specifies the user credentials to use to run the %child
* process. Defaults to the current UID.
*/
uid_t uid;
/**
* The effective user credentials.
*
* EUID that specifies the effective user credentials to use to run
* the %child process. Defaults to the current EUID.
*/
uid_t euid;
/**
* The group credentials.
*
* GID that specifies the group credentials to use to run the %child
* process. Defaults to the current GID.
*/
gid_t gid;
/**
* The effective group credentials.
*
* EGID that specifies the effective group credentials to use to run
* the %child process. Defaults to the current EGID.
*/
gid_t egid;
/**
* The chroot directory, if any.
*
* Specifies the directory in which the %child process is chrooted
* before execution. Empty if this feature is not desired.
*/
Path chroot;
};
/**
* Default instantiation of posix_basic_context.
*/
typedef posix_basic_context<std::string> posix_context;
}
}
#endif

81
boost/process/posix_operations.hpp

@ -1,81 +0,0 @@
//
// Boost.Process
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
// Copyright (c) 2008, 2009 Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
/**
* \file boost/process/posix_operations.hpp
*
* Provides miscellaneous free functions specific to POSIX operating
* systems.
*/
#ifndef BOOST_PROCESS_POSIX_OPERATIONS_HPP
#define BOOST_PROCESS_POSIX_OPERATIONS_HPP
#include <boost/process/posix_child.hpp>
#include <boost/process/posix_context.hpp>
#include <boost/process/stream_behavior.hpp>
#include <boost/process/detail/stream_info.hpp>
#include <boost/process/detail/posix_ops.hpp>
#include <sys/types.h>
namespace boost {
namespace process {
/**
* Starts a new child process.
*
* Given an executable and the set of arguments passed to it, starts
* a new process with all the parameters configured in the context.
* The context can be reused afterwards to launch other different
* processes.
*
* \return A handle to the new child process.
*/
template <class Executable, class Arguments, class Posix_Context>
inline posix_child posix_launch(const Executable &exe, const Arguments &args, const Posix_Context &ctx)
{
detail::info_map input_info;
for (behavior_map::const_iterator it = ctx.input_behavior.begin(); it != ctx.input_behavior.end(); ++it)
{
if (it->second.get_type() != stream_behavior::close)
{
detail::stream_info si = detail::stream_info(it->second, false);
input_info.insert(detail::info_map::value_type(it->first, si));
}
}
detail::info_map output_info;
for (behavior_map::const_iterator it = ctx.output_behavior.begin(); it != ctx.output_behavior.end(); ++it)
{
if (it->second.get_type() != stream_behavior::close)
{
detail::stream_info si = detail::stream_info(it->second, true);
output_info.insert(detail::info_map::value_type(it->first, si));
}
}
detail::posix_setup s;
s.work_directory = ctx.work_directory;
s.uid = ctx.uid;
s.euid = ctx.euid;
s.gid = ctx.gid;
s.egid = ctx.egid;
s.chroot = ctx.chroot;
pid_t pid = detail::posix_start(exe, args, ctx.environment, input_info, output_info, s);
return posix_child(pid, input_info, output_info);
}
}
}
#endif

128
boost/process/posix_status.hpp

@ -1,128 +0,0 @@
//
// Boost.Process
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
// Copyright (c) 2008, 2009 Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
/**
* \file boost/process/posix_status.hpp
*
* Includes the declaration of the posix_status class.
*/
#ifndef BOOST_PROCESS_POSIX_STATUS_HPP
#define BOOST_PROCESS_POSIX_STATUS_HPP
#include <boost/process/config.hpp>
#if defined(BOOST_POSIX_API)
# include <sys/wait.h>
#elif defined(BOOST_WINDOWS_API)
#else
# error "Unsupported platform."
#endif
#include <boost/process/status.hpp>
#include <boost/assert.hpp>
namespace boost {
namespace process {
/**
* Status returned by a finalized %child process on a POSIX system.
*
* This class represents the %status returned by a child process after it
* has terminated. It contains some methods not available in the status
* class that provide information only available in POSIX systems.
*/
class posix_status : public status
{
public:
/**
* Creates a posix_status object from an existing status object.
*
* Creates a new status object representing the exit status of a
* child process. The construction is done based on an existing
* status object which already contains all the available
* information: this class only provides controlled access to it.
*/
posix_status(const status &s)
: status(s)
{
}
/**
* Returns whether the process exited due to an external
* signal.
*/
bool signaled() const
{
return WIFSIGNALED(flags_);
}
/**
* If signaled, returns the terminating signal code.
*
* If the process was signaled, returns the terminating signal code.
*
* \pre signaled() is true.
*/
int term_signal() const
{
BOOST_ASSERT(signaled());
return WTERMSIG(flags_);
}
/**
* If signaled, returns whether the process dumped core.
*
* If the process was signaled, returns whether the process
* produced a core dump.
*
* \pre signaled() is true.
*/
bool dumped_core() const
{
BOOST_ASSERT(signaled());
#ifdef WCOREDUMP
return WCOREDUMP(flags_);
#else
return false;
#endif
}
/**
* Returns whether the process was stopped by an external
* signal.
*/
bool stopped() const
{
return WIFSTOPPED(flags_);
}
/**
* If stopped, returns the stop signal code.
*
* If the process was stopped, returns the stop signal code.
*
* \pre stopped() is true.
*/
int stop_signal() const
{
BOOST_ASSERT(stopped());
return WSTOPSIG(flags_);
}
};
}
}
#endif

117
boost/process/postream.hpp

@ -1,117 +0,0 @@
//
// Boost.Process
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
// Copyright (c) 2008, 2009 Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
/**
* \file boost/process/postream.hpp
*
* Includes the declaration of the postream class.
*/
#ifndef BOOST_PROCESS_POSTREAM_HPP
#define BOOST_PROCESS_POSTREAM_HPP
#include <boost/process/detail/file_handle.hpp>
#include <boost/process/detail/systembuf.hpp>
#include <boost/noncopyable.hpp>
#include <ostream>
namespace boost {
namespace process {
/**
* Child process' input stream.
*
* The postream class represents an input communication channel with the
* child process. The child process reads data from this stream and the
* parent process can write to it through the postream object. In other
* words, from the child's point of view, the communication channel is an
* input one, but from the parent's point of view it is an output one;
* hence the confusing postream name.
*
* postream objects cannot be copied because they own the file handle
* they use to communicate with the child and because they buffer data
* that flows through the communication channel.
*
* A postream object behaves as a std::ostream stream in all senses.
* The class is only provided because it must provide a method to let
* the caller explicitly close the communication channel.
*
* \remark Blocking remarks: Functions that write data to this
* stream can block if the associated file handle blocks during
* the write. As this class is used to communicate with child
* processes through anonymous pipes, the most typical blocking
* condition happens when the child is not processing the data
* in the pipe's system buffer. When this happens, the buffer
* eventually fills up and the system blocks until the reader
* consumes some data, leaving some new room.
*/
class postream : public std::ostream, public boost::noncopyable
{
public:
/**
* Creates a new process' input stream.
*
* Given a file handle, this constructor creates a new postream
* object that owns the given file handle \a fh. Ownership of
* \a fh is transferred to the created postream object.
*
* \pre \a fh is valid.
* \post \a fh is invalid.
* \post The new postream object owns \a fh.
*/
explicit postream(detail::file_handle &fh)
: std::ostream(0),
handle_(fh),
systembuf_(handle_.get())
{
rdbuf(&systembuf_);
}
/**
* Returns the file handle managed by this stream.
*
* The file handle must not be copied. Copying invalidates
* the source file handle making the postream unusable.
*/
detail::file_handle &handle()
{
return handle_;
}
/**
* Closes the file handle managed by this stream.
*
* Explicitly closes the file handle managed by this stream. This
* function can be used by the user to tell the child process there
* is no more data to send.
*/
void close()
{
systembuf_.sync();
handle_.close();
}
private:
/**
* The file handle managed by this stream.
*/
detail::file_handle handle_;
/**
* The systembuf object used to manage this stream's data.
*/
detail::systembuf systembuf_;
};
}
}
#endif

130
boost/process/process.hpp

@ -1,130 +0,0 @@
//
// Boost.Process
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
// Copyright (c) 2008, 2009 Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
/**
* \file boost/process/process.hpp
*
* Includes the declaration of the process class.
*/
#ifndef BOOST_PROCESS_PROCESS_HPP
#define BOOST_PROCESS_PROCESS_HPP
#include <boost/process/config.hpp>
#if defined(BOOST_POSIX_API)
# include <cerrno>
# include <signal.h>
#elif defined(BOOST_WINDOWS_API)
# include <cstdlib>
# include <windows.h>
#else
# error "Unsupported platform."
#endif
#include <boost/system/system_error.hpp>
#include <boost/throw_exception.hpp>
namespace boost {
namespace process {
/**
* Generic implementation of the Process concept.
*
* The process class implements the Process concept in an operating system
* agnostic way.
*/
class process
{
public:
#if defined(BOOST_PROCESS_DOXYGEN)
/**
* Opaque name for the native process' identifier type.
*
* Each operating system identifies processes using a specific type.
* The \a id_type type is used to transparently refer to a process
* regardless of the operating system in which this class is used.
*
* This type is guaranteed to be an integral type on all supported
* platforms.
*/
typedef NativeProcessId id_type;
#elif defined(BOOST_POSIX_API)
typedef pid_t id_type;
#elif defined(BOOST_WINDOWS_API)
typedef DWORD id_type;
#endif
/**
* Constructs a new process object.
*
* Creates a new process object that represents a running process
* within the system.
*/
process(id_type id)
: id_(id)
{
}
/**
* Returns the process' identifier.
*/
id_type get_id() const
{
return id_;
}
/**
* Terminates the process execution.
*
* Forces the termination of the process execution. Some platforms
* allow processes to ignore some external termination notifications
* or to capture them for a proper exit cleanup. You can set the
* \a force flag to true in them to force their termination regardless
* of any exit handler.
*
* After this call, accessing this object can be dangerous because the
* process identifier may have been reused by a different process. It
* might still be valid, though, if the process has refused to die.
*
* \throw boost::system::system_error If the system call used to
* terminate the process fails.
*/
void terminate(bool force = false) const
{
#if defined(BOOST_POSIX_API)
if (::kill(id_, force ? SIGKILL : SIGTERM) == -1)
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::process::terminate: kill(2) failed"));
#elif defined(BOOST_WINDOWS_API)
HANDLE h = ::OpenProcess(PROCESS_TERMINATE, FALSE, id_);
if (h == NULL)
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::process::terminate: OpenProcess failed"));
if (!::TerminateProcess(h, EXIT_FAILURE))
{
::CloseHandle(h);
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::process::terminate: TerminateProcess failed"));
}
if (!::CloseHandle(h))
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::process::terminate: CloseHandle failed"));
#endif
}
private:
/**
* The process' identifier.
*/
id_type id_;
};
}
}
#endif

134
boost/process/self.hpp

@ -1,134 +0,0 @@
//
// Boost.Process
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
// Copyright (c) 2008, 2009 Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
/**
* \file boost/process/self.hpp
*
* Includes the declaration of the self class.
*/
#ifndef BOOST_PROCESS_SELF_HPP
#define BOOST_PROCESS_SELF_HPP
#include <boost/process/config.hpp>
#if defined(BOOST_POSIX_API)
# include <unistd.h>
#elif defined(BOOST_WINDOWS_API)
# include <windows.h>
#else
# error "Unsupported platform."
#endif
#include <boost/process/process.hpp>
#include <boost/process/environment.hpp>
#include <boost/system/system_error.hpp>
#include <boost/throw_exception.hpp>
#include <boost/noncopyable.hpp>
#include <string>
#if defined(BOOST_POSIX_API)
extern "C"
{
extern char **environ;
}
#endif
namespace boost {
namespace process {
/**
* Generic implementation of the Process concept.
*
* The self singleton provides access to the current process.
*/
class self : public process, boost::noncopyable
{
public:
/**
* Returns the self instance representing the caller's process.
*/
static self &get_instance()
{
static self *instance = 0;
if (!instance)
instance = new self;
return *instance;
}
/**
* Returns the current environment.
*
* Returns the current process' environment variables. Modifying the
* returned object has no effect on the current environment.
*/
static environment get_environment()
{
environment e;
#if defined(BOOST_POSIX_API)
char **env = ::environ;
while (*env)
{
std::string s = *env;
std::string::size_type pos = s.find('=');
e.insert(boost::process::environment::value_type(s.substr(0, pos), s.substr(pos + 1)));
++env;
}
#elif defined(BOOST_WINDOWS_API)
#ifdef GetEnvironmentStrings
#undef GetEnvironmentStrings
#endif
char *environ = ::GetEnvironmentStrings();
if (!environ)
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::self::get_environment: GetEnvironmentStrings failed"));
try
{
char *env = environ;
while (*env)
{
std::string s = env;
std::string::size_type pos = s.find('=');
e.insert(boost::process::environment::value_type(s.substr(0, pos), s.substr(pos + 1)));
env += s.size() + 1;
}
}
catch (...)
{
::FreeEnvironmentStringsA(environ);
throw;
}
::FreeEnvironmentStringsA(environ);
#endif
return e;
}
private:
/**
* Constructs a new self object.
*
* Creates a new self object that represents the current process.
*/
self() :
#if defined(BOOST_POSIX_API)
process(::getpid())
#elif defined(BOOST_WINDOWS_API)
process(::GetCurrentProcessId())
#endif
{
}
};
}
}
#endif

105
boost/process/status.hpp

@ -1,105 +0,0 @@
//
// Boost.Process
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
// Copyright (c) 2008, 2009 Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
/**
* \file boost/process/status.hpp
*
* Includes the declaration of the status class.
*/
#ifndef BOOST_PROCESS_STATUS_HPP
#define BOOST_PROCESS_STATUS_HPP
#include <boost/process/config.hpp>
#if defined(BOOST_POSIX_API)
# include <sys/wait.h>
#elif defined(BOOST_WINDOWS_API)
#else
# error "Unsupported platform."
#endif
#include <boost/assert.hpp>
namespace boost {
namespace process {
class child;
/**
* Status returned by a finalized %child process.
*
* This class represents the %status returned by a child process after it
* has terminated. It only provides that information available under all
* supported platforms.
*
* \see posix_status
*/
class status
{
friend class child;
public:
/**
* Returns whether the process exited gracefully or not.
*/
bool exited() const
{
#if defined(BOOST_POSIX_API)
return WIFEXITED(flags_);
#elif defined(BOOST_WINDOWS_API)
return true;
#endif
}
/**
* If exited, returns the exit code.
*
* If the process exited, returns the exit code it returned.
*
* \pre exited() is true.
*/
int exit_status() const
{
BOOST_ASSERT(exited());
#if defined(BOOST_POSIX_API)
return WEXITSTATUS(flags_);
#elif defined(BOOST_WINDOWS_API)
return flags_;
#endif
}
protected:
/**
* Creates a status object based on exit information.
*
* Creates a new status object representing the exit status of a
* child process.
*
* \param flags In a POSIX system this parameter contains the
* flags returned by the ::waitpid() call. In a
* Windows system it contains the exit code only.
*/
status(int flags)
: flags_(flags)
{
}
/**
* OS-specific codification of exit status.
*/
int flags_;
};
}
}
#endif

234
boost/process/stream_behavior.hpp

@ -1,234 +0,0 @@
//
// Boost.Process
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
// Copyright (c) 2008, 2009 Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
/**
* \file boost/process/stream_behavior.hpp
*
* Includes the declaration of the stream_behavior class and associated
* free functions.
*/
#ifndef BOOST_PROCESS_STREAM_BEHAVIOR_HPP
#define BOOST_PROCESS_STREAM_BEHAVIOR_HPP
#include <boost/process/config.hpp>
namespace boost {
namespace process {
namespace detail {
struct stream_info;
}
/**
* Describes the possible states for a communication stream.
*/
class stream_behavior
{
public:
friend struct detail::stream_info;
friend stream_behavior capture_stream();
friend stream_behavior close_stream();
friend stream_behavior inherit_stream();
friend stream_behavior redirect_stream_to_stdout();
friend stream_behavior silence_stream();
#if defined(BOOST_POSIX_API) || defined(BOOST_PROCESS_DOXYGEN)
friend stream_behavior posix_redirect_stream(int to);
#endif
/**
* Describes the possible states for a communication stream.
*/
enum type
{
/**
* The child's stream is connected to the parent by using an
* anonymous pipe so that they can send and receive data to/from
* each other.
*/
capture,
/**
* The child's stream is closed upon startup so that it will not
* have any access to it.
*/
close,
/**
* The child's stream is connected to the same stream used by the
* parent. In other words, the corresponding parent's stream is
* inherited.
*/
inherit,
/**
* The child's stream is connected to child's standard output.
* This is typically used when configuring the standard error
* stream.
*/
redirect_to_stdout,
/**
* The child's stream is redirected to a null device so that its
* input is always zero or its output is lost, depending on
* whether the stream is an input or an output one. It is
* important to notice that this is different from close because
* the child is still able to write data. If we closed, e.g.
* stdout, the child might not work at all!
*/
silence,
#if defined(BOOST_POSIX_API) || defined(BOOST_PROCESS_DOXYGEN)
/**
* The child redirects the stream's output to the provided file
* descriptor. This is a generalization of the portable
* redirect_to_stdout behavior.
*/
posix_redirect
#endif
};
/**
* Constructs a new stream behavior of type close.
*
* The public constructor creates a new stream behavior that defaults
* to the close behavior. In general, you will want to use the
* available free functions to construct a stream behavior (including
* the close one).
*/
stream_behavior()
: type_(stream_behavior::close)
{
}
/**
* Returns this stream's behavior type.
*/
type get_type() const
{
return type_;
}
private:
/**
* Constructs a new stream behavior of type \a t.
*
* Constructs a new stream behavior of type \a t. It is the
* responsibility of the caller to fill in any other attributes
* required by the specified type, if any.
*/
stream_behavior(type t)
: type_(t)
{
}
/**
* This stream's behavior type.
*/
type type_;
#if defined(BOOST_POSIX_API) || defined(BOOST_PROCESS_DOXYGEN)
/**
* File descriptor the stream is redirected to.
*/
int desc_to_;
#endif
};
/**
* Creates a new stream_behavior of type stream_behavior::capture.
*
* Creates a new stream_behavior of type stream_behavior::capture,
* meaning that the child's stream is connected to the parent by using an
* anonymous pipe so that they can send and receive data to/from each
* other.
*/
inline stream_behavior capture_stream()
{
return stream_behavior(stream_behavior::capture);
}
/**
* Creates a new stream_behavior of type stream_behavior::close.
*
* Creates a new stream_behavior of type stream_behavior::close,
* meaning that the child's stream is closed upon startup so that it
* will not have any access to it.
*/
inline stream_behavior close_stream()
{
return stream_behavior(stream_behavior::close);
}
/**
* Creates a new stream_behavior of type stream_behavior::inherit.
*
* Creates a new stream_behavior of type stream_behavior::inherit,
* meaning that the child's stream is connected to the same stream used
* by the parent. In other words, the corresponding parent's stream is
* inherited.
*/
inline stream_behavior inherit_stream()
{
return stream_behavior(stream_behavior::inherit);
}
/**
* Creates a new stream_behavior of type
* stream_behavior::redirect_to_stdout.
*
* Creates a new stream_behavior of type
* stream_behavior::redirect_to_stdout, meaning that the child's stream is
* connected to child's standard output. This is typically used when
* configuring the standard error stream.
*/
inline stream_behavior redirect_stream_to_stdout()
{
return stream_behavior(stream_behavior::redirect_to_stdout);
}
/**
* Creates a new stream_behavior of type stream_behavior::silence.
*
* Creates a new stream_behavior of type stream_behavior::silence,
* meaning that the child's stream is redirected to a null device so that
* its input is always zero or its output is lost, depending on whether
* the stream is an input or an output one. It is important to notice
* that this is different from close because the child is still able to
* write data. If we closed, e.g. stdout, the child might not work at
* all!
*/
inline stream_behavior silence_stream()
{
return stream_behavior(stream_behavior::silence);
}
#if defined(BOOST_POSIX_API) || defined(BOOST_PROCESS_DOXYGEN)
/**
* Creates a new stream_behavior of type stream_behavior::posix_redirect.
*
* Creates a new stream_behavior of type stream_behavior::posix_redirect,
* meaning that the child's stream is redirected to the \a to child's
* file descriptor. This is a generalization of the portable
* redirect_stream_to_stdout() behavior.
*/
inline stream_behavior posix_redirect_stream(int to)
{
stream_behavior sb(stream_behavior::posix_redirect);
sb.desc_to_ = to;
return sb;
}
#endif
}
}
#endif

128
boost/process/win32_child.hpp

@ -1,128 +0,0 @@
//
// Boost.Process
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
// Copyright (c) 2008, 2009 Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
/**
* \file boost/process/win32_child.hpp
*
* Includes the declaration of the win32_child class.
*/
#ifndef BOOST_PROCESS_WIN32_CHILD_HPP
#define BOOST_PROCESS_WIN32_CHILD_HPP
#include <boost/process/child.hpp>
#include <boost/process/detail/file_handle.hpp>
#include <windows.h>
namespace boost {
namespace process {
/**
* Windows implementation of the Child concept.
*
* The win32_child class implements the Child concept in a Windows
* operating system.
*
* A Windows child differs from a regular %child (represented by a
* child object) in that it holds additional information about a process.
* Aside from the standard handle, it also includes a handle to the
* process' main thread, together with identifiers to both entities.
*
* This class is built on top of the generic child so as to allow its
* trivial adoption. When a program is changed to use the
* Windows-specific context (win32_context), it will most certainly need
* to migrate its use of the child class to win32_child. Doing so is only
* a matter of redefining the appropriate object and later using the
* required extra features: there should be no need to modify the existing
* code (e.g. method calls) in any other way.
*/
class win32_child : public child
{
public:
/**
* Constructs a new Windows child object representing a just
* spawned %child process.
*
* Creates a new %child object that represents the process described by
* the \a pi structure.
*
* The \a fhstdin, \a fhstdout and \a fhstderr parameters hold the
* communication streams used to interact with the %child process if
* the launcher configured redirections. See the parent class'
* constructor for more details on these.
*
* \see child
*/
win32_child(const PROCESS_INFORMATION &pi, detail::file_handle fhstdin, detail::file_handle fhstdout, detail::file_handle fhstderr)
: child(pi.dwProcessId, fhstdin, fhstdout, fhstderr, pi.hProcess),
process_information_(pi),
thread_handle_(process_information_.hThread)
{
}
/**
* Returns the process handle.
*
* Returns a process-specific handle that can be used to access the
* process. This is the value of the \a hProcess field in the
* PROCESS_INFORMATION structure returned by CreateProcess().
*
* \see get_id()
*/
HANDLE get_handle() const
{
return process_information_.hProcess;
}
/**
* Returns the primary thread's handle.
*
* Returns a handle to the primary thread of the new process. This is
* the value of the \a hThread field in the PROCESS_INFORMATION
* structure returned by CreateProcess().
*
* \see get_primary_thread_id()
*/
HANDLE get_primary_thread_handle() const
{
return process_information_.hThread;
}
/**
* Returns the primary thread's identifier.
*
* Returns a system-wide value that identifies the process's primary
* thread. This is the value of the \a dwThreadId field in the
* PROCESS_INFORMATION structure returned by CreateProcess().
*
* \see get_primary_thread_handle()
*/
DWORD get_primary_thread_id() const
{
return process_information_.dwThreadId;
}
private:
/**
* Windows-specific process information.
*/
PROCESS_INFORMATION process_information_;
/**
* Thread handle owned by RAII object.
*/
detail::file_handle thread_handle_;
};
}
}
#endif

61
boost/process/win32_context.hpp

@ -1,61 +0,0 @@
//
// Boost.Process
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
// Copyright (c) 2008, 2009 Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
/**
* \file boost/process/win_32context.hpp
*
* Includes the declaration of the win32_context class.
*/
#ifndef BOOST_PROCESS_WIN32_CONTEXT_HPP
#define BOOST_PROCESS_WIN32_CONTEXT_HPP
#include <boost/process/context.hpp>
#include <string>
#include <windows.h>
namespace boost {
namespace process {
/**
* Generic implementation of the Context concept.
*
* The context class implements the Context concept in an operating
* system agnostic way; it allows spawning new child processes using
* a single and common interface across different systems.
*/
template <class String>
class win32_basic_context : public basic_context<String>
{
public:
/**
* Initializes the Win32-specific process startup information with NULL.
*/
win32_basic_context()
: startupinfo(NULL)
{
}
/**
* Win32-specific process startup information.
*/
STARTUPINFOA *startupinfo;
};
/**
* Default instantiation of win32_basic_context.
*/
typedef win32_basic_context<std::string> win32_context;
}
}
#endif

77
boost/process/win32_operations.hpp

@ -1,77 +0,0 @@
//
// Boost.Process
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
// Copyright (c) 2008, 2009 Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
/**
* \file boost/process/win32_operations.hpp
*
* Provides miscellaneous free functions specific to Windows operating
* systems.
*/
#ifndef BOOST_PROCESS_WIN32_OPERATIONS_HPP
#define BOOST_PROCESS_WIN32_OPERATIONS_HPP
#include <boost/process/win32_child.hpp>
#include <boost/process/detail/file_handle.hpp>
#include <boost/process/detail/stream_info.hpp>
#include <boost/process/detail/win32_ops.hpp>
#include <windows.h>
namespace boost {
namespace process {
/**
* Starts a new child process.
*
* Given an executable and the set of arguments passed to it, starts
* a new process with all the parameters configured in the context.
* The context can be reused afterwards to launch other different
* processes.
*
* \return A handle to the new child process.
*/
template <class Executable, class Arguments, class Win32_Context>
inline win32_child win32_launch(const Executable &exe, const Arguments &args, const Win32_Context &ctx)
{
detail::file_handle fhstdin, fhstdout, fhstderr;
detail::stream_info behin = detail::stream_info(ctx.stdin_behavior, false);
if (behin.type_ == detail::stream_info::use_pipe)
fhstdin = behin.pipe_->wend();
detail::stream_info behout = detail::stream_info(ctx.stdout_behavior, true);
if (behout.type_ == detail::stream_info::use_pipe)
fhstdout = behout.pipe_->rend();
detail::stream_info beherr = detail::stream_info(ctx.stderr_behavior, true);
if (beherr.type_ == detail::stream_info::use_pipe)
fhstderr = beherr.pipe_->rend();
detail::win32_setup s;
s.work_directory = ctx.work_directory;
STARTUPINFOA si;
if (!ctx.startupinfo)
{
::ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
s.startupinfo = &si;
}
else
s.startupinfo = ctx.startupinfo;
PROCESS_INFORMATION pi = detail::win32_start(exe, args, ctx.environment, behin, behout, beherr, s);
return win32_child(pi, fhstdin, fhstdout, fhstderr);
}
}
}
#endif

27
build.py

@ -0,0 +1,27 @@
#!/usr/bin/python
# cpp-ethereum build script
# to be used from CI server, or to build locally
# uses python instead of bash script for better cross-platform support
# TODO Initial version. Needs much more improvements
import argparse
import os
import subprocess
def build_dependencies():
if os.path.exists("extdep"):
os.chdir("extdep")
if not os.path.exists("build"):
os.makedirs("build")
os.chdir("build")
subprocess.check_call(["cmake", ".."])
subprocess.check_call("make")
parser = argparse.ArgumentParser()
parser.add_argument("cmd", help="what to build")
args = parser.parse_args()
if args.cmd == "dep":
build_dependencies()

66
cmake/EthCompilerSettings.cmake

@ -1,59 +1,39 @@
# Set necessary compile and link flags
# C++11 check and activation
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wno-unknown-pragmas -Wextra -DSHAREDLIB -fPIC")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DETH_DEBUG")
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG -DETH_RELEASE")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -DETH_RELEASE")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DETH_DEBUG")
set(ETH_SHARED 1)
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
if (NOT (GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7))
message(FATAL_ERROR "${PROJECT_NAME} requires g++ 4.7 or greater.")
endif ()
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
else ()
message(FATAL_ERROR "Your C++ compiler does not support C++11.")
endif ()
# Initialize CXXFLAGS
set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wno-unknown-pragmas -Wextra -DSHAREDLIB")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DETH_DEBUG")
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG -DETH_RELEASE")
set(CMAKE_CXX_FLAGS_RELEASE "-O4 -DNDEBUG -DETH_RELEASE")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DETH_DEBUG")
# Windows
if ("${TARGET_PLATFORM}" STREQUAL "w64")
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_CXX_LIBRARY_ARCHITECTURE x86_64-w64-mingw32)
set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc)
set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++)
set(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres)
set(CMAKE_AR x86_64-w64-mingw32-ar)
set(CMAKE_RANLIB x86_64-w64-mingw32-ranlib)
set(CMAKE_EXECUTABLE_SUFFIX .exe)
set(CMAKE_FIND_ROOT_PATH
/usr/x86_64-w64-mingw32
)
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
include_directories(/usr/x86_64-w64-mingw32/include/cryptopp)
set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wno-unknown-pragmas -Wextra -DSHAREDLIB -fPIC")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DETH_DEBUG")
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG -DETH_RELEASE")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -DETH_RELEASE")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DETH_DEBUG")
set(ETH_SHARED 1)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
set(CMAKE_INSTALL_PREFIX /usr/x86_64-w64-mingw32)
set(ETH_BUILD_PLATFORM "windows")
# specify Exception Handling Model in msvc
set(CMAKE_C_FLAGS "/EHsc")
set(CMAKE_CXX_FLAGS "/EHsc")
# windows likes static
set(ETH_STATIC 1)
else ()
set(ETH_BUILD_PLATFORM ${CMAKE_SYSTEM_NAME})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
set(ETH_SHARED 1)
endif()
else ()
message(WARNING "Your compiler is not tested, if you run into any issues, we'd welcome any patches.")
endif ()

148
cmake/EthDependencies.cmake

@ -0,0 +1,148 @@
# all dependencies that are not directly included in the cpp-ethereum distribution are defined here
# for this to work, download the dependency via the cmake script in extdep or install them manually!
# by defining this variable, cmake will look for dependencies first in our own repository before looking in system paths like /usr/local/ ...
# this must be set to point to the same directory as $ETH_DEPENDENCY_INSTALL_DIR in /extdep directory
string(TOLOWER ${CMAKE_SYSTEM_NAME} _system_name)
set (ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/extdep/install/${_system_name}")
set (CMAKE_PREFIX_PATH ${ETH_DEPENDENCY_INSTALL_DIR})
# Qt5 requires opengl
# TODO use proper version of windows SDK (32 vs 64)
# TODO make it possible to use older versions of windows SDK (7.0+ should also work)
# TODO it windows SDK is NOT FOUND, throw ERROR
if (WIN32)
set (CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "C:/Program Files/Windows Kits/8.1/Lib/winv6.3/um/x86")
message(" - Found windows 8.1 SDK")
#set (CMAKE_PREFIX_PATH "C:/Program Files/Windows Kits/8.1/Lib/winv6.3/um/x64")
endif()
# homebrew installs qts in opt
if (APPLE)
set (CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "/usr/local/opt/qt5")
endif()
# Dependencies must have a version number, to ensure reproducible build. The version provided here is the one that is in the extdep repository. If you use system libraries, version numbers may be different.
find_package (CryptoPP 5.6.2 EXACT REQUIRED)
message(" - CryptoPP header: ${CRYPTOPP_INCLUDE_DIRS}")
message(" - CryptoPP lib : ${CRYPTOPP_LIBRARIES}")
find_package (LevelDB REQUIRED)
message(" - LevelDB header: ${LEVELDB_INCLUDE_DIRS}")
message(" - LevelDB lib: ${LEVELDB_LIBRARIES}")
# TODO the Jsoncpp package does not yet check for correct version number
find_package (Jsoncpp 0.60 REQUIRED)
message(" - Jsoncpp header: ${JSONCPP_INCLUDE_DIRS}")
message(" - Jsoncpp lib : ${JSONCPP_LIBRARIES}")
# TODO the JsonRpcCpp package does not yet check for correct version number
# json-rpc-cpp support is currently not mandatory
# TODO make headless client optional
# TODO get rid of -DETH_JSONRPC
if (JSONRPC)
find_package (JsonRpcCpp 0.3.2)
if (NOT JSON_RPC_CPP_FOUND)
message (FATAL_ERROR "JSONRPC 0.3.2. not found")
endif()
message (" - json-rpc-cpp header: ${JSON_RPC_CPP_INCLUDE_DIRS}")
message (" - json-rpc-cpp lib : ${JSON_RPC_CPP_LIBRARIES}")
add_definitions(-DETH_JSONRPC)
endif() #JSONRPC
# TODO readline package does not yet check for correct version number
# TODO make readline package dependent on cmake options
# TODO get rid of -DETH_READLINE
find_package (Readline 6.3.8)
if (READLINE_FOUND)
message (" - readline header: ${READLINE_INCLUDE_DIRS}")
message (" - readline lib : ${READLINE_LIBRARIES}")
add_definitions(-DETH_READLINE)
endif ()
# TODO miniupnpc package does not yet check for correct version number
# TODO make miniupnpc package dependent on cmake options
# TODO get rid of -DMINIUPNPC
find_package (Miniupnpc 1.8.2013)
if (MINIUPNPC_FOUND)
message (" - miniupnpc header: ${MINIUPNPC_INCLUDE_DIRS}")
message (" - miniupnpc lib : ${MINIUPNPC_LIBRARIES}")
add_definitions(-DETH_MINIUPNPC)
endif()
# TODO gmp package does not yet check for correct version number
# TODO it is also not required in msvc build
find_package (Gmp 6.0.0)
if (GMP_FOUND)
message(" - gmp Header: ${GMP_INCLUDE_DIRS}")
message(" - gmp lib : ${GMP_LIBRARIES}")
endif()
# curl is only requried for tests
# TODO specify min curl version, on windows we are currently using 7.29
find_package (CURL)
message(" - curl header: ${CURL_INCLUDE_DIRS}")
message(" - curl lib : ${CURL_LIBRARIES}")
# do not compile GUI
if (NOT HEADLESS)
# we need json rpc to build alethzero
if (NOT JSON_RPC_CPP_FOUND)
message (FATAL_ERROR "JSONRPC is required for GUI client")
endif()
# find all of the Qt packages
# remember to use 'Qt' instead of 'QT', cause unix is case sensitive
# TODO make headless client optional
find_package (Qt5Core REQUIRED)
find_package (Qt5Gui REQUIRED)
find_package (Qt5Quick REQUIRED)
find_package (Qt5Qml REQUIRED)
find_package (Qt5Network REQUIRED)
find_package (Qt5Widgets REQUIRED)
find_package (Qt5WebKit REQUIRED)
find_package (Qt5WebKitWidgets REQUIRED)
# we need to find path to macdeployqt on mac
if (APPLE)
set (MACDEPLOYQT_APP ${Qt5Core_DIR}/../../../bin/macdeployqt)
message(" - macdeployqt path: ${MACDEPLOYQT_APP}")
endif()
endif() #HEADLESS
# use multithreaded boost libraries, with -mt suffix
set(Boost_USE_MULTITHREADED ON)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
# TODO hanlde other msvc versions or it will fail find them
set(Boost_COMPILER -vc120)
# use static boost libraries *.lib
set(Boost_USE_STATIC_LIBS ON)
elseif (APPLE)
# use static boost libraries *.a
set(Boost_USE_STATIC_LIBS ON)
elseif (UNIX)
# use dynamic boost libraries .dll
set(Boost_USE_STATIC_LIBS OFF)
endif()
find_package(Boost 1.54.0 REQUIRED COMPONENTS thread date_time system regex chrono filesystem unit_test_framework program_options)
message(" - boost header: ${Boost_INCLUDE_DIRS}")
message(" - boost lib : ${Boost_LIBRARIES}")
if (APPLE)
link_directories(/usr/local/lib)
include_directories(/usr/local/include)
endif()

210
cmake/EthDependenciesDeprecated.cmake

@ -1,210 +0,0 @@
# search for and configure dependencies
# deprecated. TODO will rewrite to proper CMake packages
if("${TARGET_PLATFORM}" STREQUAL "w64")
# set(MINIUPNPC_LS /usr/x86_64-w64-mingw32/lib/libminiupnpc.a)
set(LEVELDB_LS leveldb)
set(CRYPTOPP_LS cryptopp)
set(CRYPTOPP_ID /usr/x86_64-w64-mingw32/include/cryptopp)
else()
# Look for available Crypto++ version and if it is >= 5.6.2
find_path(ID cryptlib.h
../cryptopp/src
../../cryptopp/src
/usr/include/cryptopp
/usr/include/crypto++
/usr/local/include/cryptopp
/usr/local/include/crypto++
/opt/local/include/cryptopp
/opt/local/include/crypto++
)
find_library(LS NAMES cryptoppeth cryptopp
../cryptopp/src/../target/build/release
../../cryptopp/src/../target/build/release
PATHS
/usr/lib
/usr/local/lib
/opt/local/lib
)
if (ID AND LS)
message(STATUS "Found Crypto++: ${ID}, ${LS}")
set(_CRYPTOPP_VERSION_HEADER ${ID}/config.h)
if(EXISTS ${_CRYPTOPP_VERSION_HEADER})
file(STRINGS ${_CRYPTOPP_VERSION_HEADER} _CRYPTOPP_VERSION REGEX "^#define CRYPTOPP_VERSION[ \t]+[0-9]+$")
string(REGEX REPLACE "^#define CRYPTOPP_VERSION[ \t]+([0-9]+)" "\\1" _CRYPTOPP_VERSION ${_CRYPTOPP_VERSION})
if(${_CRYPTOPP_VERSION} LESS 562)
message(FATAL_ERROR "Crypto++ version found is smaller than 5.6.2.")
else()
set(CRYPTOPP_ID ${ID} CACHE FILEPATH "")
set(CRYPTOPP_LS ${LS} CACHE FILEPATH "")
message(STATUS "Crypto++ found and version greater or equal to 5.6.2")
endif()
endif()
else()
message(STATUS "Crypto++ Not Found: ${CRYPTOPP_ID}, ${CRYPTOPP_LS}")
endif()
find_path( LEVELDB_ID leveldb/db.h
/usr/include
/usr/local/include
)
if ( LEVELDB_ID STREQUAL "LEVELDB_ID-NOTFOUND" )
message(FATAL_ERROR "Failed to find the LevelDB headers")
else ()
message(STATUS "Found LevelDB Headers")
# Check for accessory dev libraries leveldb and miniupnpc
find_library( LEVELDB_LS NAMES leveldb
PATHS
/usr/lib
/usr/local/lib
/opt/local/lib
/usr/lib/*/
)
if ( LEVELDB_LS STREQUAL "LEVELDB_LS-NOTFOUND" )
message(FATAL_ERROR "Failed to find the LevelDB Library!")
else ()
message(STATUS "Found LevelDB Library: ${LEVELDB_LS}")
add_definitions(-DETH_LEVELDB)
endif ()
endif ()
find_path( PYTHON_ID pyconfig.h
${PYTHON_INCLUDE_DIR}
/usr/include/python2.7
/usr/local/include/python2.7
)
if ( PYTHON_ID STREQUAL "PYTHON_ID-NOTFOUND" )
message(STATUS "Failed to find the Python-2.7 headers")
else ()
message(STATUS "Found Python-2.7 Headers: ${PYTHON_ID}")
# Check for accessory dev libraries leveldb and miniupnpc
find_library( PYTHON_LS NAMES python2.7
PATHS
/usr/lib
/usr/local/lib
/opt/local/lib
/usr/lib/*/
)
if ( PYTHON_LS STREQUAL "PYTHON_LS-NOTFOUND" )
message(STATUS "Failed to find the Python-2.7 Library!")
set(PYTHON_ID)
set(PYTHON_LS)
else ()
message(STATUS "Found Python-2.7 Library: ${PYTHON_LS}")
add_definitions(-DETH_PYTHON)
endif ()
endif ()
find_path( MINIUPNPC_ID miniupnpc/miniwget.h
/usr/include
/usr/local/include
)
if ( MINIUPNPC_ID )
message(STATUS "Found miniupnpc headers")
find_library( MINIUPNPC_LS NAMES miniupnpc
PATHS
/usr/lib
/usr/local/lib
/opt/local/lib
/usr/lib/*/
)
if ( MINIUPNPC_LS )
message(STATUS "Found miniupnpc library: ${MINIUPNPC_LS}")
add_definitions(-DETH_MINIUPNPC)
else ()
message(STATUS "Failed to find the miniupnpc library!")
endif ()
else ()
message(STATUS "Failed to find the miniupnpc headers!")
endif ()
find_path( JSONRPC_ID jsonrpc/rpc.h
/usr/include
/usr/local/include
../libjson-rpc-cpp/src
)
if ( JSONRPC_ID )
message(STATUS "Found jsonrpc headers")
find_library( JSONRPC_LS NAMES jsonrpc
PATHS
/usr/lib
/usr/local/lib
/opt/local/lib
/usr/lib/*/
../libjson-rpc-cpp/build/out
)
if ( JSONRPC_LS )
message(STATUS "Found jsonrpc library: ${JSONRPC_LS}")
add_definitions(-DETH_JSONRPC)
else ()
message(STATUS "Failed to find the jsonrpc library!")
endif ()
else ()
message(STATUS "Failed to find the jsonrpc headers!")
endif ()
find_path( READLINE_ID readline/readline.h
/usr/include
/usr/local/include
)
if ( READLINE_ID )
message(STATUS "Found readline headers")
find_library( READLINE_LS NAMES readline
PATHS
/usr/lib
/usr/local/lib
/opt/local/lib
/usr/lib/*/
)
if ( READLINE_LS )
message(STATUS "Found readline library: ${READLINE_LS}")
add_definitions(-DETH_READLINE)
else ()
message(STATUS "Failed to find the readline library!")
endif ()
else ()
message(STATUS "Failed to find the readline headers!")
endif ()
if (LANGUAGES)
find_package(Boost 1.53 REQUIRED COMPONENTS thread date_time)
else()
find_package(Boost 1.53 REQUIRED COMPONENTS thread date_time system regex)
endif()
set(QTQML 1)
endif()
if(CRYPTOPP_ID)
include_directories(${CRYPTOPP_ID})
endif()
if(PYTHON_ID)
include_directories(${PYTHON_ID})
endif()
if(MINIUPNPC_ID)
include_directories(${MINIUPNPC_ID})
endif()
if(LEVELDB_ID)
include_directories(${LEVELDB_ID})
endif()
if(READLINE_ID)
include_directories(${READLINE_ID})
endif()
if(JSONRPC_ID)
include_directories(${JSONRPC_ID})
endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
link_directories(/usr/local/lib)
include_directories(/usr/local/include)
endif()

152
cmake/EthExecutableHelper.cmake

@ -0,0 +1,152 @@
#
# this function requires the following variables to be specified:
# ETH_VERSION
# PROJECT_NAME
# PROJECT_VERSION
# PROJECT_COPYRIGHT_YEAR
# PROJECT_VENDOR
# PROJECT_DOMAIN_SECOND
# PROJECT_DOMAIN_FIRST
# SRC_LIST
# HEADERS
#
# params:
# ICON
#
macro(eth_add_executable EXECUTABLE)
set (extra_macro_args ${ARGN})
set (options)
set (one_value_args ICON)
set (multi_value_args UI_RESOURCES WIN_RESOURCES)
cmake_parse_arguments (ETH_ADD_EXECUTABLE "${options}" "${one_value_args}" "${multi_value_args}" "${extra_macro_args}")
if (APPLE)
add_executable(${EXECUTABLE} MACOSX_BUNDLE ${SRC_LIST} ${HEADERS} ${ETH_ADD_EXECUTABLE_UI_RESOURCES})
set(PROJECT_VERSION "${ETH_VERSION}")
set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME} ${PROJECT_VERSION}")
set(MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_NAME} ${PROJECT_VERSION}")
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME} ${PROJECT_VERSION}")
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}")
set(MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT_YEAR} ${PROJECT_VENDOR}")
set(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_DOMAIN_SECOND}.${PROJECT_DOMAIN_FIRST}")
set(MACOSX_BUNDLE_BUNDLE_NAME ${EXECUTABLE})
set(MACOSX_BUNDLE_ICON_FILE ${ETH_ADD_EXECUTABLE_ICON})
set_target_properties(${EXECUTABLE} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_SOURCE_DIR}/EthereumMacOSXBundleInfo.plist.in")
set_source_files_properties(${EXECUTABLE} PROPERTIES MACOSX_PACKAGE_LOCATION MacOS)
set_source_files_properties(${MACOSX_BUNDLE_ICON_FILE}.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
else ()
add_executable(${EXECUTABLE} ${ETH_ADD_EXECUTABLE_UI_RESOURCES} ${ETH_ADD_EXECUTABLE_WIN_RESOURCES} ${SRC_LIST} ${HEADERS})
endif()
endmacro()
#
# this function requires the following variables to be specified:
# ETH_DEPENDENCY_INSTALL_DIR
#
# params:
# QMLDIR
#
macro(eth_install_executable EXECUTABLE)
set (extra_macro_args ${ARGN})
set (options)
set (one_value_args QMLDIR)
set (multi_value_args)
cmake_parse_arguments (ETH_INSTALL_EXECUTABLE "${options}" "${one_value_args}" "${multi_value_args}" "${extra_macro_args}")
if (ETH_INSTALL_EXECUTABLE_QMLDIR)
if (APPLE)
set(eth_qml_dir "-qmldir=${ETH_INSTALL_EXECUTABLE_QMLDIR}")
elseif (WIN32)
set(eth_qml_dir --qmldir ${ETH_INSTALL_EXECUTABLE_QMLDIR})
endif()
message(STATUS "${EXECUTABLE} qmldir: ${eth_qml_dir}")
endif()
if (APPLE)
# First have qt5 install plugins and frameworks
add_custom_command(TARGET ${EXECUTABLE} POST_BUILD
COMMAND ${MACDEPLOYQT_APP} ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTABLE}.app ${eth_qml_dir}
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
)
# This tool and next will inspect linked libraries in order to determine which dependencies are required
if (${CMAKE_CFG_INTDIR} STREQUAL ".")
set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${EXECUTABLE}.app")
else ()
set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/\$ENV{CONFIGURATION}/${EXECUTABLE}.app")
endif ()
# TODO check, how fixup_bundle works and if it is required
install(CODE "
include(BundleUtilities)
set(BU_CHMOD_BUNDLE_ITEMS 1)
fixup_bundle(\"${APP_BUNDLE_PATH}\" \"${BUNDLELIBS}\" \"../libqethereum ../libethereum ../secp256k1\")
" COMPONENT RUNTIME )
# Cleanup duplicate libs from macdeployqt
install(CODE "
file(GLOB LINGER_RM \"${APP_BUNDLE_PATH}/Contents/Frameworks/*.dylib\")
if (LINGER_RM)
file(REMOVE \${LINGER_RM})
endif ()
")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
# copy all dlls to executable directory
# TODO improve that by copying only required dlls
file (GLOB DLLS ${ETH_DEPENDENCY_INSTALL_DIR}/bin/*.dll)
foreach(DLL ${DLLS})
add_custom_command(TARGET ${EXECUTABLE} POST_BUILD
COMMAND cmake -E copy "${DLL}" "$<TARGET_FILE_DIR:${EXECUTABLE}>"
)
endforeach()
add_custom_command(TARGET ${EXECUTABLE} POST_BUILD
COMMAND cmake -E copy_directory
"${ETH_DEPENDENCY_INSTALL_DIR}/plugins/platforms"
$<TARGET_FILE_DIR:${EXECUTABLE}>/platforms
)
# ugly way, improve that
add_custom_command(TARGET ${EXECUTABLE} POST_BUILD
COMMAND cmake -E copy_directory
"${ETH_DEPENDENCY_INSTALL_DIR}/qml"
$<TARGET_FILE_DIR:${EXECUTABLE}>
)
install( FILES ${DLLS}
DESTINATION bin
COMPONENT ${EXECUTABLE}
)
install( DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/plugins/platforms
DESTINATION bin
COMPONENT ${EXECUTABLE}
)
file (GLOB QMLS ${ETH_DEPENDENCY_INSTALL_DIR}/qml/*)
foreach(QML ${QMLS})
install( DIRECTORY ${QML}
DESTINATION bin
COMPONENT ${EXECUTABLE}
)
endforeach()
install( TARGETS ${EXECUTABLE} RUNTIME
DESTINATION bin
COMPONENT ${EXECUTABLE}
)
else()
install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin)
endif ()
endmacro()

49
cmake/FindCURL.cmake

@ -0,0 +1,49 @@
# Find CURL
#
# Find the curl includes and library
#
# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH
#
# This module defines
# CURL_INCLUDE_DIRS, where to find header, etc.
# CURL_LIBRARIES, the libraries needed to use curl.
# CURL_FOUND, If false, do not try to use curl.
# only look in default directories
find_path(
CURL_INCLUDE_DIR
NAMES curl/curl.h
DOC "curl include dir"
)
find_library(
CURL_LIBRARY
# names from cmake's FindCURL
NAMES curl curllib libcurl_imp curllib_static libcurl
DOC "curl library"
)
set(CURL_INCLUDE_DIRS ${CURL_INCLUDE_DIR})
set(CURL_LIBRARIES ${CURL_LIBRARY})
# debug library on windows
# same naming convention as in qt (appending debug library with d)
# boost is using the same "hack" as us with "optimized" and "debug"
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
find_library(
CURL_LIBRARY_DEBUG
NAMES curld libcurld
DOC "curl debug library"
)
set(CURL_LIBRARIES optimized ${CURL_LIBRARIES} debug ${CURL_LIBRARY_DEBUG})
endif()
# handle the QUIETLY and REQUIRED arguments and set CURL_FOUND to TRUE
# if all listed variables are TRUE, hide their existence from configuration view
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(CURL DEFAULT_MSG
CURL_INCLUDE_DIR CURL_LIBRARY)
mark_as_advanced (CURL_INCLUDE_DIR CURL_LIBRARY)

108
cmake/FindCryptoPP.cmake

@ -0,0 +1,108 @@
# Module for locating the Crypto++ encryption library.
#
# Customizable variables:
# CRYPTOPP_ROOT_DIR
# This variable points to the CryptoPP root directory. On Windows the
# library location typically will have to be provided explicitly using the
# -D command-line option. The directory should include the include/cryptopp,
# lib and/or bin sub-directories.
#
# Read-only variables:
# CRYPTOPP_FOUND
# Indicates whether the library has been found.
#
# CRYPTOPP_INCLUDE_DIRS
# Points to the CryptoPP include directory.
#
# CRYPTOPP_LIBRARIES
# Points to the CryptoPP libraries that should be passed to
# target_link_libararies.
#
#
# Copyright (c) 2012 Sergiu Dotenco
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
INCLUDE (FindPackageHandleStandardArgs)
FIND_PATH (CRYPTOPP_ROOT_DIR
NAMES cryptopp/cryptlib.h include/cryptopp/cryptlib.h
PATHS ENV CRYPTOPPROOT
DOC "CryptoPP root directory")
# Re-use the previous path:
FIND_PATH (CRYPTOPP_INCLUDE_DIR
NAMES cryptopp/cryptlib.h
HINTS ${CRYPTOPP_ROOT_DIR}
PATH_SUFFIXES include
DOC "CryptoPP include directory")
FIND_LIBRARY (CRYPTOPP_LIBRARY_DEBUG
NAMES cryptlibd cryptoppd
HINTS ${CRYPTOPP_ROOT_DIR}
PATH_SUFFIXES lib
DOC "CryptoPP debug library")
FIND_LIBRARY (CRYPTOPP_LIBRARY_RELEASE
NAMES cryptlib cryptopp
HINTS ${CRYPTOPP_ROOT_DIR}
PATH_SUFFIXES lib
DOC "CryptoPP release library")
IF (CRYPTOPP_LIBRARY_DEBUG AND CRYPTOPP_LIBRARY_RELEASE)
SET (CRYPTOPP_LIBRARY
optimized ${CRYPTOPP_LIBRARY_RELEASE}
debug ${CRYPTOPP_LIBRARY_DEBUG} CACHE DOC "CryptoPP library")
ELSEIF (CRYPTOPP_LIBRARY_RELEASE)
SET (CRYPTOPP_LIBRARY ${CRYPTOPP_LIBRARY_RELEASE} CACHE DOC
"CryptoPP library")
ENDIF (CRYPTOPP_LIBRARY_DEBUG AND CRYPTOPP_LIBRARY_RELEASE)
IF (CRYPTOPP_INCLUDE_DIR)
SET (_CRYPTOPP_VERSION_HEADER ${CRYPTOPP_INCLUDE_DIR}/cryptopp/config.h)
IF (EXISTS ${_CRYPTOPP_VERSION_HEADER})
FILE (STRINGS ${_CRYPTOPP_VERSION_HEADER} _CRYPTOPP_VERSION_TMP REGEX
"^#define CRYPTOPP_VERSION[ \t]+[0-9]+$")
STRING (REGEX REPLACE
"^#define CRYPTOPP_VERSION[ \t]+([0-9]+)" "\\1" _CRYPTOPP_VERSION_TMP
${_CRYPTOPP_VERSION_TMP})
STRING (REGEX REPLACE "([0-9]+)[0-9][0-9]" "\\1" CRYPTOPP_VERSION_MAJOR
${_CRYPTOPP_VERSION_TMP})
STRING (REGEX REPLACE "[0-9]([0-9])[0-9]" "\\1" CRYPTOPP_VERSION_MINOR
${_CRYPTOPP_VERSION_TMP})
STRING (REGEX REPLACE "[0-9][0-9]([0-9])" "\\1" CRYPTOPP_VERSION_PATCH
${_CRYPTOPP_VERSION_TMP})
SET (CRYPTOPP_VERSION_COUNT 3)
SET (CRYPTOPP_VERSION
${CRYPTOPP_VERSION_MAJOR}.${CRYPTOPP_VERSION_MINOR}.${CRYPTOPP_VERSION_PATCH})
ENDIF (EXISTS ${_CRYPTOPP_VERSION_HEADER})
ENDIF (CRYPTOPP_INCLUDE_DIR)
SET (CRYPTOPP_INCLUDE_DIRS ${CRYPTOPP_INCLUDE_DIR})
SET (CRYPTOPP_LIBRARIES ${CRYPTOPP_LIBRARY})
MARK_AS_ADVANCED (CRYPTOPP_INCLUDE_DIR CRYPTOPP_LIBRARY CRYPTOPP_LIBRARY_DEBUG
CRYPTOPP_LIBRARY_RELEASE)
FIND_PACKAGE_HANDLE_STANDARD_ARGS (CryptoPP REQUIRED_VARS
CRYPTOPP_INCLUDE_DIR CRYPTOPP_LIBRARY VERSION_VAR CRYPTOPP_VERSION)

34
cmake/FindGmp.cmake

@ -0,0 +1,34 @@
# Find gmp
#
# Find the gmp includes and library
#
# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH
#
# This module defines
# GMP_INCLUDE_DIRS, where to find header, etc.
# GMP_LIBRARIES, the libraries needed to use gmp.
# GMP_FOUND, If false, do not try to use gmp.
# only look in default directories
find_path(
GMP_INCLUDE_DIR
NAMES gmp.h
DOC "gmp include dir"
)
find_library(
GMP_LIBRARY
NAMES gmp
DOC "gmp library"
)
set(GMP_INCLUDE_DIRS ${GMP_INCLUDE_DIR})
set(GMP_LIBRARIES ${GMP_LIBRARY})
# handle the QUIETLY and REQUIRED arguments and set GMP_FOUND to TRUE
# if all listed variables are TRUE, hide their existence from configuration view
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(gmp DEFAULT_MSG
GMP_INCLUDE_DIR GMP_LIBRARY)
mark_as_advanced (GMP_INCLUDE_DIR GMP_LIBRARY)

99
cmake/FindJsonRpcCpp.cmake

@ -0,0 +1,99 @@
# Find json-rcp-cpp
#
# Find the json-rpc-cpp includes and library
#
# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH
#
# This module defines
# JSON_RCP_CPP_INCLUDE_DIRS, where to find header, etc.
# JSON_RCP_CPP_LIBRARIES, the libraries needed to use json-rpc-cpp.
# JSON_RPC_CPP_SERVER_LIBRARIES, the libraries needed to use json-rpc-cpp-server
# JSON_RPC_CPP_CLIENT_LIBRARIES, the libraries needed to use json-rpc-cpp-client
# JSON_RCP_CPP_FOUND, If false, do not try to use json-rpc-cpp.
# only look in default directories
find_path(
JSON_RPC_CPP_INCLUDE_DIR
NAMES jsonrpccpp/server.h
PATH_SUFFIXES jsonrpc
DOC "json-rpc-cpp include dir"
)
find_library(
JSON_RPC_CPP_COMMON_LIBRARY
NAMES jsonrpccpp-common
DOC "json-rpc-cpp common library"
)
find_library(
JSON_RPC_CPP_SERVER_LIBRARY
NAMES jsonrpccpp-server
DOC "json-rpc-cpp server library"
)
find_library(
JSON_RPC_CPP_CLIENT_LIBRARY
NAMES jsonrpccpp-client
DOC "json-rpc-cpp client library"
)
# these are the variables to be uses by the calling script
set (JSON_RPC_CPP_INCLUDE_DIRS ${JSON_RPC_CPP_INCLUDE_DIR})
set (JSON_RPC_CPP_LIBRARIES ${JSON_RPC_CPP_COMMON_LIBRARY} ${JSON_RPC_CPP_SERVER_LIBRARY} ${JSON_RPC_CPP_CLIENT_LIBRARY})
set (JSON_RPC_CPP_SERVER_LIBRARIES ${JSON_RPC_CPP_COMMON_LIBRARY} ${JSON_RPC_CPP_SERVER_LIBRARY})
set (JSON_RPC_CPP_CLIENT_LIBRARIES ${JSON_RPC_CPP_COMMON_LIBRARY} ${JSON_RPC_CPP_CLIENT_LIBRARY})
# debug library on windows
# same naming convention as in qt (appending debug library with d)
# boost is using the same "hack" as us with "optimized" and "debug"
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
find_library(
JSON_RPC_CPP_COMMON_LIBRARY_DEBUG
NAMES jsonrpccpp-commond
DOC "json-rpc-cpp common debug library"
)
find_library(
JSON_RPC_CPP_SERVER_LIBRARY_DEBUG
NAMES jsonrpccpp-serverd
DOC "json-rpc-cpp server debug library"
)
find_library(
JSON_RPC_CPP_CLIENT_LIBRARY_DEBUG
NAMES jsonrpccpp-clientd
DOC "json-rpc-cpp client debug library"
)
set (JSON_RPC_CPP_LIBRARIES
optimized ${JSON_RPC_CPP_COMMON_LIBRARY}
optimized ${JSON_RPC_CPP_SERVER_LIBRARY}
optimized ${JSON_RPC_CPP_CLIENT_LIBRARY}
debug ${JSON_RPC_CPP_COMMON_LIBRARY_DEBUG}
debug ${JSON_RPC_CPP_SERVER_LIBRARY_DEBUG}
debug ${JSON_RPC_CPP_CLIENT_LIBRARY_DEBUG}
)
set (JSON_RPC_CPP_SERVER_LIBRARIES
optimized ${JSON_RPC_CPP_COMMON_LIBRARY}
optimized ${JSON_RPC_CPP_SERVER_LIBRARY}
debug ${JSON_RPC_CPP_COMMON_LIBRARY_DEBUG}
debug ${JSON_RPC_CPP_SERVER_LIBRARY_DEBUG}
)
set (JSON_RPC_CPP_CLIENT_LIBRARIES
optimized ${JSON_RPC_CPP_COMMON_LIBRARY}
optimized ${JSON_RPC_CPP_CLIENT_LIBRARY}
debug ${JSON_RPC_CPP_COMMON_LIBRARY_DEBUG}
debug ${JSON_RPC_CPP_CLIENT_LIBRARY_DEBUG}
)
endif()
# handle the QUIETLY and REQUIRED arguments and set JSON_RPC_CPP_FOUND to TRUE
# if all listed variables are TRUE, hide their existence from configuration view
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(json_rpc_cpp DEFAULT_MSG
JSON_RPC_CPP_COMMON_LIBRARY JSON_RPC_CPP_SERVER_LIBRARY JSON_RPC_CPP_CLIENT_LIBRARY JSON_RPC_CPP_INCLUDE_DIR)
mark_as_advanced (JSON_RPC_CPP_COMMON_LIBRARY JSON_RPC_CPP_SERVER_LIBRARY JSON_RPC_CPP_CLIENT_LIBRARY JSON_RPC_CPP_INCLUDE_DIR)

48
cmake/FindJsoncpp.cmake

@ -0,0 +1,48 @@
# Find jsoncpp
#
# Find the jsoncpp includes and library
#
# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH
#
# This module defines
# JSONCPP_INCLUDE_DIRS, where to find header, etc.
# JSONCPP_LIBRARIES, the libraries needed to use jsoncpp.
# JSONCPP_FOUND, If false, do not try to use jsoncpp.
# only look in default directories
find_path(
JSONCPP_INCLUDE_DIR
NAMES jsoncpp/json/json.h
DOC "jsoncpp include dir"
)
find_library(
JSONCPP_LIBRARY
NAMES jsoncpp
DOC "jsoncpp library"
)
set(JSONCPP_INCLUDE_DIRS ${JSONCPP_INCLUDE_DIR})
set(JSONCPP_LIBRARIES ${JSONCPP_LIBRARY})
# debug library on windows
# same naming convention as in qt (appending debug library with d)
# boost is using the same "hack" as us with "optimized" and "debug"
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
find_library(
JSONCPP_LIBRARY_DEBUG
NAMES jsoncppd
DOC "jsoncpp debug library"
)
set(JSONCPP_LIBRARIES optimized ${JSONCPP_LIBRARIES} debug ${JSONCPP_LIBRARY_DEBUG})
endif()
# handle the QUIETLY and REQUIRED arguments and set JSONCPP_FOUND to TRUE
# if all listed variables are TRUE, hide their existence from configuration view
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(jsoncpp DEFAULT_MSG
JSONCPP_INCLUDE_DIR JSONCPP_LIBRARY)
mark_as_advanced (JSONCPP_INCLUDE_DIR JSONCPP_LIBRARY)

48
cmake/FindLevelDB.cmake

@ -0,0 +1,48 @@
# Find leveldb
#
# Find the leveldb includes and library
#
# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH
#
# This module defines
# LEVELDB_INCLUDE_DIRS, where to find header, etc.
# LEVELDB_LIBRARIES, the libraries needed to use leveldb.
# LEVELDB_FOUND, If false, do not try to use leveldb.
# only look in default directories
find_path(
LEVELDB_INCLUDE_DIR
NAMES leveldb/db.h
DOC "leveldb include dir"
)
find_library(
LEVELDB_LIBRARY
NAMES leveldb
DOC "leveldb library"
)
set(LEVELDB_INCLUDE_DIRS ${LEVELDB_INCLUDE_DIR})
set(LEVELDB_LIBRARIES ${LEVELDB_LIBRARY})
# debug library on windows
# same naming convention as in qt (appending debug library with d)
# boost is using the same "hack" as us with "optimized" and "debug"
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
find_library(
LEVELDB_LIBRARY_DEBUG
NAMES leveldbd
DOC "leveldb debug library"
)
set(LEVELDB_LIBRARIES optimized ${LEVELDB_LIBRARIES} debug ${LEVELDB_LIBRARY_DEBUG})
endif()
# handle the QUIETLY and REQUIRED arguments and set LEVELDB_FOUND to TRUE
# if all listed variables are TRUE, hide their existence from configuration view
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(leveldb DEFAULT_MSG
LEVELDB_INCLUDE_DIR LEVELDB_LIBRARY)
mark_as_advanced (LEVELDB_INCLUDE_DIR LEVELDB_LIBRARY)

34
cmake/FindMiniupnpc.cmake

@ -0,0 +1,34 @@
# Find miniupnpc
#
# Find the miniupnpc includes and library
#
# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH
#
# This module defines
# MINIUPNPC_INCLUDE_DIRS, where to find header, etc.
# MINIUPNPC_LIBRARIES, the libraries needed to use gmp.
# MINIUPNPC_FOUND, If false, do not try to use gmp.
# only look in default directories
find_path(
MINIUPNPC_INCLUDE_DIR
NAMES miniupnpc/miniupnpc.h
DOC "miniupnpc include dir"
)
find_library(
MINIUPNPC_LIBRARY
NAMES miniupnpc
DOC "miniupnpc library"
)
set(MINIUPNPC_INCLUDE_DIRS ${MINIUPNPC_INCLUDE_DIR})
set(MINIUPNPC_LIBRARIES ${MINIUPNPC_LIBRARY})
# handle the QUIETLY and REQUIRED arguments and set MINIUPNPC_FOUND to TRUE
# if all listed variables are TRUE, hide their existence from configuration view
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(miniupnpc DEFAULT_MSG
MINIUPNPC_INCLUDE_DIR MINIUPNPC_LIBRARY)
mark_as_advanced (MINIUPNPC_INCLUDE_DIR MINIUPNPC_LIBRARY)

34
cmake/FindReadline.cmake

@ -0,0 +1,34 @@
# Find readline
#
# Find the readline includes and library
#
# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH
#
# This module defines
# READLINE_INCLUDE_DIRS, where to find header, etc.
# READLINE_LIBRARIES, the libraries needed to use readline.
# READLINE_FOUND, If false, do not try to use readline.
# only look in default directories
find_path(
READLINE_INCLUDE_DIR
NAMES readline/readline.h
DOC "readling include dir"
)
find_library(
READLINE_LIBRARY
NAMES readline
DOC "readline library"
)
set(READLINE_INCLUDE_DIRS ${READLINE_INCLUDE_DIR})
set(READLINE_LIBRARIES ${READLINE_LIBRARY})
# handle the QUIETLY and REQUIRED arguments and set READLINE_FOUND to TRUE
# if all listed variables are TRUE, hide their existence from configuration view
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(readline DEFAULT_MSG
READLINE_INCLUDE_DIR READLINE_LIBRARY)
mark_as_advanced (READLINE_INCLUDE_DIR READLINE_LIBRARY)

2364
doc/Doxyfile

File diff suppressed because it is too large

15
docker/Dockerfile

@ -7,6 +7,7 @@ RUN apt-get upgrade -y
# Ethereum dependencies
RUN apt-get install -qy build-essential g++-4.8 git cmake libboost-all-dev libcurl4-openssl-dev wget
RUN apt-get install -qy automake unzip libgmp-dev libtool libleveldb-dev yasm libminiupnpc-dev libreadline-dev scons
RUN apt-get install -qy libjsoncpp-dev libargtable2-dev
# NCurses based GUI (not optional though for a succesful compilation, see https://github.com/ethereum/cpp-ethereum/issues/452 )
RUN apt-get install -qy libncurses5-dev
@ -14,15 +15,11 @@ RUN apt-get install -qy libncurses5-dev
# Qt-based GUI
# RUN apt-get install -qy qtbase5-dev qt5-default qtdeclarative5-dev libqt5webkit5-dev
# Cryptopp
RUN git clone --depth=1 https://github.com/mmoss/cryptopp.git
RUN cd cryptopp && scons --shared --prefix=/usr
# JSONRPC (version 0.2.1, see https://github.com/ethereum/cpp-ethereum/issues/453 )
RUN apt-get install -qy libjsoncpp-dev libargtable2-dev
RUN git clone --depth=1 --branch=0.2.1 https://github.com/cinemast/libjson-rpc-cpp.git
RUN mkdir -p libjson-rpc-cpp/build
RUN cd libjson-rpc-cpp/build && cmake .. && make && make install
# Ethereum PPA
RUN apt-get install -qy software-properties-common
RUN add-apt-repository ppa:ethereum/ethereum
RUN apt-get update
RUN apt-get install -qy libcryptopp-dev libjson-rpc-cpp-dev
# Build Ethereum (HEADLESS)
RUN git clone --depth=1 https://github.com/ethereum/cpp-ethereum

47
eth/CMakeLists.txt

@ -1,48 +1,33 @@
cmake_policy(SET CMP0015 NEW)
set(CMAKE_AUTOMOC OFF)
aux_source_directory(. SRC_LIST)
include_directories(${Boost_INCLUDE_DIRS})
include_directories(${JSON_RPC_CPP_INCLUDE_DIRS})
include_directories(..)
set(EXECUTABLE eth)
file(GLOB HEADERS "*.h")
add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS})
target_link_libraries(${EXECUTABLE} webthree)
target_link_libraries(${EXECUTABLE} secp256k1)
target_link_libraries(${EXECUTABLE} gmp)
if(MINIUPNPC_LS)
target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS})
endif()
target_link_libraries(${EXECUTABLE} ${LEVELDB_LS})
target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS})
if(JSONRPC_LS)
target_link_libraries(${EXECUTABLE} web3jsonrpc)
add_dependencies(${EXECUTABLE} BuildInfo.h)
target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARIES})
target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARIES})
if (READLINE_FOUND)
target_link_libraries(${EXECUTABLE} ${READLINE_LIBRARIES})
endif()
if(READLINE_LS)
target_link_libraries(${EXECUTABLE} ${READLINE_LS})
if (JSONRPC)
target_link_libraries(${EXECUTABLE} web3jsonrpc)
endif()
if ("${TARGET_PLATFORM}" STREQUAL "w64")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++")
target_link_libraries(${EXECUTABLE} boost_system-mt-s)
target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s)
target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s)
target_link_libraries(${EXECUTABLE} gcc)
target_link_libraries(${EXECUTABLE} gdi32)
target_link_libraries(${EXECUTABLE} ws2_32)
target_link_libraries(${EXECUTABLE} mswsock)
target_link_libraries(${EXECUTABLE} shlwapi)
target_link_libraries(${EXECUTABLE} iphlpapi)
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS)
elseif (UNIX)
else ()
target_link_libraries(${EXECUTABLE} boost_system)
target_link_libraries(${EXECUTABLE} boost_filesystem)
find_package(Threads REQUIRED)
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT})
endif ()
target_link_libraries(${EXECUTABLE} webthree)
target_link_libraries(${EXECUTABLE} secp256k1)
install( TARGETS ${EXECUTABLE} DESTINATION bin )

31
eth/main.cpp

@ -27,10 +27,6 @@
#include <signal.h>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/trim_all.hpp>
#if ETH_JSONRPC
#include <jsonrpc/connectors/httpserver.h>
#include <libweb3jsonrpc/CorsHttpServer.h>
#endif
#include <libdevcrypto/FileSystem.h>
#include <libevmcore/Instruction.h>
#include <libevm/VM.h>
@ -42,6 +38,7 @@
#endif
#if ETH_JSONRPC
#include <libweb3jsonrpc/WebThreeStubServer.h>
#include <libweb3jsonrpc/CorsHttpServer.h>
#endif
#include "BuildInfo.h"
using namespace std;
@ -92,6 +89,7 @@ void interactiveHelp()
<< " importConfig <path> Import the config (.RLP) from the path provided." <<endl
<< " inspect <contract> Dumps a contract to <APPDATA>/<contract>.evm." << endl
<< " dumptrace <block> <index> <filename> <format> Dumps a transaction trace" << endl << "to <filename>. <format> should be one of pretty, standard, standard+." << endl
<< " dumpreceipt <block> <index> Dumps a transation receipt." << endl
<< " exit Exits the application." << endl;
}
@ -338,9 +336,11 @@ int main(int argc, char** argv)
#if ETH_JSONRPC
shared_ptr<WebThreeStubServer> jsonrpcServer;
unique_ptr<jsonrpc::AbstractServerConnector> jsonrpcConnector;
if (jsonrpc > -1)
{
jsonrpcServer = shared_ptr<WebThreeStubServer>(new WebThreeStubServer(new jsonrpc::CorsHttpServer(jsonrpc), web3, {us}));
jsonrpcConnector = unique_ptr<jsonrpc::AbstractServerConnector>(new jsonrpc::HttpServer(jsonrpc));
jsonrpcServer = shared_ptr<WebThreeStubServer>(new WebThreeStubServer(*jsonrpcConnector.get(), web3, vector<KeyPair>({us})));
jsonrpcServer->setIdentities({us});
jsonrpcServer->StartListening();
}
@ -428,7 +428,8 @@ int main(int argc, char** argv)
{
if (jsonrpc < 0)
jsonrpc = 8080;
jsonrpcServer = make_shared<WebThreeStubServer>(new jsonrpc::CorsHttpServer(jsonrpc), web3, vector<KeyPair>({us}));
jsonrpcConnector = unique_ptr<jsonrpc::AbstractServerConnector>(new jsonrpc::HttpServer(jsonrpc));
jsonrpcServer = shared_ptr<WebThreeStubServer>(new WebThreeStubServer(*jsonrpcConnector.get(), web3, vector<KeyPair>({us})));
jsonrpcServer->setIdentities({us});
jsonrpcServer->StartListening();
}
@ -441,9 +442,8 @@ int main(int argc, char** argv)
#endif
else if (cmd == "address")
{
cout << "Current address:" << endl;
const char* addchr = toHex(us.address().asArray()).c_str();
cout << addchr << endl;
cout << "Current address:" << endl
<< toHex(us.address().asArray()) << endl;
}
else if (cmd == "secret")
{
@ -607,6 +607,17 @@ int main(int argc, char** argv)
else
cwarn << "Require parameters: contract ENDOWMENT GASPRICE GAS CODEHEX";
}
else if (c && cmd == "dumpreceipt")
{
unsigned block;
unsigned index;
iss >> block >> index;
dev::eth::TransactionReceipt r = c->blockChain().receipts(c->blockChain().numberHash(block)).receipts[index];
auto rb = r.rlp();
cout << "RLP: " << RLP(rb) << endl;
cout << "Hex: " << toHex(rb) << endl;
cout << r << endl;
}
else if (c && cmd == "dumptrace")
{
unsigned block;
@ -620,7 +631,7 @@ int main(int argc, char** argv)
dev::eth::State state =c->state(index + 1,c->blockChain().numberHash(block));
if (index < state.pending().size())
{
Executive e(state, 0);
Executive e(state, c->blockChain(), 0);
Transaction t = state.pending()[index];
state = state.fromPending(index);
bytes r = t.rlp();

1
evmjit

@ -0,0 +1 @@
Subproject commit 66d5a2b5cdf1361dcf0205b191dd12be090ed224

30
exp/CMakeLists.txt

@ -1,7 +1,9 @@
cmake_policy(SET CMP0015 NEW)
set(CMAKE_AUTOMOC OFF)
aux_source_directory(. SRC_LIST)
include_directories(${LEVELDB_INCLUDE_DIRS})
include_directories(..)
set(EXECUTABLE exp)
@ -10,32 +12,6 @@ add_executable(${EXECUTABLE} ${SRC_LIST})
target_link_libraries(${EXECUTABLE} ethereum)
target_link_libraries(${EXECUTABLE} p2p)
target_link_libraries(${EXECUTABLE} gmp)
target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS})
if(MINIUPNPC_LS)
target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS})
endif()
target_link_libraries(${EXECUTABLE} ${LEVELDB_LS})
if ("${TARGET_PLATFORM}" STREQUAL "w64")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++")
target_link_libraries(${EXECUTABLE} gcc)
target_link_libraries(${EXECUTABLE} gdi32)
target_link_libraries(${EXECUTABLE} ws2_32)
target_link_libraries(${EXECUTABLE} mswsock)
target_link_libraries(${EXECUTABLE} shlwapi)
target_link_libraries(${EXECUTABLE} iphlpapi)
target_link_libraries(${EXECUTABLE} boost_system-mt-s)
target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s)
target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s)
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS)
elseif (UNIX)
else ()
target_link_libraries(${EXECUTABLE} boost_system)
target_link_libraries(${EXECUTABLE} boost_filesystem)
find_package(Threads REQUIRED)
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT})
endif ()
install( TARGETS ${EXECUTABLE} DESTINATION bin )
install( TARGETS ${EXECUTABLE} DESTINATION bin)

92
exp/main.cpp

@ -20,14 +20,17 @@
* Ethereum client.
*/
#include <functional>
#include <libethereum/AccountDiff.h>
#include <libdevcore/RangeMask.h>
#include <libdevcore/Log.h>
#include <libdevcore/Common.h>
#include <libdevcore/CommonData.h>
#include <libdevcore/RLP.h>
#include <libdevcore/CommonIO.h>
#include <libp2p/All.h>
#include <libdevcore/RangeMask.h>
#include <libethereum/DownloadMan.h>
#include <libethereum/All.h>
#include <liblll/All.h>
#include <libwhisper/WhisperPeer.h>
#include <libwhisper/WhisperHost.h>
using namespace std;
@ -36,7 +39,7 @@ using namespace dev::eth;
using namespace dev::p2p;
using namespace dev::shh;
#if 1
#if 0
int main()
{
DownloadMan man;
@ -72,72 +75,25 @@ int main()
cnote << i;*/
return 0;
}
#endif
/*int other(bool& o_started)
#else
int main()
{
setThreadName("other");
short listenPort = 30300;
Host ph("Test", NetworkPreferences(listenPort, "", false, true));
auto wh = ph.registerCapability(new WhisperHost());
ph.start();
o_started = true;
/// Only interested in odd packets
auto w = wh->installWatch(BuildTopicMask()("odd"));
unsigned last = 0;
unsigned total = 0;
for (int i = 0; i < 100 && last < 81; ++i)
{
for (auto i: wh->checkWatch(w))
{
Message msg = wh->envelope(i).open();
last = RLP(msg.payload()).toInt<unsigned>();
cnote << "New message from:" << msg.from().abridged() << RLP(msg.payload()).toInt<unsigned>();
total += last;
}
this_thread::sleep_for(chrono::milliseconds(50));
}
return total;
KeyPair u = KeyPair::create();
KeyPair cb = KeyPair::create();
OverlayDB db;
State s(cb.address(), db, BaseState::Empty);
cnote << s.rootHash();
s.addBalance(u.address(), 1 * ether);
Address c = s.newContract(1000 * ether, compileLLL("(suicide (caller))"));
s.commit();
State before = s;
cnote << "State before transaction: " << before;
Transaction t(0, 10000, 10000, c, bytes(), 0, u.secret());
cnote << "Transaction: " << t;
cnote << s.balance(c);
s.execute(LastHashes(), t.rlp());
cnote << "State after transaction: " << s;
cnote << before.diff(s);
}
#endif
int main(int, char**)
{
g_logVerbosity = 0;
bool started = false;
unsigned result;
std::thread listener([&](){ return (result = other(started)); });
while (!started)
this_thread::sleep_for(chrono::milliseconds(50));
short listenPort = 30303;
string remoteHost = "127.0.0.1";
short remotePort = 30300;
Host ph("Test", NetworkPreferences(listenPort, "", false, true));
auto wh = ph.registerCapability(new WhisperHost());
ph.start();
if (!remoteHost.empty())
ph.connect(remoteHost, remotePort);
KeyPair us = KeyPair::create();
for (int i = 0; i < 10; ++i)
{
wh->post(us.sec(), RLPStream().append(i * i).out(), BuildTopic(i)(i % 2 ? "odd" : "even"));
this_thread::sleep_for(chrono::milliseconds(250));
}
listener.join();
assert(result == 1 + 9 + 25 + 49 + 81);
return 0;
}*/

55
extdep/CMakeLists.txt

@ -0,0 +1,55 @@
cmake_minimum_required(VERSION 2.8.12)
include(ExternalProject)
include(CMakeParseArguments)
include(eth_download.cmake)
# all dependencies will be installed into this directory, separated by platform
string(TOLOWER ${CMAKE_SYSTEM_NAME} _system_name)
set(ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/install/${_system_name}")
set(ETH_DEPENDENCY_SERVER "http://poc-7.ethdev.com/precompiled/${_system_name}")
file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/lib)
file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/include)
file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/bin)
if (ETH_COMPILE)
# json-rpc-cpp and its dependencies
include(compile/jsoncpp.cmake)
include(compile/argtable2.cmake)
include(compile/curl.cmake)
include(compile/json-rpc-cpp.cmake)
# qt and its dependencies
include(compile/icu.cmake)
include(compile/jom.cmake)
include(compile/qt.cmake)
# leveldb and its dependencies
include(compile/snappy.cmake)
include(compile/leveldb.cmake)
# cryptopp
include(compile/cryptopp.cmake)
# boost
include(compile/boost.cmake)
else()
eth_download(jsoncpp)
eth_download(json-rpc-cpp OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/json-rpc-cpp_osx.sh)
if (APPLE)
eth_download(snappy OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/snappy_osx.sh)
endif()
eth_download(leveldb OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/leveldb_osx.sh)
eth_download(qt)
eth_download(cryptopp)
eth_download(boost)
eth_download(curl)
endif()
# will be re-eanbled later
# include(miniupnpc.cmake)
# if install phase of extep fails, even if libs are already created, the ethereum install will fail

16
extdep/Readme.md

@ -0,0 +1,16 @@
# cpp-ethereum external dependencies
**This is Work-in-Progress!**
This directory hosts the external libraries that are needed to build cpp-ethereum.
To automatically download, build, and link libraries, do
```
cd extdep; mkdir build; cd build; cmake ..; make
```
this will take some time.
To check which libraries are already included, check `CMakeLists.txt`. Other libraries still need to be fetched via the system's package manager.
Libraries will be installed in `cpp-ethereum/extdep/install/<platform-name>`

9
extdep/cmake/FindCURL.cmake

@ -0,0 +1,9 @@
# hacky way to resolve nested dependencies - needed for json-rpc-cpp
find_library(CURL_LIBRARY NAMES curl
PATHS
${ETH_DEPENDENCY_INSTALL_DIR}/lib
)
set(CURL_LIBRARIES ${CURL_LIBRARY})
set(CURL_INCLUDE_DIRS ${ETH_DEPENDENCY_INSTALL_DIR}/include)

13
extdep/compile/argtable2.cmake

@ -0,0 +1,13 @@
if (APPLE)
elseif (WIN32)
ExternalProject_Add(argtable2
GIT_REPOSITORY https://github.com/debris/argtable.git
GIT_TAG master
BINARY_DIR argtable2-prefix/src/argtable2
CONFIGURE_COMMAND cmake .
BUILD_COMMAND devenv argtable2.sln /build release
INSTALL_COMMAND cmd /c cp src/Release/argtable2.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp src/argtable2.h ${ETH_DEPENDENCY_INSTALL_DIR}/include
)
else()
endif()

19
extdep/compile/boost.cmake

@ -0,0 +1,19 @@
if (APPLE)
elseif (WIN32)
set(boost_address_model)
# on windows 64:
# set(boost_address_model address-model=64)
set(boost_targets --with-filesystem --with-system --with-thread --with-date_time --with-regex --with-test --with-chrono --with-program_options)
ExternalProject_Add(boost
URL http://downloads.sourceforge.net/project/boost/boost/1.55.0/boost_1_55_0.tar.gz
BINARY_DIR boost-prefix/src/boost
CONFIGURE_COMMAND ./bootstrap.bat
BUILD_COMMAND ./b2.exe -j4 --build-type=complete link=static runtime-link=shared variant=debug,release threading=multi ${boost_addressModel} ${boost_targets} install --prefix=${ETH_DEPENDENCY_INSTALL_DIR}
INSTALL_COMMAND cmake -E rename ${ETH_DEPENDENCY_INSTALL_DIR}/include/boost-1_55/boost ${ETH_DEPENDENCY_INSTALL_DIR}/include/boost
)
else()
endif()

33
extdep/compile/cryptopp.cmake

@ -0,0 +1,33 @@
# CryptoPP does not have good cross-platform support, there exist several different other projects to make it work ...
# TODO the OS X build throws a lot of warnings, but compiles fine
if (APPLE)
ExternalProject_Add(cryptopp
URL https://downloads.sourceforge.net/project/cryptopp/cryptopp/5.6.2/cryptopp562.zip
BINARY_DIR cryptopp-prefix/src/cryptopp
CONFIGURE_COMMAND ""
BUILD_COMMAND make CXX=clang++ CXXFLAGS=-DCRYPTOPP_DISABLE_ASM
INSTALL_COMMAND make install PREFIX=${ETH_DEPENDENCY_INSTALL_DIR}
)
elseif (WIN32)
file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/include/cryptopp)
ExternalProject_Add(cryptopp
SVN_REPOSITORY http://svn.code.sf.net/p/cryptopp/code/trunk/c5
SVN_REVISION -r "541"
BINARY_DIR cryptopp-prefix/src/cryptopp
CONFIGURE_COMMAND devenv cryptest.sln /upgrade
BUILD_COMMAND devenv cryptest.sln /build release
INSTALL_COMMAND cmd /c cp Win32/DLL_Output/Release/cryptopp.dll ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp Win32/DLL_Output/Release/cryptopp.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp *.h ${ETH_DEPENDENCY_INSTALL_DIR}/include/cryptopp
)
# on Linux, the default Makefile does not work.
else()
ExternalProject_Add(cryptopp
URL https://github.com/mmoss/cryptopp/archive/v5.6.2.zip
BINARY_DIR cryptopp-prefix/src/cryptopp
CONFIGURE_COMMAND ""
BUILD_COMMAND scons --shared --prefix=${ETH_DEPENDENCY_INSTALL_DIR}
INSTALL_COMMAND ""
)
endif()

29
extdep/compile/curl.cmake

@ -0,0 +1,29 @@
if (APPLE)
ExternalProject_Add(curl
URL http://curl.haxx.se/download/curl-7.38.0.tar.bz2
BINARY_DIR curl-prefix/src/curl
CONFIGURE_COMMAND ./configure --with-darwinssl --prefix=${ETH_DEPENDENCY_INSTALL_DIR} --exec-prefix=${ETH_DEPENDENCY_INSTALL_DIR}
BUILD_COMMAND make -j 3
INSTALL_COMMAND make install
)
elseif (WIN32)
ExternalProject_Add(curl
GIT_REPOSITORY https://github.com/debris/libcurl-7.29
GIT_TAG master
BINARY_DIR curl-prefix/src/curl
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND cmd /c cp lib/release/libcurl.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp -R include/curl ${ETH_DEPENDENCY_INSTALL_DIR}/include
)
else()
ExternalProject_Add(curl
URL http://curl.haxx.se/download/curl-7.38.0.tar.bz2
BINARY_DIR curl-prefix/src/curl
CONFIGURE_COMMAND CONFIG_CMD ./configure --prefix=${ETH_DEPENDENCY_INSTALL_DIR} --exec-prefix=${ETH_DEPENDENCY_INSTALL_DIR}
BUILD_COMMAND make -j 3
INSTALL_COMMAND make install
)
endif()

17
extdep/compile/icu.cmake

@ -0,0 +1,17 @@
if (APPLE)
elseif (WIN32)
ExternalProject_Add(icu
GIT_REPOSITORY https://github.com/debris/icu-win32.git
GIT_TAG master
BINARY_DIR icu-prefix/src/icu
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND cmake -E copy_directory . ${ETH_DEPENDENCY_INSTALL_DIR}
)
else()
endif()

16
extdep/compile/jom.cmake

@ -0,0 +1,16 @@
if (APPLE)
elseif (WIN32)
ExternalProject_Add(jom
URL http://download.qt-project.org/official_releases/jom/jom.zip
BINARY_DIR jom-prefix/src/jom
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND cmake -E copy jom.exe ${ETH_DEPENDENCY_INSTALL_DIR}/bin
)
else()
endif()

40
extdep/compile/json-rpc-cpp.cmake

@ -0,0 +1,40 @@
# json-rpc-cpp is under heavy development, not yet stable, and multiplatform builds are not yet available.
# DO NOT MESS WITH THESE SETTINGS! IF YOU HAVE TO MAKE CHANGES HERE, CONSULT sven@ethdev.com BEFOREHAND!!
# DO NOT CHANGE ANYTHING HERE!
if(APPLE)
ExternalProject_Add(json-rpc-cpp
# DEPENDS argtable2 jsoncpp
# DEPENDS curl # re-enable later, when we build curl again
GIT_REPOSITORY https://github.com/cinemast/libjson-rpc-cpp.git
GIT_TAG v0.3.2
BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp
CONFIGURE_COMMAND cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR}/cmake -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST -Wno-dev .
BUILD_COMMAND make -j 3
INSTALL_COMMAND make install && ${CMAKE_CURRENT_SOURCE_DIR}/scripts/json-rpc-cpp_osx.sh . ${ETH_DEPENDENCY_INSTALL_DIR}
)
elseif (WIN32)
ExternalProject_Add(json-rpc-cpp
DEPENDS argtable2 jsoncpp curl
GIT_REPOSITORY https://github.com/debris/libjson-rpc-cpp.git
GIT_TAG windows
BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp
CONFIGURE_COMMAND cmake -DCMAKE_PREFIX_PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCURL_LIBRARIES=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libcurl.lib .
BUILD_COMMAND devenv libjson-rpc-cpp.sln /build release
INSTALL_COMMAND cmd /c cp lib/Release/* ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp -R src/jsonrpccpp ${ETH_DEPENDENCY_INSTALL_DIR}/include
)
else()
ExternalProject_Add(json-rpc-cpp
# DEPENDS argtable2 jsoncpp
# DEPENDS curl # re-enable later, when we build curl again
GIT_REPOSITORY https://github.com/cinemast/libjson-rpc-cpp.git
GIT_TAG v0.3.2
BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp
CONFIGURE_COMMAND cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR}/cmake -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST .
BUILD_COMMAND make -j 3
INSTALL_COMMAND make install
)
endif()

16
extdep/compile/jsoncpp.cmake

@ -0,0 +1,16 @@
if (APPLE)
elseif (WIN32)
file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/include/jsoncpp)
ExternalProject_Add(jsoncpp
GIT_REPOSITORY https://github.com/open-source-parsers/jsoncpp
GIT_TAG svn-import
BINARY_DIR jsoncpp-prefix/src/jsoncpp
CONFIGURE_COMMAND cmake .
BUILD_COMMAND devenv jsoncpp.sln /build release
INSTALL_COMMAND cmd /c cp lib/Release/jsoncpp.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp -R include/json ${ETH_DEPENDENCY_INSTALL_DIR}/include/jsoncpp
)
else()
endif()

23
extdep/compile/leveldb.cmake

@ -0,0 +1,23 @@
if (APPLE)
ExternalProject_Add(leveldb
#DEPENDS snappy
URL https://leveldb.googlecode.com/files/leveldb-1.15.0.tar.gz
BINARY_DIR leveldb-prefix/src/leveldb
#CONFIGURE_COMMAND patch < ${CMAKE_CURRENT_SOURCE_DIR}/compile/leveldb_osx.patch
CONFIGURE_COMMAND ""
BUILD_COMMAND export ETH_DEPENDENCY_INSTALL_DIR=${ETH_DEPENDENCY_INSTALL_DIR} && make -j 3
INSTALL_COMMAND cp -rf include/leveldb ${ETH_DEPENDENCY_INSTALL_DIR}/include/ && cp libleveldb.a ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp libleveldb.dylib.1.15 ${ETH_DEPENDENCY_INSTALL_DIR}/lib/libleveldb.dylib
)
elseif (WIN32)
ExternalProject_Add(leveldb
GIT_REPOSITORY https://github.com/debris/leveldb-win32.git
GIT_TAG master
BINARY_DIR leveldb-prefix/src/leveldb
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND cmd /c cp lib/LibLevelDB.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib/leveldb.lib && cp -R include/leveldb ${ETH_DEPENDENCY_INSTALL_DIR}/include
)
else()
endif()

18
extdep/compile/leveldb_osx.patch

@ -0,0 +1,18 @@
--- Makefile 2014-11-07 00:54:05.000000000 +0100
+++ MakefilePatch 2014-11-07 00:56:59.000000000 +0100
@@ -17,11 +17,11 @@
# this file is generated by the previous line to set build flags and sources
include build_config.mk
-CFLAGS += -I. -I./include $(PLATFORM_CCFLAGS) $(OPT)
-CXXFLAGS += -I. -I./include $(PLATFORM_CXXFLAGS) $(OPT)
+CFLAGS += -I. -I./include $(PLATFORM_CCFLAGS) $(OPT)
+CXXFLAGS += -I. -I./include $(PLATFORM_CXXFLAGS) $(OPT) -DSNAPPY -I$(ETH_DEPENDENCY_INSTALL_DIR)/include
-LDFLAGS += $(PLATFORM_LDFLAGS)
-LIBS += $(PLATFORM_LIBS)
+LDFLAGS += $(PLATFORM_LDFLAGS) -L$(ETH_DEPENDENCY_INSTALL_DIR)/lib
+LIBS += $(PLATFORM_LIBS) -lsnappy
LIBOBJECTS = $(SOURCES:.cc=.o)
MEMENVOBJECTS = $(MEMENV_SOURCES:.cc=.o)

32
extdep/compile/qt.cmake

@ -0,0 +1,32 @@
if (APPLE)
ExternalProject_add(qt
URL http://qtmirror.ics.com/pub/qtproject/official_releases/qt/5.3/5.3.2/single/qt-everywhere-opensource-src-5.3.2.tar.gz
BINARY_DIR qt-prefix/src/qt
PATCH_COMMAND patch -d qtmultimedia/src/plugins/avfoundation/mediaplayer < ${CMAKE_CURRENT_SOURCE_DIR}/compile/qt_osx.patch
CONFIGURE_COMMAND ./configure -prefix ${ETH_DEPENDENCY_INSTALL_DIR} -system-zlib -qt-libpng -qt-libjpeg -confirm-license -opensource -nomake tests -release -nomake examples -no-xcb -arch x86_64
BUILD_COMMAND make
INSTALL_COMMAND make install
)
elseif(WIN32)
ExternalProject_Add(qt
DEPENDS icu jom
URL http://qtmirror.ics.com/pub/qtproject/official_releases/qt/5.3/5.3.2/single/qt-everywhere-opensource-src-5.3.2.tar.gz
BINARY_DIR qt-prefix/src/qt
UPDATE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/compile/qt_tools.bat
#PATCH_COMMAND cmake -E copy ${CMAKE_CURRENT_SOURCE_DIR}/compile/qt_configure.bat qtbase/configure.bat
CONFIGURE_COMMAND configure -prefix ${ETH_DEPENDENCY_INSTALL_DIR} -opensource -confirm-license -release -opengl desktop -platform win32-msvc2013 -icu -I ${ETH_DEPENDENCY_INSTALL_DIR}/include -L ${ETH_DEPENDENCY_INSTALL_DIR}/lib -nomake tests -nomake examples
BUILD_COMMAND nmake
INSTALL_COMMAND nmake install
)
ExternalProject_Add_Step(qt configure_paths
COMMAND set PATH=${ETH_DEPENDENCY_INSTALL_DIR}/bin;%cd%/gnuwin32/bin;%cd%/qtbase/bin;%PATH%
DEPENDEES patch
DEPENDERS configure
)
else()
endif()

111
extdep/compile/qt_configure.bat

@ -0,0 +1,111 @@
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::
:: Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
:: Contact: http://www.qt-project.org/legal
::
:: This file is part of the tools applications of the Qt Toolkit.
::
:: $QT_BEGIN_LICENSE:LGPL$
:: Commercial License Usage
:: Licensees holding valid commercial Qt licenses may use this file in
:: accordance with the commercial license agreement provided with the
:: Software or, alternatively, in accordance with the terms contained in
:: a written agreement between you and Digia. For licensing terms and
:: conditions see http://qt.digia.com/licensing. For further information
:: use the contact form at http://qt.digia.com/contact-us.
::
:: GNU Lesser General Public License Usage
:: Alternatively, this file may be used under the terms of the GNU Lesser
:: General Public License version 2.1 as published by the Free Software
:: Foundation and appearing in the file LICENSE.LGPL included in the
:: packaging of this file. Please review the following information to
:: ensure the GNU Lesser General Public License version 2.1 requirements
:: will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
::
:: In addition, as a special exception, Digia gives you certain additional
:: rights. These rights are described in the Digia Qt LGPL Exception
:: version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
::
:: GNU General Public License Usage
:: Alternatively, this file may be used under the terms of the GNU
:: General Public License version 3.0 as published by the Free Software
:: Foundation and appearing in the file LICENSE.GPL included in the
:: packaging of this file. Please review the following information to
:: ensure the GNU General Public License version 3.0 requirements will be
:: met: http://www.gnu.org/copyleft/gpl.html.
::
::
:: $QT_END_LICENSE$
::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
@echo off
set QTSRC=%~dp0
set QTDIR=%CD%
::if not exist %QTSRC%\.gitignore goto sconf
echo Please wait while bootstrapping configure ...
for %%C in (cl.exe icl.exe g++.exe perl.exe) do set %%C=%%~$PATH:C
if "%perl.exe%" == "" (
echo Perl not found in PATH. Aborting. >&2
exit /b 1
)
if not exist mkspecs (
md mkspecs
if errorlevel 1 goto exit
)
perl %QTSRC%bin\syncqt.pl -minimal -module QtCore -outdir %QTDIR% %QTSRC%
if errorlevel 1 goto exit
if not exist tools\configure (
md tools\configure
if errorlevel 1 goto exit
)
cd tools\configure
if errorlevel 1 goto exit
echo #### Generated by configure.bat - DO NOT EDIT! ####> Makefile
echo/>> Makefile
for /f "tokens=3 usebackq" %%V in (`findstr QT_VERSION_STR %QTSRC%\src\corelib\global\qglobal.h`) do @echo QTVERSION = %%~V>> Makefile
if not "%cl.exe%" == "" (
echo CXX = cl>>Makefile
echo EXTRA_CXXFLAGS =>>Makefile
rem This must have a trailing space.
echo QTSRC = %QTSRC% >> Makefile
set tmpl=win32
set make=nmake
) else if not "%icl.exe%" == "" (
echo CXX = icl>>Makefile
echo EXTRA_CXXFLAGS = /Zc:forScope>>Makefile
rem This must have a trailing space.
echo QTSRC = %QTSRC% >> Makefile
set tmpl=win32
set make=nmake
) else if not "%g++.exe%" == "" (
echo CXX = g++>>Makefile
echo EXTRA_CXXFLAGS =>>Makefile
rem This must NOT have a trailing space.
echo QTSRC = %QTSRC:\=/%>> Makefile
set tmpl=mingw
set make=mingw32-make
) else (
echo No suitable compiler found in PATH. Aborting. >&2
cd ..\..
exit /b 1
)
echo/>> Makefile
type %QTSRC%tools\configure\Makefile.%tmpl% >> Makefile
%make%
if errorlevel 1 (cd ..\.. & exit /b 1)
cd ..\..
:conf
configure.exe -srcdir %QTSRC% %*
goto exit
:sconf
%QTSRC%\configure.exe %*
:exit

11
extdep/compile/qt_osx.patch

@ -0,0 +1,11 @@
--- avfmediaplayersession.mm 2014-09-11 12:48:26.000000000 +0200
+++ avfmediaplayersessionPatch.mm 2014-12-01 12:53:14.000000000 +0100
@@ -295,7 +295,7 @@
//AVPlayerItem "status" property value observer.
if (context == AVFMediaPlayerSessionObserverStatusObservationContext)
{
- AVPlayerStatus status = [[change objectForKey:NSKeyValueChangeNewKey] integerValue];
+ AVPlayerStatus status = (AVPlayerStatus)[[change objectForKey:NSKeyValueChangeNewKey] integerValue];
switch (status)
{
//Indicates that the status of the player is not yet known because

2
extdep/compile/qt_tools.bat

@ -0,0 +1,2 @@
rem : import VC environment vars
call "%VS120COMNTOOLS%\..\..\VC\vcvarsall.bat" x86

14
extdep/compile/snappy.cmake

@ -0,0 +1,14 @@
if (APPLE)
ExternalProject_Add(snappy
URL https://snappy.googlecode.com/files/snappy-1.1.1.tar.gz
BINARY_DIR snappy-prefix/src/snappy
CONFIGURE_COMMAND ./configure --disable-dependency-tracking --prefix=${ETH_DEPENDENCY_INSTALL_DIR}
BUILD_COMMAND ""
INSTALL_COMMAND make install
)
elseif(WIN32)
else()
endif()

74
extdep/eth_download.cmake

@ -0,0 +1,74 @@
# this macro requires the following variables to be specified:
#
# ETH_DEPENDENCY_SERVER - server from which dependencies should be downloaded
# ETH_DEPENDENCY_INSTALL_DIR - install location for all dependencies
#
# usage:
#
# eth_download("json-rpc-cpp")
# eth_download("json-rpc-cpp" VERSION "0.3.2")
#
# params:
# VERSION - exact version we want to use
# OSX_SCRIPT - script which will be executed on apple in install phase
# UNIX_SCRIPT - script which will be executed on unix in install phase
# WIN_SCRIPT - script which will be executed on win in install phase
# OSX_SCRIPT, WIN_SCRIPT, UNIX_SCRIPT are taking 2 params:
# $1 is package_source,
# $2 is ETH_DEPENDENCY_INSTALL_DIR
#
# parsing arguments
# http://www.cmake.org/cmake/help/v3.0/module/CMakeParseArguments.html
#
# for macos you may need to specify OSX_SCRIPT with install_name_tool to fix dylib
# http://stackoverflow.com/questions/2985315/using-install-name-tool-whats-going-wrong
#
# TODO:
# check if install_command is handling symlinks correctly on linux and windows
macro(eth_download eth_package_name)
set (extra_macro_args ${ARGN})
set (options)
set (one_value_args VERSION OSX_SCRIPT UNIX_SCRIPT WIN_SCRIPT)
set (multi_value_args)
cmake_parse_arguments (ETH_DOWNLOAD "${options}" "${one_value_args}" "${multi_value_args}" ${extra_macro_args})
if (ETH_DOWNLOAD_VERSION)
set(eth_tar_name "${eth_package_name}-${ETH_DOWNLOAD_VERSION}.tar.gz")
else()
set(eth_tar_name "${eth_package_name}.tar.gz")
endif()
message(STATUS "download path for ${eth_package_name} is : ${ETH_DEPENDENCY_SERVER}/${eth_tar_name}")
# we need that to copy symlinks
# see http://superuser.com/questions/138587/how-to-copy-symbolic-links
if (APPLE)
set (eth_package_copy cp -a . ${ETH_DEPENDENCY_INSTALL_DIR})
set (eth_package_install ${ETH_DOWNLOAD_OSX_SCRIPT})
elseif (UNIX)
set (eth_package_copy cp -a . ${ETH_DEPENDENCY_INSTALL_DIR})
set (eth_package_install ${ETH_DOWNLOAD_UNIX_SCRIPT})
else ()
set (eth_package_copy cmake -E copy_directory . ${ETH_DEPENDENCY_INSTALL_DIR})
set (eth_package_install ${ETH_DOWNLOAD_WIN_SCRIPT})
endif()
if (eth_package_install)
message(STATUS "install script: ${eth_package_install}")
set (eth_package_install ${eth_package_install} . ${ETH_DEPENDENCY_INSTALL_DIR})
else ()
set (eth_package_install echo 0) # cause empty string is not handled properly
endif()
ExternalProject_Add(${eth_package_name}
URL ${ETH_DEPENDENCY_SERVER}/${eth_tar_name}
BINARY_DIR ${eth_package_name}-prefix/src/${eth_package_name}
CONFIGURE_COMMAND ""
BUILD_COMMAND ${eth_package_copy}
INSTALL_COMMAND ${eth_package_install}
)
endmacro()

11
extdep/miniupnpc.cmake

@ -0,0 +1,11 @@
# TODO this file is not used yet, but will be in future
include(ExternalProject)
ExternalProject_Add(miniupnpc
URL http://miniupnp.tuxfamily.org/files/download.php?file=miniupnpc-1.9.20141027.tar.gz
BINARY_DIR miniupnpc-prefix/src/miniupnpc
CONFIGURE_COMMAND ""
BUILD_COMMAND make -j 3
INSTALL_COMMAND make install INSTALLPREFIX=${ETH_DEPENDENCY_INSTALL_DIR}
)

29
extdep/scripts/json-rpc-cpp_osx.sh

@ -0,0 +1,29 @@
#!/bin/bash
ETH_DEPENDENCY_SOURCE_DIR=$1
ETH_DEPENDENCY_INSTALL_DIR=$2
OLD_COMMON_DYLIB="libjsonrpccpp-common.0.dylib"
COMMON_DYLIB=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libjsonrpccpp-common.0.dylib
SERVER_DYLIB=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libjsonrpccpp-server.0.dylib
CLIENT_DYLIB=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libjsonrpccpp-client.0.dylib
# fix bin
STAB_EXEC=${ETH_DEPENDENCY_INSTALL_DIR}/bin/jsonrpcstub
install_name_tool -change ${OLD_COMMON_DYLIB} ${COMMON_DYLIB} ${STAB_EXEC}
# fix common
install_name_tool -id ${COMMON_DYLIB} ${COMMON_DYLIB}
# fix server
install_name_tool -id ${SERVER_DYLIB} ${SERVER_DYLIB}
install_name_tool -change ${OLD_COMMON_DYLIB} ${COMMON_DYLIB} ${SERVER_DYLIB}
# fix client
install_name_tool -id ${CLIENT_DYLIB} ${CLIENT_DYLIB}
install_name_tool -change ${OLD_COMMON_DYLIB} ${COMMON_DYLIB} ${CLIENT_DYLIB}
# TODO fix argtable and jsoncpp once they are downloaded as dependencies

12
extdep/scripts/leveldb_osx.sh

@ -0,0 +1,12 @@
#!/bin/bash
ETH_DEPENDENCY_SOURCE_DIR=$1
ETH_DEPENDENCY_INSTALL_DIR=$2
OLD_SNAPPY_DYLIB="/Users/marekkotewicz/ethereum/cpp-ethereum/extdep/install/darwin/lib/libsnappy.1.dylib"
SNAPPY_DYLIB=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libsnappy.dylib
LEVELDB_DYLIB=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libleveldb.dylib
install_name_tool -id ${LEVELDB_DYLIB} ${LEVELDB_DYLIB}
install_name_tool -change ${OLD_SNAPPY_DYLIB} ${SNAPPY_DYLIB} ${LEVELDB_DYLIB}

8
extdep/scripts/snappy_osx.sh

@ -0,0 +1,8 @@
#!/bin/bash
ETH_DEPENDENCY_SOURCE_DIR=$1
ETH_DEPENDENCY_INSTALL_DIR=$2
SNAPPY_DYLIB=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libsnappy.dylib
install_name_tool -id ${SNAPPY_DYLIB} ${SNAPPY_DYLIB}

117
iethxi/CMakeLists.txt

@ -1,117 +0,0 @@
cmake_policy(SET CMP0015 NEW)
if ("${TARGET_PLATFORM}" STREQUAL "w64")
cmake_policy(SET CMP0020 NEW)
endif ()
set(CMAKE_INCLUDE_CURRENT_DIR ON)
aux_source_directory(. SRC_LIST)
include_directories(..)
link_directories(../libethcore)
link_directories(../libethereum)
link_directories(../libqethereum)
# Find Qt5 for Apple and update src_list for windows
if (APPLE)
# homebrew defaults to qt4 and installs qt5 as 'keg-only'
# which places it into /usr/local/opt insteadof /usr/local.
set(CMAKE_PREFIX_PATH /usr/local/opt/qt5)
include_directories(/usr/local/opt/qt5/include /usr/local/include)
elseif ("${TARGET_PLATFORM}" STREQUAL "w64")
set(SRC_LIST ${SRC_LIST} ../windows/qt_plugin_import.cpp)
elseif (UNIX)
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ";$ENV{QTDIR}/lib/cmake")
endif ()
find_package(Qt5Widgets REQUIRED)
find_package(Qt5Gui REQUIRED)
find_package(Qt5Quick REQUIRED)
find_package(Qt5Qml REQUIRED)
find_package(Qt5Network REQUIRED)
qt5_wrap_ui(ui_Main.h Main.ui)
qt5_add_resources(RESOURCE_ADDED Resources.qrc)
# Set name of binary and add_executable()
if (APPLE)
set(EXECUTEABLE IEthXi)
set(CMAKE_INSTALL_PREFIX ./)
set(BIN_INSTALL_DIR ".")
set(DOC_INSTALL_DIR ".")
set(PROJECT_VERSION "${ETH_VERSION}")
set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME} ${PROJECT_VERSION}")
set(MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_NAME} ${PROJECT_VERSION}")
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME} ${PROJECT_VERSION}")
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}")
set(MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT_YEAR} ${PROJECT_VENDOR}")
set(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_DOMAIN_SECOND}.${PROJECT_DOMAIN_FIRST}")
set(MACOSX_BUNDLE_BUNDLE_NAME ${EXECUTEABLE})
include(BundleUtilities)
add_executable(${EXECUTEABLE} MACOSX_BUNDLE Main.ui ${RESOURCE_ADDED} ${SRC_LIST})
else ()
set(EXECUTEABLE iethxi)
add_executable(${EXECUTEABLE} Main.ui ${RESOURCE_ADDED} ${SRC_LIST})
endif ()
qt5_use_modules(${EXECUTEABLE} Core Gui Widgets Network Quick Qml)
target_link_libraries(${EXECUTEABLE} qethereum ethereum secp256k1 ${CRYPTOPP_LS})
if (APPLE)
if (${ADDFRAMEWORKS})
set_target_properties(${EXECUTEABLE} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/EthereumMacOSXBundleInfo.plist.in")
endif ()
SET_SOURCE_FILES_PROPERTIES(${EXECUTEABLE} PROPERTIES MACOSX_PACKAGE_LOCATION MacOS)
# This is a workaround for when the build-type defaults to Debug, and when a multi-config generator like xcode is used, where the type
# will not be set but defaults to release.
set(generator_lowercase "${CMAKE_GENERATOR}")
string(TOLOWER "${CMAKE_GENERATOR}" generator_lowercase)
if ("${generator_lowercase}" STREQUAL "xcode")
# TODO: Not sure how to resolve this. Possibly \${TARGET_BUILD_DIR}
set(binary_build_dir "${CMAKE_CURRENT_BINARY_DIR}/Debug")
else ()
set(binary_build_dir "${CMAKE_CURRENT_BINARY_DIR}")
endif ()
set(APPS ${binary_build_dir}/${EXECUTEABLE}.app)
# This tool and the next will automatically looked at the linked libraries in order to determine what dependencies are required. Thus, target_link_libaries only needs to add ethereum and secp256k1 (above)
install(CODE "
include(BundleUtilities)
set(BU_CHMOD_BUNDLE_ITEMS 1)
fixup_bundle(\"${APPS}\" \"${BUNDLELIBS}\" \"../libqethereum ../libethereum ../secp256k1\")
" COMPONENT RUNTIME )
if (${ADDFRAMEWORKS})
add_custom_target(addframeworks ALL
COMMAND /usr/local/opt/qt5/bin/macdeployqt ${binary_build_dir}/${EXECUTEABLE}.app
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
DEPENDS ${PROJECT_NAME}
)
endif ()
elseif ("${TARGET_PLATFORM}" STREQUAL "w64")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-keep-inline-dllexport -static-libgcc -static-libstdc++ -static")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-s -Wl,-subsystem,windows -mthreads -L/usr/x86_64-w64-mingw32/plugins/platforms")
target_link_libraries(${EXECUTEABLE} gcc)
target_link_libraries(${EXECUTEABLE} mingw32 qtmain mswsock iphlpapi qwindows shlwapi Qt5PlatformSupport gdi32 comdlg32 oleaut32 imm32 winmm ole32 uuid ws2_32)
target_link_libraries(${EXECUTEABLE} boost_system-mt-s)
target_link_libraries(${EXECUTEABLE} boost_filesystem-mt-s)
target_link_libraries(${EXECUTEABLE} boost_thread_win32-mt-s)
target_link_libraries(${EXECUTEABLE} Qt5PlatformSupport)
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS)
elseif (UNIX)
else ()
target_link_libraries(${EXECUTEABLE} boost_system)
target_link_libraries(${EXECUTEABLE} boost_filesystem)
find_package(Threads REQUIRED)
target_link_libraries(${EXECUTEABLE} ${CMAKE_THREAD_LIBS_INIT})
install( TARGETS ${EXECUTEABLE} RUNTIME DESTINATION bin )
endif ()

38
iethxi/EthereumMacOSXBundleInfo.plist.in

@ -1,38 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
<key>CFBundleGetInfoString</key>
<string>${MACOSX_BUNDLE_INFO_STRING}</string>
<key>CFBundleIconFile</key>
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
<key>CFBundleIdentifier</key>
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLongVersionString</key>
<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
<key>CFBundleName</key>
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>LSRequiresCarbon</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
<key>NSHighResolutionCapable</key>
<true/>
</dict>
</plist>

168
iethxi/Main.ui

@ -1,168 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Main</class>
<widget class="QMainWindow" name="Main">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>562</width>
<height>488</height>
</rect>
</property>
<property name="windowTitle">
<string>Walleth</string>
</property>
<property name="dockNestingEnabled">
<bool>true</bool>
</property>
<property name="dockOptions">
<set>QMainWindow::AllowNestedDocks|QMainWindow::AllowTabbedDocks|QMainWindow::VerticalTabs</set>
</property>
<property name="sizeGripEnabled" stdset="0">
<bool>true</bool>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="fullDisplay">
<item>
<widget class="QLabel" name="balance">
<property name="text">
<string>0 wei</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="peerCount">
<property name="text">
<string>0 peers</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="blockCount">
<property name="text">
<string>1 block</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>562</width>
<height>25</height>
</rect>
</property>
<widget class="QMenu" name="menu_File">
<property name="title">
<string>&amp;File</string>
</property>
<addaction name="quit"/>
</widget>
<widget class="QMenu" name="menu_Network">
<property name="title">
<string>&amp;Network</string>
</property>
<addaction name="upnp"/>
<addaction name="net"/>
<addaction name="connect"/>
</widget>
<widget class="QMenu" name="menu_Tools">
<property name="title">
<string>T&amp;ools</string>
</property>
<addaction name="mine"/>
<addaction name="create"/>
<addaction name="preview"/>
</widget>
<widget class="QMenu" name="menu_Help">
<property name="title">
<string>&amp;Help</string>
</property>
<addaction name="about"/>
</widget>
<addaction name="menu_File"/>
<addaction name="menu_Network"/>
<addaction name="menu_Tools"/>
<addaction name="menu_Help"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<action name="quit">
<property name="text">
<string>&amp;Quit</string>
</property>
</action>
<action name="upnp">
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="text">
<string>Use &amp;UPnP</string>
</property>
</action>
<action name="connect">
<property name="text">
<string>&amp;Connect to Peer...</string>
</property>
</action>
<action name="net">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Enable &amp;Network</string>
</property>
</action>
<action name="mine">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Mine</string>
</property>
</action>
<action name="create">
<property name="text">
<string>&amp;New Address</string>
</property>
</action>
<action name="about">
<property name="text">
<string>&amp;About...</string>
</property>
</action>
<action name="preview">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Preview</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>

59
iethxi/MainWin.cpp

@ -1,59 +0,0 @@
#include <QtNetwork/QNetworkReply>
#include <QtQuick/QQuickView>
#include <QtQml/QQmlContext>
#include <QtQml/QQmlEngine>
#include <QtQml/QtQml>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QInputDialog>
#include <QtGui/QClipboard>
#include <QtCore/QtCore>
#include <libethcore/FileSystem.h>
#include <libethcore/Dagger.h>
#include <libevmcore/Instruction.h>
#include <libethereum/Client.h>
#include <libethereum/EthereumHost.h>
#include "BuildInfo.h"
#include "MainWin.h"
#include "ui_Main.h"
using namespace std;
using namespace eth;
Main::Main(QWidget *parent) :
QObject(parent)
{
/* qRegisterMetaType<eth::u256>("eth::u256");
qRegisterMetaType<eth::KeyPair>("eth::KeyPair");
qRegisterMetaType<eth::Secret>("eth::Secret");
qRegisterMetaType<eth::Address>("eth::Address");
qRegisterMetaType<QmlAccount*>("QmlAccount*");
qRegisterMetaType<QmlEthereum*>("QmlEthereum*");
qmlRegisterType<QmlEthereum>("org.ethereum", 1, 0, "Ethereum");
qmlRegisterType<QmlAccount>("org.ethereum", 1, 0, "Account");
qmlRegisterSingletonType<QmlU256Helper>("org.ethereum", 1, 0, "Balance", QmlEthereum::constructU256Helper);
qmlRegisterSingletonType<QmlKeyHelper>("org.ethereum", 1, 0, "Key", QmlEthereum::constructKeyHelper);
*/
/*
ui->librariesView->setModel(m_libraryMan);
ui->graphsView->setModel(m_graphMan);
*/
// QQmlContext* context = m_view->rootContext();
// context->setContextProperty("u256", new U256Helper(this));
}
Main::~Main()
{
}
// extra bits needed to link on VS
#ifdef _MSC_VER
// include moc file, ofuscated to hide from automoc
#include\
"moc_MainWin.cpp"
#endif

18
iethxi/MainWin.h

@ -1,18 +0,0 @@
#ifndef MAIN_H
#define MAIN_H
#include <QtQml/QQmlApplicationEngine>
class Main: public QObject
{
Q_OBJECT
public:
explicit Main(QWidget *parent = 0);
~Main();
private:
QQmlApplicationEngine* m_view;
};
#endif // MAIN_H

5
iethxi/Resources.qrc

@ -1,5 +0,0 @@
<RCC>
<qresource prefix="/">
<file>Simple.qml</file>
</qresource>
</RCC>

9
iethxi/Simple.qml

@ -1,9 +0,0 @@
import QtQuick.Controls 1.1
ApplicationWindow {
title: "My App"
Button {
text: "Push Me"
anchors.centerIn: parent
}
}

9
iethxi/main.cpp

@ -1,9 +0,0 @@
#include <QtQml/QQmlApplicationEngine>
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QQmlApplicationEngine app(QUrl("qrc:/Simple.qml"));
return a.exec();
}

8
libdevcore/All.h

@ -1,8 +0,0 @@
#pragma once
#include "Common.h"
#include "CommonData.h"
#include "CommonIO.h"
#include "FixedHash.h"
#include "Log.h"
#include "RLP.h"

41
libdevcore/CMakeLists.txt

@ -1,49 +1,42 @@
cmake_policy(SET CMP0015 NEW)
if (CMAKE_MAJOR_VERSION GREATER 1 AND CMAKE_MINOR_VERSION GREATER 7 AND CMAKE_PATCH_VERSION GREATER 11)
cmake_policy(SET CMP0022 NEW)
# this policy was introduced in cmake 3.0
# remove if, once 3.0 will be used on unix
if (${CMAKE_MAJOR_VERSION} GREATER 2)
# old policy do not use MACOSX_RPATH
cmake_policy(SET CMP0042 OLD)
endif()
set(CMAKE_AUTOMOC OFF)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB")
aux_source_directory(. SRC_LIST)
include_directories(${Boost_INCLUDE_DIRS})
include_directories(..)
set(EXECUTABLE devcore)
file(GLOB HEADERS "*.h")
if(ETH_STATIC)
add_library(${EXECUTABLE} STATIC ${SRC_LIST} ${HEADERS})
else()
add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS})
endif()
include_directories(..)
target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARIES})
target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARIES})
target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARIES})
target_link_libraries(${EXECUTABLE} ${Boost_CHRONO_LIBRARIES})
if("${TARGET_PLATFORM}" STREQUAL "w64")
include_directories(/usr/x86_64-w64-mingw32/include/cryptopp)
target_link_libraries(${EXECUTABLE} boost_system-mt-s)
target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s)
target_link_libraries(${EXECUTABLE} iphlpapi)
target_link_libraries(${EXECUTABLE} ws2_32)
target_link_libraries(${EXECUTABLE} mswsock)
target_link_libraries(${EXECUTABLE} shlwapi)
elseif (APPLE)
# Latest mavericks boost libraries only come with -mt
target_link_libraries(${EXECUTABLE} boost_system-mt)
target_link_libraries(${EXECUTABLE} boost_filesystem-mt)
target_link_libraries(${EXECUTABLE} boost_thread-mt)
if (APPLE)
find_package(Threads REQUIRED)
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT})
elseif (UNIX)
find_package(Boost 1.53 REQUIRED COMPONENTS thread system)
target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY} ${Boost_SYSTEM_LIBRARY})
find_package(Threads REQUIRED)
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT})
else ()
target_link_libraries(${EXECUTABLE} boost_thread)
find_package(Threads REQUIRED)
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT})
endif ()
endif()
install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} )

2
libdevcore/Common.cpp

@ -27,7 +27,7 @@ using namespace dev;
namespace dev
{
char const* Version = "0.7.12";
char const* Version = "0.8.0";
}

3
libdevcore/Common.h

@ -74,6 +74,9 @@ using StringMap = std::map<std::string, std::string>;
using u256Map = std::map<u256, u256>;
using HexMap = std::map<bytes, std::string>;
// Fixed-length string types.
using string32 = std::array<char, 32>;
// Null/Invalid values for convenience.
static const u256 Invalid256 = ~(u256)0;
static const bytes NullBytes;

201
libdevcore/CommonData.cpp

@ -14,7 +14,7 @@
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file Common.cpp
/** @file CommonData.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
@ -23,7 +23,8 @@
#include <random>
#include "Exceptions.h"
#include <libdevcore/Log.h>
#include "Log.h"
using namespace std;
using namespace dev;
@ -88,13 +89,25 @@ bytes dev::fromHex(std::string const& _s)
{
ret.push_back(fromHex(_s[s++]));
}
catch (...){ ret.push_back(0); cwarn << boost::current_exception_diagnostic_information(); }
catch (...)
{
ret.push_back(0);
// msvc does not support it
#ifndef BOOST_NO_EXCEPTIONS
cwarn << boost::current_exception_diagnostic_information();
#endif
}
for (unsigned i = s; i < _s.size(); i += 2)
try
{
ret.push_back((byte)(fromHex(_s[i]) * 16 + fromHex(_s[i + 1])));
}
catch (...){ ret.push_back(0); cwarn << boost::current_exception_diagnostic_information(); }
catch (...){
ret.push_back(0);
#ifndef BOOST_NO_EXCEPTIONS
cwarn << boost::current_exception_diagnostic_information();
#endif
}
return ret;
}
@ -110,180 +123,10 @@ bytes dev::asNibbles(std::string const& _s)
return ret;
}
#if 0
/* Following code is copyright 2012-2014 Luke Dashjr
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the standard MIT license. See COPYING for more details.
*/
#include <cstdbool>
#include <cstddef>
#include <cstdint>
#include <cstring>
static const int8_t b58digits_map[] = {
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8,-1,-1,-1,-1,-1,-1,
-1, 9,10,11,12,13,14,15, 16,-1,17,18,19,20,21,-1,
22,23,24,25,26,27,28,29, 30,31,32,-1,-1,-1,-1,-1,
-1,33,34,35,36,37,38,39, 40,41,42,43,-1,44,45,46,
47,48,49,50,51,52,53,54, 55,56,57,-1,-1,-1,-1,-1,
};
bool b58tobin(void *bin, size_t *binszp, const char *b58, size_t b58sz)
{
size_t binsz = *binszp;
const unsigned char *b58u = (void*)b58;
unsigned char *binu = bin;
size_t outisz = (binsz + 3) / 4;
uint32_t outi[outisz];
uint64_t t;
uint32_t c;
size_t i, j;
uint8_t bytesleft = binsz % 4;
uint32_t zeromask = bytesleft ? (0xffffffff << (bytesleft * 8)) : 0;
unsigned zerocount = 0;
if (!b58sz)
b58sz = strlen(b58);
memset(outi, 0, outisz * sizeof(*outi));
// Leading zeros, just count
for (i = 0; i < b58sz && !b58digits_map[b58u[i]]; ++i)
++zerocount;
for ( ; i < b58sz; ++i)
{
if (b58u[i] & 0x80)
// High-bit set on invalid digit
return false;
if (b58digits_map[b58u[i]] == -1)
// Invalid base58 digit
return false;
c = (unsigned)b58digits_map[b58u[i]];
for (j = outisz; j--; )
{
t = ((uint64_t)outi[j]) * 58 + c;
c = (t & 0x3f00000000) >> 32;
outi[j] = t & 0xffffffff;
}
if (c)
// Output number too big (carry to the next int32)
return false;
if (outi[0] & zeromask)
// Output number too big (last int32 filled too far)
return false;
}
j = 0;
switch (bytesleft) {
case 3:
*(binu++) = (outi[0] & 0xff0000) >> 16;
case 2:
*(binu++) = (outi[0] & 0xff00) >> 8;
case 1:
*(binu++) = (outi[0] & 0xff);
++j;
default:
break;
}
for (; j < outisz; ++j)
{
*(binu++) = (outi[j] >> 0x18) & 0xff;
*(binu++) = (outi[j] >> 0x10) & 0xff;
*(binu++) = (outi[j] >> 8) & 0xff;
*(binu++) = (outi[j] >> 0) & 0xff;
}
// Count canonical base58 byte count
binu = bin;
for (i = 0; i < binsz; ++i)
{
if (binu[i])
break;
--*binszp;
}
*binszp += zerocount;
return true;
}
static
bool my_dblsha256(void *hash, const void *data, size_t datasz)
{
uint8_t buf[0x20];
return b58_sha256_impl(buf, data, datasz) && b58_sha256_impl(hash, buf, sizeof(buf));
}
int b58check(const void *bin, size_t binsz, const char *base58str, size_t b58sz)
{
unsigned char buf[32];
const uint8_t *binc = bin;
unsigned i;
if (binsz < 4)
return -4;
if (!my_dblsha256(buf, bin, binsz - 4))
return -2;
if (memcmp(&binc[binsz - 4], buf, 4))
return -1;
// Check number of zeros is correct AFTER verifying checksum (to avoid possibility of accessing base58str beyond the end)
for (i = 0; binc[i] == '\0' && base58str[i] == '1'; ++i)
{} // Just finding the end of zeros, nothing to do in loop
if (binc[i] == '\0' || base58str[i] == '1')
return -3;
return binc[0];
}
static const char b58digits_ordered[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz)
std::string dev::toString(string32 const& _s)
{
const uint8_t *bin = data;
int carry;
size_t i, j, high, zcount = 0;
size_t size;
while (zcount < binsz && !bin[zcount])
++zcount;
size = (binsz - zcount) * 138 / 100 + 1;
uint8_t buf[size];
memset(buf, 0, size);
for (i = zcount, high = size - 1; i < binsz; ++i, high = j)
{
for (carry = bin[i], j = size - 1; (j > high) || carry; --j)
{
carry += 256 * buf[j];
buf[j] = carry % 58;
carry /= 58;
}
}
for (j = 0; j < size && !buf[j]; ++j);
if (*b58sz <= zcount + size - j)
{
*b58sz = zcount + size - j + 1;
return false;
}
if (zcount)
memset(b58, '1', zcount);
for (i = zcount; j < size; ++i, ++j)
b58[i] = b58digits_ordered[buf[j]];
b58[i] = '\0';
*b58sz = i + 1;
return true;
std::string ret;
for (unsigned i = 0; i < 32 && _s[i]; ++i)
ret.push_back(_s[i]);
return ret;
}
#endif

5
libdevcore/CommonData.h

@ -14,7 +14,7 @@
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file Common.h
/** @file CommonData.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*
@ -236,4 +236,7 @@ inline std::set<_T> operator+(std::set<_T> const& _a, std::set<_T> const& _b)
return ret += _b;
}
/// Make normal string from fixed-length string.
std::string toString(string32 const& _s);
}

2
libdevcore/CommonIO.cpp

@ -65,6 +65,8 @@ bytes dev::contents(std::string const& _file)
// get length of file:
is.seekg (0, is.end);
streamoff length = is.tellg();
if (length == 0) // return early, MSVC does not like reading 0 bytes
return {};
is.seekg (0, is.beg);
bytes ret(length);
is.read((char*)ret.data(), length);

60
libdevcore/CommonJS.cpp

@ -54,4 +54,64 @@ bytes unpadded(bytes _b)
return _b;
}
std::string prettyU256(u256 _n)
{
unsigned inc = 0;
std::string raw;
std::ostringstream s;
if (!(_n >> 64))
s << " " << (uint64_t)_n << " (0x" << (uint64_t)_n << ")";
else if (!~(_n >> 64))
s << " " << (int64_t)_n << " (0x" << (int64_t)_n << ")";
else if ((_n >> 160) == 0)
{
Address a = right160(_n);
std::string n = a.abridged();
if (n.empty())
s << "0x" << a;
else
s << n << "(0x" << a.abridged() << ")";
}
else if ((raw = fromRaw((h256)_n, &inc)).size())
return "\"" + raw + "\"" + (inc ? " + " + std::to_string(inc) : "");
else
s << "" << (h256)_n;
return s.str();
}
std::string fromRaw(h256 _n, unsigned* _inc)
{
if (_n)
{
std::string s((char const*)_n.data(), 32);
auto l = s.find_first_of('\0');
if (!l)
return "";
if (l != std::string::npos)
{
auto p = s.find_first_not_of('\0', l);
if (!(p == std::string::npos || (_inc && p == 31)))
return "";
if (_inc)
*_inc = (byte)s[31];
s.resize(l);
}
for (auto i: s)
if (i < 32)
return "";
return s;
}
return "";
}
Address fromString(std::string const& _sn)
{
if (_sn.size() == 40)
return Address(fromHex(_sn));
else
return Address();
}
}

7
libdevcore/CommonJS.h

@ -35,12 +35,12 @@ template <unsigned S> std::string toJS(FixedHash<S> const& _h)
{
return "0x" + toHex(_h.ref());
}
template <unsigned N> std::string toJS(boost::multiprecision::number<boost::multiprecision::cpp_int_backend<N, N, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>> const& _n)
{
return "0x" + toHex(toCompactBigEndian(_n));
}
inline std::string toJS(dev::bytes const& _n)
{
return "0x" + dev::toHex(_n);
@ -49,6 +49,9 @@ inline std::string toJS(dev::bytes const& _n)
bytes jsToBytes(std::string const& _s);
bytes padded(bytes _b, unsigned _l);
bytes unpadded(bytes _s);
std::string prettyU256(u256 _n);
std::string fromRaw(h256 _n, unsigned* _inc = nullptr);
Address fromString(std::string const& _a);
template <unsigned N> FixedHash<N> jsToFixed(std::string const& _s)
{

35
windows/stdafx.cpp → libdevcore/Diff.h

@ -14,8 +14,39 @@
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file stdafx.cpp
* @author Tim Hughes <tim@twistedfury.com>
/** @file Diff.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#pragma once
namespace dev
{
enum class ExistDiff
{
Same,
New,
Dead
};
template <class T>
class Diff
{
public:
Diff() {}
Diff(T _from, T _to): m_from(_from), m_to(_to) {}
T const& from() const { return m_from; }
T const& to() const { return m_to; }
explicit operator bool() const { return m_from != m_to; }
private:
T m_from;
T m_to;
};
}

8
libdevcore/RLP.h

@ -28,10 +28,10 @@
#include <exception>
#include <iostream>
#include <iomanip>
#include <libdevcore/vector_ref.h>
#include <libdevcore/Common.h>
#include <libdevcore/Exceptions.h>
#include <libdevcore/FixedHash.h>
#include "vector_ref.h"
#include "Common.h"
#include "Exceptions.h"
#include "FixedHash.h"
namespace dev
{

2
libdevcore/RangeMask.h

@ -14,7 +14,7 @@
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file EthereumHost.h
/** @file RangeMask.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save