From 59b2824d46c3162cb87e1f076cf7e658620251be Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Tue, 25 Jun 2013 06:59:27 -0700 Subject: [PATCH 1/9] Fix Clang static analysis warnings --- .../modules/beast_core/containers/beast_Array.h | 16 +++++++++++----- .../containers/beast_ArrayAllocationBase.h | 3 ++- .../beast_core/containers/beast_OwnedArray.h | 16 ++++++++++++---- .../containers/beast_ReferenceCountedArray.h | 4 +++- .../beast_core/system/beast_PlatformDefs.h | 15 +++++++++++++-- 5 files changed, 41 insertions(+), 13 deletions(-) diff --git a/Subtrees/beast/modules/beast_core/containers/beast_Array.h b/Subtrees/beast/modules/beast_core/containers/beast_Array.h index 1cec6d7fd..9e8e13e7f 100644 --- a/Subtrees/beast/modules/beast_core/containers/beast_Array.h +++ b/Subtrees/beast/modules/beast_core/containers/beast_Array.h @@ -230,8 +230,14 @@ public: ElementType operator[] (const int index) const { const ScopedLockType lock (getLock()); - return isPositiveAndBelow (index, numUsed) ? data.elements [index] - : ElementType(); + + if (isPositiveAndBelow (index, numUsed)) + { + bassert (data.elements != nullptr); + return data.elements [index]; + } + + return ElementType(); } /** Returns one of the elements in the array, without checking the index passed in. @@ -246,7 +252,7 @@ public: inline ElementType getUnchecked (const int index) const { const ScopedLockType lock (getLock()); - bassert (isPositiveAndBelow (index, numUsed)); + bassert (isPositiveAndBelow (index, numUsed) && data.elements != nullptr); return data.elements [index]; } @@ -262,7 +268,7 @@ public: inline ElementType& getReference (const int index) const noexcept { const ScopedLockType lock (getLock()); - bassert (isPositiveAndBelow (index, numUsed)); + bassert (isPositiveAndBelow (index, numUsed) && data.elements != nullptr); return data.elements [index]; } @@ -383,6 +389,7 @@ public: { const ScopedLockType lock (getLock()); data.ensureAllocatedSize (numUsed + 1); + bassert (data.elements != nullptr); if (isPositiveAndBelow (indexToInsertAt, numUsed)) { @@ -1043,5 +1050,4 @@ private: } }; - #endif // BEAST_ARRAY_BEASTHEADER diff --git a/Subtrees/beast/modules/beast_core/containers/beast_ArrayAllocationBase.h b/Subtrees/beast/modules/beast_core/containers/beast_ArrayAllocationBase.h index 479fb9091..9f1ffe114 100644 --- a/Subtrees/beast/modules/beast_core/containers/beast_ArrayAllocationBase.h +++ b/Subtrees/beast/modules/beast_core/containers/beast_ArrayAllocationBase.h @@ -103,6 +103,8 @@ public: { if (minNumElements > numAllocated) setAllocatedSize ((minNumElements + minNumElements / 2 + 8) & ~7); + + bassert (numAllocated <= 0 || elements != nullptr); } /** Minimises the amount of storage allocated so that it's no more than @@ -129,5 +131,4 @@ private: BEAST_DECLARE_NON_COPYABLE (ArrayAllocationBase) }; - #endif // BEAST_ARRAYALLOCATIONBASE_BEASTHEADER diff --git a/Subtrees/beast/modules/beast_core/containers/beast_OwnedArray.h b/Subtrees/beast/modules/beast_core/containers/beast_OwnedArray.h index e4a13429f..b029269da 100644 --- a/Subtrees/beast/modules/beast_core/containers/beast_OwnedArray.h +++ b/Subtrees/beast/modules/beast_core/containers/beast_OwnedArray.h @@ -124,8 +124,13 @@ public: inline ObjectClass* operator[] (const int index) const noexcept { const ScopedLockType lock (getLock()); - return isPositiveAndBelow (index, numUsed) ? data.elements [index] - : static_cast (nullptr); + if (isPositiveAndBelow (index, numUsed)) + { + bassert (data.elements != nullptr); + return data.elements [index]; + } + + return nullptr; } /** Returns a pointer to the object at this index in the array, without checking whether the index is in-range. @@ -136,7 +141,7 @@ public: inline ObjectClass* getUnchecked (const int index) const noexcept { const ScopedLockType lock (getLock()); - bassert (isPositiveAndBelow (index, numUsed)); + bassert (isPositiveAndBelow (index, numUsed) && data.elements != nullptr); return data.elements [index]; } @@ -243,6 +248,7 @@ public: { const ScopedLockType lock (getLock()); data.ensureAllocatedSize (numUsed + 1); + bassert (data.elements != nullptr); data.elements [numUsed++] = const_cast (newObject); } @@ -274,6 +280,7 @@ public: indexToInsertAt = numUsed; data.ensureAllocatedSize (numUsed + 1); + bassert (data.elements != nullptr); ObjectClass** const e = data.elements + indexToInsertAt; const int numToMove = numUsed - indexToInsertAt; @@ -426,6 +433,7 @@ public: numElementsToAdd = arrayToAddFrom.size() - startIndex; data.ensureAllocatedSize (numUsed + numElementsToAdd); + bassert (data.elements != nullptr); while (--numElementsToAdd >= 0) { @@ -466,6 +474,7 @@ public: numElementsToAdd = arrayToAddFrom.size() - startIndex; data.ensureAllocatedSize (numUsed + numElementsToAdd); + bassert (data.elements != nullptr); while (--numElementsToAdd >= 0) { @@ -861,5 +870,4 @@ private: BEAST_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OwnedArray) }; - #endif // BEAST_OWNEDARRAY_BEASTHEADER diff --git a/Subtrees/beast/modules/beast_core/containers/beast_ReferenceCountedArray.h b/Subtrees/beast/modules/beast_core/containers/beast_ReferenceCountedArray.h index 9010b78fa..b03559170 100644 --- a/Subtrees/beast/modules/beast_core/containers/beast_ReferenceCountedArray.h +++ b/Subtrees/beast/modules/beast_core/containers/beast_ReferenceCountedArray.h @@ -292,6 +292,7 @@ public: { const ScopedLockType lock (getLock()); data.ensureAllocatedSize (numUsed + 1); + bassert (data.elements != nullptr); data.elements [numUsed++] = newObject; if (newObject != nullptr) @@ -322,6 +323,7 @@ public: indexToInsertAt = numUsed; data.ensureAllocatedSize (numUsed + 1); + bassert (data.elements != nullptr); ObjectClass** const e = data.elements + indexToInsertAt; const int numToMove = numUsed - indexToInsertAt; @@ -388,6 +390,7 @@ public: else { data.ensureAllocatedSize (numUsed + 1); + bassert (data.elements != nullptr); data.elements [numUsed++] = newObject; } } @@ -851,5 +854,4 @@ private: int numUsed; }; - #endif // BEAST_REFERENCECOUNTEDARRAY_BEASTHEADER diff --git a/Subtrees/beast/modules/beast_core/system/beast_PlatformDefs.h b/Subtrees/beast/modules/beast_core/system/beast_PlatformDefs.h index dd3ff1051..59b93ba3c 100644 --- a/Subtrees/beast/modules/beast_core/system/beast_PlatformDefs.h +++ b/Subtrees/beast/modules/beast_core/system/beast_PlatformDefs.h @@ -78,6 +78,17 @@ #define beast_breakDebugger { __asm int 3 } #endif +#if BEAST_CLANG && defined (__has_feature) && ! defined (BEAST_ANALYZER_NORETURN) + #if __has_feature (attribute_analyzer_noreturn) + inline void __attribute__((analyzer_noreturn)) beast_assert_noreturn() {} + #define BEAST_ANALYZER_NORETURN beast_assert_noreturn(); + #endif +#endif + +#ifndef BEAST_ANALYZER_NORETURN + #define BEAST_ANALYZER_NORETURN +#endif + //============================================================================== #if BEAST_DEBUG || DOXYGEN @@ -92,9 +103,9 @@ It is only compiled in a debug build, (unless BEAST_LOG_ASSERTIONS is enabled for your build). @see bassert */ - #define bassertfalse { beast_LogCurrentAssertion; if (beast::beast_isRunningUnderDebugger()) beast_breakDebugger; } + #define bassertfalse { beast_LogCurrentAssertion; if (beast::beast_isRunningUnderDebugger()) beast_breakDebugger; BEAST_ANALYZER_NORETURN } - //============================================================================== + //============================================================================== /** Platform-independent assertion macro. This macro gets turned into a no-op when you're building with debugging turned off, so be From fe15cfbf31438dfa8940129b184d61f9ef297612 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Wed, 26 Jun 2013 00:17:09 -0700 Subject: [PATCH 2/9] Use provided names for CountedObject instead of typeid() --- modules/ripple_basics/utility/ripple_CountedObject.h | 2 ++ modules/ripple_data/protocol/ripple_SerializedObject.h | 4 ++++ src/cpp/ripple/Ledger.h | 2 ++ src/cpp/ripple/LedgerProposal.h | 2 ++ src/cpp/ripple/SerializedValidation.h | 2 ++ src/cpp/ripple/Transaction.h | 2 ++ src/cpp/ripple/TransactionEngine.h | 3 +++ src/cpp/ripple/WSConnection.h | 2 ++ src/cpp/ripple/ripple_HashRouter.cpp | 2 ++ src/cpp/ripple/ripple_HashedObject.h | 2 ++ src/cpp/ripple/ripple_InboundLedger.h | 2 ++ src/cpp/ripple/ripple_InfoSub.h | 2 ++ src/cpp/ripple/ripple_LedgerConsensus.h | 2 ++ src/cpp/ripple/ripple_LedgerEntrySet.h | 4 ++++ src/cpp/ripple/ripple_Peer.cpp | 2 ++ src/cpp/ripple/ripple_SHAMap.h | 2 ++ src/cpp/ripple/ripple_SHAMapItem.h | 2 ++ src/cpp/ripple/ripple_SHAMapTreeNode.h | 2 ++ src/cpp/ripple/ripple_SerializedLedger.h | 2 ++ src/cpp/ripple/ripple_SerializedTransaction.h | 2 ++ src/cpp/ripple/ripple_TransactionAcquire.h | 2 ++ 21 files changed, 47 insertions(+) diff --git a/modules/ripple_basics/utility/ripple_CountedObject.h b/modules/ripple_basics/utility/ripple_CountedObject.h index 6cde85059..8aca24a5a 100644 --- a/modules/ripple_basics/utility/ripple_CountedObject.h +++ b/modules/ripple_basics/utility/ripple_CountedObject.h @@ -101,6 +101,8 @@ public: getCounter ().decrement (); } + virtual char const* getCountedObjectName () = 0; + private: class Counter : public CountedObjects::CounterBase { diff --git a/modules/ripple_data/protocol/ripple_SerializedObject.h b/modules/ripple_data/protocol/ripple_SerializedObject.h index bcc4fd426..7fd24396e 100644 --- a/modules/ripple_data/protocol/ripple_SerializedObject.h +++ b/modules/ripple_data/protocol/ripple_SerializedObject.h @@ -12,6 +12,8 @@ class STObject , public CountedObject { public: + char const* getCountedObjectName () { return "STObject"; } + STObject () : mType (NULL) { ; @@ -323,6 +325,8 @@ class STArray , public CountedObject { public: + char const* getCountedObjectName () { return "STArray"; } + typedef boost::ptr_vector vector; typedef boost::ptr_vector::iterator iterator; typedef boost::ptr_vector::const_iterator const_iterator; diff --git a/src/cpp/ripple/Ledger.h b/src/cpp/ripple/Ledger.h index f39c03762..22a97babb 100644 --- a/src/cpp/ripple/Ledger.h +++ b/src/cpp/ripple/Ledger.h @@ -41,6 +41,8 @@ class Ledger , public CountedObject { public: + char const* getCountedObjectName () { return "Ledger"; } + typedef boost::shared_ptr pointer; typedef const boost::shared_ptr& ref; diff --git a/src/cpp/ripple/LedgerProposal.h b/src/cpp/ripple/LedgerProposal.h index 072c2cc50..2e4228bc0 100644 --- a/src/cpp/ripple/LedgerProposal.h +++ b/src/cpp/ripple/LedgerProposal.h @@ -11,6 +11,8 @@ class LedgerProposal : public CountedObject { public: + char const* getCountedObjectName () { return "LedgerProposal"; } + static const uint32 seqLeave = 0xffffffff; // leaving the consensus process typedef boost::shared_ptr pointer; diff --git a/src/cpp/ripple/SerializedValidation.h b/src/cpp/ripple/SerializedValidation.h index a04fd16df..67ce0a771 100644 --- a/src/cpp/ripple/SerializedValidation.h +++ b/src/cpp/ripple/SerializedValidation.h @@ -12,6 +12,8 @@ class SerializedValidation , public CountedObject { public: + char const* getCountedObjectName () { return "SerializedValidation"; } + typedef boost::shared_ptr pointer; typedef const boost::shared_ptr& ref; diff --git a/src/cpp/ripple/Transaction.h b/src/cpp/ripple/Transaction.h index 9543b177b..bb40b1ee1 100644 --- a/src/cpp/ripple/Transaction.h +++ b/src/cpp/ripple/Transaction.h @@ -32,6 +32,8 @@ class Transaction , public CountedObject { public: + char const* getCountedObjectName () { return "Transaction"; } + typedef boost::shared_ptr pointer; typedef const pointer& ref; diff --git a/src/cpp/ripple/TransactionEngine.h b/src/cpp/ripple/TransactionEngine.h index 6d45bbb14..6cb63832e 100644 --- a/src/cpp/ripple/TransactionEngine.h +++ b/src/cpp/ripple/TransactionEngine.h @@ -15,6 +15,9 @@ class TransactionEngine : public CountedObject { +public: + char const* getCountedObjectName () { return "TransactionEngine"; } + private: LedgerEntrySet mNodes; diff --git a/src/cpp/ripple/WSConnection.h b/src/cpp/ripple/WSConnection.h index fbfa63aa9..9b0da61e0 100644 --- a/src/cpp/ripple/WSConnection.h +++ b/src/cpp/ripple/WSConnection.h @@ -24,6 +24,8 @@ class WSConnection , public CountedObject > { public: + char const* getCountedObjectName () { return "WSConnection"; } + typedef typename endpoint_type::connection_type connection; typedef typename boost::shared_ptr connection_ptr; typedef typename boost::weak_ptr weak_connection_ptr; diff --git a/src/cpp/ripple/ripple_HashRouter.cpp b/src/cpp/ripple/ripple_HashRouter.cpp index 22cbea8d9..5772aaedc 100644 --- a/src/cpp/ripple/ripple_HashRouter.cpp +++ b/src/cpp/ripple/ripple_HashRouter.cpp @@ -13,6 +13,8 @@ private: class Entry : public CountedObject { public: + char const* getCountedObjectName () { return "HashRouterEntry"; } + Entry () : mFlags (0) { diff --git a/src/cpp/ripple/ripple_HashedObject.h b/src/cpp/ripple/ripple_HashedObject.h index 5760f2759..4162a7cb3 100644 --- a/src/cpp/ripple/ripple_HashedObject.h +++ b/src/cpp/ripple/ripple_HashedObject.h @@ -36,6 +36,8 @@ class HashedObject : public CountedObject { public: + char const* getCountedObjectName () { return "HashedObject"; } + typedef boost::shared_ptr pointer; typedef pointer const& ref; diff --git a/src/cpp/ripple/ripple_InboundLedger.h b/src/cpp/ripple/ripple_InboundLedger.h index 6768508cc..bc902a661 100644 --- a/src/cpp/ripple/ripple_InboundLedger.h +++ b/src/cpp/ripple/ripple_InboundLedger.h @@ -15,6 +15,8 @@ class InboundLedger , public CountedObject { public: + char const* getCountedObjectName () { return "InboundLedger"; } + typedef boost::shared_ptr pointer; public: diff --git a/src/cpp/ripple/ripple_InfoSub.h b/src/cpp/ripple/ripple_InfoSub.h index 3b926870f..11439817a 100644 --- a/src/cpp/ripple/ripple_InfoSub.h +++ b/src/cpp/ripple/ripple_InfoSub.h @@ -16,6 +16,8 @@ class InfoSub : public CountedObject { public: + char const* getCountedObjectName () { return "InfoSub"; } + typedef boost::shared_ptr pointer; // VFALCO TODO Standardize on the names of weak / strong pointer typedefs. diff --git a/src/cpp/ripple/ripple_LedgerConsensus.h b/src/cpp/ripple/ripple_LedgerConsensus.h index 56f1e76c7..4c4f74aa5 100644 --- a/src/cpp/ripple/ripple_LedgerConsensus.h +++ b/src/cpp/ripple/ripple_LedgerConsensus.h @@ -17,6 +17,8 @@ class LedgerConsensus , public CountedObject { public: + char const* getCountedObjectName () { return "LedgerConsensus"; } + LedgerConsensus (LedgerHash const & prevLCLHash, Ledger::ref previousLedger, uint32 closeTime); int startup (); diff --git a/src/cpp/ripple/ripple_LedgerEntrySet.h b/src/cpp/ripple/ripple_LedgerEntrySet.h index 1b2cc55a8..6bc750f8d 100644 --- a/src/cpp/ripple/ripple_LedgerEntrySet.h +++ b/src/cpp/ripple/ripple_LedgerEntrySet.h @@ -36,6 +36,8 @@ class LedgerEntrySetEntry : public CountedObject { public: + char const* getCountedObjectName () { return "LedgerEntrySetEntry"; } + SLE::pointer mEntry; LedgerEntryAction mAction; int mSeq; @@ -60,6 +62,8 @@ class LedgerEntrySet : public CountedObject { public: + char const* getCountedObjectName () { return "LedgerEntrySet"; } + LedgerEntrySet (Ledger::ref ledger, TransactionEngineParams tep, bool immutable = false) : mLedger (ledger), mParams (tep), mSeq (0), mImmutable (immutable) { diff --git a/src/cpp/ripple/ripple_Peer.cpp b/src/cpp/ripple/ripple_Peer.cpp index ffb26889e..77b372f0b 100644 --- a/src/cpp/ripple/ripple_Peer.cpp +++ b/src/cpp/ripple/ripple_Peer.cpp @@ -24,6 +24,8 @@ class PeerImp : public Peer , public CountedObject { public: + char const* getCountedObjectName () { return "Peer"; } + PeerImp (boost::asio::io_service & io_service, boost::asio::ssl::context & ctx, uint64 peerId, diff --git a/src/cpp/ripple/ripple_SHAMap.h b/src/cpp/ripple/ripple_SHAMap.h index 0ad68daa7..c50548324 100644 --- a/src/cpp/ripple/ripple_SHAMap.h +++ b/src/cpp/ripple/ripple_SHAMap.h @@ -20,6 +20,8 @@ class SHAMap : public CountedObject { public: + char const* getCountedObjectName () { return "SHAMap"; } + typedef boost::shared_ptr pointer; typedef const boost::shared_ptr& ref; diff --git a/src/cpp/ripple/ripple_SHAMapItem.h b/src/cpp/ripple/ripple_SHAMapItem.h index 3cfdbd5e3..c8759a201 100644 --- a/src/cpp/ripple/ripple_SHAMapItem.h +++ b/src/cpp/ripple/ripple_SHAMapItem.h @@ -12,6 +12,8 @@ class SHAMapItem : public CountedObject { public: + char const* getCountedObjectName () { return "SHAMapItem"; } + typedef boost::shared_ptr pointer; typedef const boost::shared_ptr& ref; diff --git a/src/cpp/ripple/ripple_SHAMapTreeNode.h b/src/cpp/ripple/ripple_SHAMapTreeNode.h index 44705dd49..8034b719b 100644 --- a/src/cpp/ripple/ripple_SHAMapTreeNode.h +++ b/src/cpp/ripple/ripple_SHAMapTreeNode.h @@ -21,6 +21,8 @@ class SHAMapTreeNode , public CountedObject { public: + char const* getCountedObjectName () { return "SHAMapTreeNode"; } + typedef boost::shared_ptr pointer; typedef const boost::shared_ptr& ref; diff --git a/src/cpp/ripple/ripple_SerializedLedger.h b/src/cpp/ripple/ripple_SerializedLedger.h index 37984b0ae..fbff0bbf4 100644 --- a/src/cpp/ripple/ripple_SerializedLedger.h +++ b/src/cpp/ripple/ripple_SerializedLedger.h @@ -27,6 +27,8 @@ class SerializedLedgerEntry , public CountedObject { public: + char const* getCountedObjectName () { return "SerializedLedgerEntry"; } + typedef boost::shared_ptr pointer; typedef const boost::shared_ptr& ref; diff --git a/src/cpp/ripple/ripple_SerializedTransaction.h b/src/cpp/ripple/ripple_SerializedTransaction.h index dd17e293f..c70b73e78 100644 --- a/src/cpp/ripple/ripple_SerializedTransaction.h +++ b/src/cpp/ripple/ripple_SerializedTransaction.h @@ -21,6 +21,8 @@ class SerializedTransaction , public CountedObject { public: + char const* getCountedObjectName () { return "SerializedTransaction"; } + typedef boost::shared_ptr pointer; typedef const boost::shared_ptr& ref; diff --git a/src/cpp/ripple/ripple_TransactionAcquire.h b/src/cpp/ripple/ripple_TransactionAcquire.h index 347ae01c8..f679dd19a 100644 --- a/src/cpp/ripple/ripple_TransactionAcquire.h +++ b/src/cpp/ripple/ripple_TransactionAcquire.h @@ -15,6 +15,8 @@ class TransactionAcquire , public CountedObject { public: + char const* getCountedObjectName () { return "TransactionAcquire"; } + typedef boost::shared_ptr pointer; public: From aa92b9cffeb69079d464416cfb1d1ed98b904d6c Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Wed, 26 Jun 2013 00:18:49 -0700 Subject: [PATCH 3/9] Temporarily remove beast_basics from the build --- Builds/VisualStudio2012/RippleD.vcxproj | 7 ++++++- SConstruct | 1 - modules/ripple_basics/ripple_basics.h | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Builds/VisualStudio2012/RippleD.vcxproj b/Builds/VisualStudio2012/RippleD.vcxproj index d43197f18..fb35320f3 100644 --- a/Builds/VisualStudio2012/RippleD.vcxproj +++ b/Builds/VisualStudio2012/RippleD.vcxproj @@ -1494,7 +1494,12 @@ true true - + + true + true + true + true + diff --git a/SConstruct b/SConstruct index 6c1b26dab..505315841 100644 --- a/SConstruct +++ b/SConstruct @@ -104,7 +104,6 @@ INCLUDE_PATHS = [ COMPILED_FILES = [ 'Subtrees/beast/modules/beast_core/beast_core.cpp', - 'Subtrees/beast/modules/beast_basics/beast_basics.cpp', 'modules/ripple_basics/ripple_basics.cpp', 'modules/ripple_core/ripple_core.cpp', 'modules/ripple_data/ripple_data.cpp', diff --git a/modules/ripple_basics/ripple_basics.h b/modules/ripple_basics/ripple_basics.h index 39a11237a..4bcde707c 100644 --- a/modules/ripple_basics/ripple_basics.h +++ b/modules/ripple_basics/ripple_basics.h @@ -73,7 +73,9 @@ #include "BeastConfig.h" // Must come before any Beast includes #include "modules/beast_core/beast_core.h" -#include "modules/beast_basics/beast_basics.h" + +// VFALCO TODO Fix this for FreeBSD +//#include "modules/beast_basics/beast_basics.h" #include "../ripple_json/ripple_json.h" From 1dffaf5d5735e70727acc2a9d67d48c91a8b5a1f Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Wed, 26 Jun 2013 01:10:54 -0700 Subject: [PATCH 4/9] Use manual method for naming CountedObject classes --- .../ripple_basics/utility/ripple_CountedObject.h | 14 +------------- .../ripple_data/protocol/ripple_SerializedObject.h | 4 ++-- src/cpp/ripple/Ledger.h | 2 +- src/cpp/ripple/LedgerProposal.h | 2 +- src/cpp/ripple/SerializedValidation.h | 2 +- src/cpp/ripple/Transaction.h | 2 +- src/cpp/ripple/TransactionEngine.h | 2 +- src/cpp/ripple/WSConnection.h | 2 +- src/cpp/ripple/ripple_HashRouter.cpp | 2 +- src/cpp/ripple/ripple_HashedObject.h | 2 +- src/cpp/ripple/ripple_InboundLedger.h | 2 +- src/cpp/ripple/ripple_InfoSub.h | 2 +- src/cpp/ripple/ripple_LedgerConsensus.h | 2 +- src/cpp/ripple/ripple_LedgerEntrySet.h | 4 ++-- src/cpp/ripple/ripple_Peer.cpp | 2 +- src/cpp/ripple/ripple_SHAMap.h | 2 +- src/cpp/ripple/ripple_SHAMapItem.h | 2 +- src/cpp/ripple/ripple_SHAMapTreeNode.h | 2 +- src/cpp/ripple/ripple_SerializedLedger.h | 2 +- src/cpp/ripple/ripple_SerializedTransaction.h | 2 +- src/cpp/ripple/ripple_TransactionAcquire.h | 2 +- 21 files changed, 23 insertions(+), 35 deletions(-) diff --git a/modules/ripple_basics/utility/ripple_CountedObject.h b/modules/ripple_basics/utility/ripple_CountedObject.h index 8aca24a5a..897eee350 100644 --- a/modules/ripple_basics/utility/ripple_CountedObject.h +++ b/modules/ripple_basics/utility/ripple_CountedObject.h @@ -101,8 +101,6 @@ public: getCounter ().decrement (); } - virtual char const* getCountedObjectName () = 0; - private: class Counter : public CountedObjects::CounterBase { @@ -111,23 +109,13 @@ private: char const* getName () const noexcept { - return getClassName (); + return Object::getCountedObjectName (); } void checkPureVirtual () const { } }; private: - /* Due to a bug in Visual Studio 10 and earlier, the string returned by - typeid().name() will appear to leak on exit. Therefore, we should - only call this function when there's an actual leak, or else there - will be spurious leak notices at exit. - */ - static char const* getClassName () noexcept - { - return typeid (Object).name (); - } - static Counter& getCounter () noexcept { // VFALCO TODO Research the thread safety of static initializers diff --git a/modules/ripple_data/protocol/ripple_SerializedObject.h b/modules/ripple_data/protocol/ripple_SerializedObject.h index 7fd24396e..0e8bd79be 100644 --- a/modules/ripple_data/protocol/ripple_SerializedObject.h +++ b/modules/ripple_data/protocol/ripple_SerializedObject.h @@ -12,7 +12,7 @@ class STObject , public CountedObject { public: - char const* getCountedObjectName () { return "STObject"; } + static char const* getCountedObjectName () { return "STObject"; } STObject () : mType (NULL) { @@ -325,7 +325,7 @@ class STArray , public CountedObject { public: - char const* getCountedObjectName () { return "STArray"; } + static char const* getCountedObjectName () { return "STArray"; } typedef boost::ptr_vector vector; typedef boost::ptr_vector::iterator iterator; diff --git a/src/cpp/ripple/Ledger.h b/src/cpp/ripple/Ledger.h index 22a97babb..714435568 100644 --- a/src/cpp/ripple/Ledger.h +++ b/src/cpp/ripple/Ledger.h @@ -41,7 +41,7 @@ class Ledger , public CountedObject { public: - char const* getCountedObjectName () { return "Ledger"; } + static char const* getCountedObjectName () { return "Ledger"; } typedef boost::shared_ptr pointer; typedef const boost::shared_ptr& ref; diff --git a/src/cpp/ripple/LedgerProposal.h b/src/cpp/ripple/LedgerProposal.h index 2e4228bc0..34b51258f 100644 --- a/src/cpp/ripple/LedgerProposal.h +++ b/src/cpp/ripple/LedgerProposal.h @@ -11,7 +11,7 @@ class LedgerProposal : public CountedObject { public: - char const* getCountedObjectName () { return "LedgerProposal"; } + static char const* getCountedObjectName () { return "LedgerProposal"; } static const uint32 seqLeave = 0xffffffff; // leaving the consensus process diff --git a/src/cpp/ripple/SerializedValidation.h b/src/cpp/ripple/SerializedValidation.h index 67ce0a771..e4aaed02e 100644 --- a/src/cpp/ripple/SerializedValidation.h +++ b/src/cpp/ripple/SerializedValidation.h @@ -12,7 +12,7 @@ class SerializedValidation , public CountedObject { public: - char const* getCountedObjectName () { return "SerializedValidation"; } + static char const* getCountedObjectName () { return "SerializedValidation"; } typedef boost::shared_ptr pointer; typedef const boost::shared_ptr& ref; diff --git a/src/cpp/ripple/Transaction.h b/src/cpp/ripple/Transaction.h index bb40b1ee1..66505c5a7 100644 --- a/src/cpp/ripple/Transaction.h +++ b/src/cpp/ripple/Transaction.h @@ -32,7 +32,7 @@ class Transaction , public CountedObject { public: - char const* getCountedObjectName () { return "Transaction"; } + static char const* getCountedObjectName () { return "Transaction"; } typedef boost::shared_ptr pointer; typedef const pointer& ref; diff --git a/src/cpp/ripple/TransactionEngine.h b/src/cpp/ripple/TransactionEngine.h index 6cb63832e..d643811c6 100644 --- a/src/cpp/ripple/TransactionEngine.h +++ b/src/cpp/ripple/TransactionEngine.h @@ -16,7 +16,7 @@ class TransactionEngine : public CountedObject { public: - char const* getCountedObjectName () { return "TransactionEngine"; } + static char const* getCountedObjectName () { return "TransactionEngine"; } private: LedgerEntrySet mNodes; diff --git a/src/cpp/ripple/WSConnection.h b/src/cpp/ripple/WSConnection.h index 9b0da61e0..29011e668 100644 --- a/src/cpp/ripple/WSConnection.h +++ b/src/cpp/ripple/WSConnection.h @@ -24,7 +24,7 @@ class WSConnection , public CountedObject > { public: - char const* getCountedObjectName () { return "WSConnection"; } + static char const* getCountedObjectName () { return "WSConnection"; } typedef typename endpoint_type::connection_type connection; typedef typename boost::shared_ptr connection_ptr; diff --git a/src/cpp/ripple/ripple_HashRouter.cpp b/src/cpp/ripple/ripple_HashRouter.cpp index 5772aaedc..c11c824e1 100644 --- a/src/cpp/ripple/ripple_HashRouter.cpp +++ b/src/cpp/ripple/ripple_HashRouter.cpp @@ -13,7 +13,7 @@ private: class Entry : public CountedObject { public: - char const* getCountedObjectName () { return "HashRouterEntry"; } + static char const* getCountedObjectName () { return "HashRouterEntry"; } Entry () : mFlags (0) diff --git a/src/cpp/ripple/ripple_HashedObject.h b/src/cpp/ripple/ripple_HashedObject.h index 4162a7cb3..0134af07d 100644 --- a/src/cpp/ripple/ripple_HashedObject.h +++ b/src/cpp/ripple/ripple_HashedObject.h @@ -36,7 +36,7 @@ class HashedObject : public CountedObject { public: - char const* getCountedObjectName () { return "HashedObject"; } + static char const* getCountedObjectName () { return "HashedObject"; } typedef boost::shared_ptr pointer; typedef pointer const& ref; diff --git a/src/cpp/ripple/ripple_InboundLedger.h b/src/cpp/ripple/ripple_InboundLedger.h index bc902a661..b5327ffa4 100644 --- a/src/cpp/ripple/ripple_InboundLedger.h +++ b/src/cpp/ripple/ripple_InboundLedger.h @@ -15,7 +15,7 @@ class InboundLedger , public CountedObject { public: - char const* getCountedObjectName () { return "InboundLedger"; } + static char const* getCountedObjectName () { return "InboundLedger"; } typedef boost::shared_ptr pointer; diff --git a/src/cpp/ripple/ripple_InfoSub.h b/src/cpp/ripple/ripple_InfoSub.h index 11439817a..2aa6fa464 100644 --- a/src/cpp/ripple/ripple_InfoSub.h +++ b/src/cpp/ripple/ripple_InfoSub.h @@ -16,7 +16,7 @@ class InfoSub : public CountedObject { public: - char const* getCountedObjectName () { return "InfoSub"; } + static char const* getCountedObjectName () { return "InfoSub"; } typedef boost::shared_ptr pointer; diff --git a/src/cpp/ripple/ripple_LedgerConsensus.h b/src/cpp/ripple/ripple_LedgerConsensus.h index 4c4f74aa5..30f4eca98 100644 --- a/src/cpp/ripple/ripple_LedgerConsensus.h +++ b/src/cpp/ripple/ripple_LedgerConsensus.h @@ -17,7 +17,7 @@ class LedgerConsensus , public CountedObject { public: - char const* getCountedObjectName () { return "LedgerConsensus"; } + static char const* getCountedObjectName () { return "LedgerConsensus"; } LedgerConsensus (LedgerHash const & prevLCLHash, Ledger::ref previousLedger, uint32 closeTime); diff --git a/src/cpp/ripple/ripple_LedgerEntrySet.h b/src/cpp/ripple/ripple_LedgerEntrySet.h index 6bc750f8d..6f1d9be64 100644 --- a/src/cpp/ripple/ripple_LedgerEntrySet.h +++ b/src/cpp/ripple/ripple_LedgerEntrySet.h @@ -36,7 +36,7 @@ class LedgerEntrySetEntry : public CountedObject { public: - char const* getCountedObjectName () { return "LedgerEntrySetEntry"; } + static char const* getCountedObjectName () { return "LedgerEntrySetEntry"; } SLE::pointer mEntry; LedgerEntryAction mAction; @@ -62,7 +62,7 @@ class LedgerEntrySet : public CountedObject { public: - char const* getCountedObjectName () { return "LedgerEntrySet"; } + static char const* getCountedObjectName () { return "LedgerEntrySet"; } LedgerEntrySet (Ledger::ref ledger, TransactionEngineParams tep, bool immutable = false) : mLedger (ledger), mParams (tep), mSeq (0), mImmutable (immutable) diff --git a/src/cpp/ripple/ripple_Peer.cpp b/src/cpp/ripple/ripple_Peer.cpp index 77b372f0b..279f4757f 100644 --- a/src/cpp/ripple/ripple_Peer.cpp +++ b/src/cpp/ripple/ripple_Peer.cpp @@ -24,7 +24,7 @@ class PeerImp : public Peer , public CountedObject { public: - char const* getCountedObjectName () { return "Peer"; } + static char const* getCountedObjectName () { return "Peer"; } PeerImp (boost::asio::io_service & io_service, boost::asio::ssl::context & ctx, diff --git a/src/cpp/ripple/ripple_SHAMap.h b/src/cpp/ripple/ripple_SHAMap.h index c50548324..c71bdfb92 100644 --- a/src/cpp/ripple/ripple_SHAMap.h +++ b/src/cpp/ripple/ripple_SHAMap.h @@ -20,7 +20,7 @@ class SHAMap : public CountedObject { public: - char const* getCountedObjectName () { return "SHAMap"; } + static char const* getCountedObjectName () { return "SHAMap"; } typedef boost::shared_ptr pointer; typedef const boost::shared_ptr& ref; diff --git a/src/cpp/ripple/ripple_SHAMapItem.h b/src/cpp/ripple/ripple_SHAMapItem.h index c8759a201..a7c8e29f7 100644 --- a/src/cpp/ripple/ripple_SHAMapItem.h +++ b/src/cpp/ripple/ripple_SHAMapItem.h @@ -12,7 +12,7 @@ class SHAMapItem : public CountedObject { public: - char const* getCountedObjectName () { return "SHAMapItem"; } + static char const* getCountedObjectName () { return "SHAMapItem"; } typedef boost::shared_ptr pointer; typedef const boost::shared_ptr& ref; diff --git a/src/cpp/ripple/ripple_SHAMapTreeNode.h b/src/cpp/ripple/ripple_SHAMapTreeNode.h index 8034b719b..2af350e02 100644 --- a/src/cpp/ripple/ripple_SHAMapTreeNode.h +++ b/src/cpp/ripple/ripple_SHAMapTreeNode.h @@ -21,7 +21,7 @@ class SHAMapTreeNode , public CountedObject { public: - char const* getCountedObjectName () { return "SHAMapTreeNode"; } + static char const* getCountedObjectName () { return "SHAMapTreeNode"; } typedef boost::shared_ptr pointer; typedef const boost::shared_ptr& ref; diff --git a/src/cpp/ripple/ripple_SerializedLedger.h b/src/cpp/ripple/ripple_SerializedLedger.h index fbff0bbf4..c92c3a403 100644 --- a/src/cpp/ripple/ripple_SerializedLedger.h +++ b/src/cpp/ripple/ripple_SerializedLedger.h @@ -27,7 +27,7 @@ class SerializedLedgerEntry , public CountedObject { public: - char const* getCountedObjectName () { return "SerializedLedgerEntry"; } + static char const* getCountedObjectName () { return "SerializedLedgerEntry"; } typedef boost::shared_ptr pointer; typedef const boost::shared_ptr& ref; diff --git a/src/cpp/ripple/ripple_SerializedTransaction.h b/src/cpp/ripple/ripple_SerializedTransaction.h index c70b73e78..7c2a8e336 100644 --- a/src/cpp/ripple/ripple_SerializedTransaction.h +++ b/src/cpp/ripple/ripple_SerializedTransaction.h @@ -21,7 +21,7 @@ class SerializedTransaction , public CountedObject { public: - char const* getCountedObjectName () { return "SerializedTransaction"; } + static char const* getCountedObjectName () { return "SerializedTransaction"; } typedef boost::shared_ptr pointer; typedef const boost::shared_ptr& ref; diff --git a/src/cpp/ripple/ripple_TransactionAcquire.h b/src/cpp/ripple/ripple_TransactionAcquire.h index f679dd19a..de057dd96 100644 --- a/src/cpp/ripple/ripple_TransactionAcquire.h +++ b/src/cpp/ripple/ripple_TransactionAcquire.h @@ -15,7 +15,7 @@ class TransactionAcquire , public CountedObject { public: - char const* getCountedObjectName () { return "TransactionAcquire"; } + static char const* getCountedObjectName () { return "TransactionAcquire"; } typedef boost::shared_ptr pointer; From 3556ae5325f7ac12d2a51aaf5514c9bbd4cffb1d Mon Sep 17 00:00:00 2001 From: Alex Dupre Date: Wed, 26 Jun 2013 12:01:22 +0200 Subject: [PATCH 5/9] Use pkg-config for protobuf, it works also on FreeBSD. Do not add sources/headers to OBJECT_FILES. --- SConstruct | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/SConstruct b/SConstruct index 505315841..b63f94d16 100644 --- a/SConstruct +++ b/SConstruct @@ -49,6 +49,8 @@ else: # Use openssl env.ParseConfig('pkg-config --cflags --libs openssl') +# Use protobuf +env.ParseConfig('pkg-config --cflags --libs protobuf') # The required version of boost is documented in the README file. # @@ -143,15 +145,9 @@ if not FreeBSD: ] ) -# Apparently, pkg-config --libs protobuf on bsd fails to provide this necessary include dir. -if FreeBSD: - env.Append(LINKFLAGS = ['-I/usr/local/include']) - env.Append(CXXFLAGS = ['-DOS_FREEBSD']) - env.Append( LIBS = [ 'rt', # for clock_nanosleep in beast - 'protobuf', 'z' ] ) @@ -183,7 +179,7 @@ TAG_SRCS = copy.copy(COMPILED_FILES) # Derive the object files from the source files. OBJECT_FILES = [] -OBJECT_FILES += PROTO_SRCS +OBJECT_FILES.append(PROTO_SRCS[0]) for file in COMPILED_FILES: OBJECT_FILES.append('build/obj/' + file) From d82a68dbbb154a966a48e2376769be45212338ed Mon Sep 17 00:00:00 2001 From: Alex Dupre Date: Wed, 26 Jun 2013 12:02:22 +0200 Subject: [PATCH 6/9] Fix compilation on FreeBSD. --- Subtrees/beast/modules/beast_basics/beast_basics.h | 4 ++-- Subtrees/beast/modules/beast_basics/functor/beast_Bind.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Subtrees/beast/modules/beast_basics/beast_basics.h b/Subtrees/beast/modules/beast_basics/beast_basics.h index 29049bed4..3d509cdcd 100644 --- a/Subtrees/beast/modules/beast_basics/beast_basics.h +++ b/Subtrees/beast/modules/beast_basics/beast_basics.h @@ -280,11 +280,11 @@ # include # endif -#elif BEAST_LINUX +#elif BEAST_LINUX || BEAST_BSD # include #else -# error Unnkown platform! +# error Unknown platform! #endif diff --git a/Subtrees/beast/modules/beast_basics/functor/beast_Bind.h b/Subtrees/beast/modules/beast_basics/functor/beast_Bind.h index ed29b3d47..91b4aca6c 100644 --- a/Subtrees/beast/modules/beast_basics/functor/beast_Bind.h +++ b/Subtrees/beast/modules/beast_basics/functor/beast_Bind.h @@ -71,7 +71,7 @@ using std::tr1::placeholders::_1; using std::tr1::placeholders::_2; #endif -#elif BEAST_LINUX +#elif BEAST_LINUX || BEAST_BSD using std::tr1::bind; using std::tr1::placeholders::_1; using std::tr1::placeholders::_2; From 64075993945d1b7e172366b059cc71df86e11918 Mon Sep 17 00:00:00 2001 From: Alex Dupre Date: Wed, 26 Jun 2013 12:02:41 +0200 Subject: [PATCH 7/9] Fix build on FreeBSD/MacOS, they are POSIX platforms, too. --- modules/ripple_leveldb/ripple_leveldb.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/modules/ripple_leveldb/ripple_leveldb.cpp b/modules/ripple_leveldb/ripple_leveldb.cpp index fcf011da7..ed230e194 100644 --- a/modules/ripple_leveldb/ripple_leveldb.cpp +++ b/modules/ripple_leveldb/ripple_leveldb.cpp @@ -15,16 +15,18 @@ #if BEAST_WIN32 #define LEVELDB_PLATFORM_WINDOWS -#elif BEAST_MAC || BEAST_IOS - #define OS_MACOSX - -// VFALCO TODO Distinguish between BEAST_BSD and BEAST_FREEBSD -#elif BEAST_BSD - #define OS_FREEBSD - #else #define LEVELDB_PLATFORM_POSIX + #if BEAST_MAC || BEAST_IOS + #define OS_MACOSX + + // VFALCO TODO Distinguish between BEAST_BSD and BEAST_FREEBSD + #elif BEAST_BSD + #define OS_FREEBSD + + #endif + #endif #if BEAST_MSVC From a5167c809f5059a86e33d442a33379c830ecbbe6 Mon Sep 17 00:00:00 2001 From: Alex Dupre Date: Wed, 26 Jun 2013 12:03:21 +0200 Subject: [PATCH 8/9] Conditionalize definition of __STDC_LIMIT_MACROS and define it at the top of ripple_websocket.h. --- Subtrees/websocket/src/rng/boost_rng.hpp | 4 +++- modules/ripple_websocket/ripple_websocket.h | 9 ++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Subtrees/websocket/src/rng/boost_rng.hpp b/Subtrees/websocket/src/rng/boost_rng.hpp index 806993708..c87c20e54 100644 --- a/Subtrees/websocket/src/rng/boost_rng.hpp +++ b/Subtrees/websocket/src/rng/boost_rng.hpp @@ -30,7 +30,9 @@ #ifndef BOOST_RNG_HPP #define BOOST_RNG_HPP -#define __STDC_LIMIT_MACROS 1 +#ifndef __STDC_LIMIT_MACROS + #define __STDC_LIMIT_MACROS +#endif #include #include diff --git a/modules/ripple_websocket/ripple_websocket.h b/modules/ripple_websocket/ripple_websocket.h index 0e3b7fb1b..4eeb8c78c 100644 --- a/modules/ripple_websocket/ripple_websocket.h +++ b/modules/ripple_websocket/ripple_websocket.h @@ -21,6 +21,10 @@ @deprecated */ +// needed before inclusion of stdint.h for INT32_MIN/INT32_MAX macros +#ifndef __STDC_LIMIT_MACROS + #define __STDC_LIMIT_MACROS +#endif // VFALCO NOTE Log dependencies have wormed their way into websocketpp, // which needs the ripple_basic module to compile. @@ -38,11 +42,6 @@ //------------------------------------------------------------------------------ -// VFALCO TODO This include is just to prevent a warning about -// redefinition of __STDC_LIMIT_MACROS. Fix it right. -// -#include "websocket/src/rng/boost_rng.hpp" - #include "websocket/src/common.hpp" #include "websocket/src/sockets/socket_base.hpp" From f61c33538b0a7a9833c4946a765cc6c98cc759b7 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Wed, 26 Jun 2013 07:56:00 -0700 Subject: [PATCH 9/9] Add missing native BSD support for Beast --- SConstruct | 9 + .../Builds/VisualStudio2012/beast.vcxproj | 16 + .../VisualStudio2012/beast.vcxproj.filters | 12 + .../beast/modules/beast_core/beast_core.cpp | 7 + .../native/beast_BasicNativeHeaders.h | 9 + .../beast_core/native/beast_bsd_Files.cpp | 373 ++++++++++++++ .../beast_core/native/beast_bsd_Network.cpp | 461 ++++++++++++++++++ .../native/beast_bsd_SystemStats.cpp | 346 +++++++++++++ .../beast_core/native/beast_bsd_Threads.cpp | 85 ++++ .../beast_core/system/beast_StandardHeader.h | 4 +- .../beast_core/system/beast_SystemStats.cpp | 6 +- .../beast_core/system/beast_SystemStats.h | 13 +- 12 files changed, 1330 insertions(+), 11 deletions(-) create mode 100644 Subtrees/beast/modules/beast_core/native/beast_bsd_Files.cpp create mode 100644 Subtrees/beast/modules/beast_core/native/beast_bsd_Network.cpp create mode 100644 Subtrees/beast/modules/beast_core/native/beast_bsd_SystemStats.cpp create mode 100644 Subtrees/beast/modules/beast_core/native/beast_bsd_Threads.cpp diff --git a/SConstruct b/SConstruct index b63f94d16..6d272413a 100644 --- a/SConstruct +++ b/SConstruct @@ -52,6 +52,14 @@ env.ParseConfig('pkg-config --cflags --libs openssl') # Use protobuf env.ParseConfig('pkg-config --cflags --libs protobuf') +# Beast uses kvm on FreeBSD +if FreeBSD: + env.Append ( + LIBS = [ + 'kvm' + ] + ) + # The required version of boost is documented in the README file. # # We whitelist platforms where the non -mt version is linked with pthreads. @@ -59,6 +67,7 @@ env.ParseConfig('pkg-config --cflags --libs protobuf') # If a threading library is included the platform can be whitelisted. # # FreeBSD and Ubuntu non-mt libs do link with pthreads. + if FreeBSD or Ubuntu: env.Append( LIBS = [ diff --git a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj index 04af470a2..5872be298 100644 --- a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj +++ b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj @@ -419,6 +419,22 @@ true true + + true + true + + + true + true + + + true + true + + + true + true + true true diff --git a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters index f2f88ba0b..5a57fbb7e 100644 --- a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters +++ b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters @@ -952,5 +952,17 @@ beast_basics\threads + + beast_core\native + + + beast_core\native + + + beast_core\native + + + beast_core\native + \ No newline at end of file diff --git a/Subtrees/beast/modules/beast_core/beast_core.cpp b/Subtrees/beast/modules/beast_core/beast_core.cpp index 0514b14c5..4bf563e2a 100644 --- a/Subtrees/beast/modules/beast_core/beast_core.cpp +++ b/Subtrees/beast/modules/beast_core/beast_core.cpp @@ -201,6 +201,13 @@ namespace beast #include "native/beast_linux_SystemStats.cpp" #include "native/beast_linux_Threads.cpp" +//============================================================================== +#elif BEAST_BSD +#include "native/beast_bsd_Files.cpp" +#include "native/beast_bsd_Network.cpp" +#include "native/beast_bsd_SystemStats.cpp" +#include "native/beast_bsd_Threads.cpp" + //============================================================================== #elif BEAST_ANDROID #include "native/beast_android_Files.cpp" diff --git a/Subtrees/beast/modules/beast_core/native/beast_BasicNativeHeaders.h b/Subtrees/beast/modules/beast_core/native/beast_BasicNativeHeaders.h index 5af5a11d7..21249d82f 100644 --- a/Subtrees/beast/modules/beast_core/native/beast_BasicNativeHeaders.h +++ b/Subtrees/beast/modules/beast_core/native/beast_BasicNativeHeaders.h @@ -188,8 +188,17 @@ #if BEAST_BSD #include + #include + #include + #include #include #include + #include + #include + + // This has to be in the global namespace + extern char** environ; + #else #include #include diff --git a/Subtrees/beast/modules/beast_core/native/beast_bsd_Files.cpp b/Subtrees/beast/modules/beast_core/native/beast_bsd_Files.cpp new file mode 100644 index 000000000..6487f80fb --- /dev/null +++ b/Subtrees/beast/modules/beast_core/native/beast_bsd_Files.cpp @@ -0,0 +1,373 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + Portions of this file are from JUCE. + Copyright (c) 2013 - Raw Material Software Ltd. + Please visit http://www.juce.com + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +enum +{ + U_ISOFS_SUPER_MAGIC = 0x9660, // linux/iso_fs.h + U_MSDOS_SUPER_MAGIC = 0x4d44, // linux/msdos_fs.h + U_NFS_SUPER_MAGIC = 0x6969, // linux/nfs_fs.h + U_SMB_SUPER_MAGIC = 0x517B // linux/smb_fs.h +}; + +//============================================================================== +bool File::copyInternal (const File& dest) const +{ + FileInputStream in (*this); + + if (dest.deleteFile()) + { + { + FileOutputStream out (dest); + + if (out.failedToOpen()) + return false; + + if (out.writeFromInputStream (in, -1) == getSize()) + return true; + } + + dest.deleteFile(); + } + + return false; +} + +void File::findFileSystemRoots (Array& destArray) +{ + destArray.add (File ("/")); +} + +//============================================================================== +bool File::isOnCDRomDrive() const +{ + struct statfs buf; + + return statfs (getFullPathName().toUTF8(), &buf) == 0 + && buf.f_type == (short) U_ISOFS_SUPER_MAGIC; +} + +bool File::isOnHardDisk() const +{ + struct statfs buf; + + if (statfs (getFullPathName().toUTF8(), &buf) == 0) + { + switch (buf.f_type) + { + case U_ISOFS_SUPER_MAGIC: // CD-ROM + case U_MSDOS_SUPER_MAGIC: // Probably floppy (but could be mounted FAT filesystem) + case U_NFS_SUPER_MAGIC: // Network NFS + case U_SMB_SUPER_MAGIC: // Network Samba + return false; + + default: + // Assume anything else is a hard-disk (but note it could + // be a RAM disk. There isn't a good way of determining + // this for sure) + return true; + } + } + + // Assume so if this fails for some reason + return true; +} + +bool File::isOnRemovableDrive() const +{ + bassertfalse; // xxx not implemented for linux! + return false; +} + +bool File::isHidden() const +{ + return getFileName().startsWithChar ('.'); +} + +//============================================================================== +namespace +{ + File beast_readlink (const String& file, const File& defaultFile) + { + const size_t size = 8192; + HeapBlock buffer; + buffer.malloc (size + 4); + + const size_t numBytes = readlink (file.toUTF8(), buffer, size); + + if (numBytes > 0 && numBytes <= size) + return File (file).getSiblingFile (String::fromUTF8 (buffer, (int) numBytes)); + + return defaultFile; + } +} + +File File::getLinkedTarget() const +{ + return beast_readlink (getFullPathName().toUTF8(), *this); +} + +//============================================================================== +static File resolveXDGFolder (const char* const type, const char* const fallbackFolder) +{ + StringArray confLines; + File ("~/.config/user-dirs.dirs").readLines (confLines); + + for (int i = 0; i < confLines.size(); ++i) + { + const String line (confLines[i].trimStart()); + + if (line.startsWith (type)) + { + // eg. resolve XDG_MUSIC_DIR="$HOME/Music" to /home/user/Music + const File f (line.replace ("$HOME", File ("~").getFullPathName()) + .fromFirstOccurrenceOf ("=", false, false) + .trim().unquoted()); + + if (f.isDirectory()) + return f; + } + } + + return File (fallbackFolder); +} + +const char* const* beast_argv = nullptr; +int beast_argc = 0; + +File File::getSpecialLocation (const SpecialLocationType type) +{ + switch (type) + { + case userHomeDirectory: + { + const char* homeDir = getenv ("HOME"); + + if (homeDir == nullptr) + { + struct passwd* const pw = getpwuid (getuid()); + if (pw != nullptr) + homeDir = pw->pw_dir; + } + + return File (CharPointer_UTF8 (homeDir)); + } + + case userDocumentsDirectory: return resolveXDGFolder ("XDG_DOCUMENTS_DIR", "~"); + case userMusicDirectory: return resolveXDGFolder ("XDG_MUSIC_DIR", "~"); + case userMoviesDirectory: return resolveXDGFolder ("XDG_VIDEOS_DIR", "~"); + case userPicturesDirectory: return resolveXDGFolder ("XDG_PICTURES_DIR", "~"); + case userDesktopDirectory: return resolveXDGFolder ("XDG_DESKTOP_DIR", "~/Desktop"); + case userApplicationDataDirectory: return File ("~"); + case commonApplicationDataDirectory: return File ("/var"); + case globalApplicationsDirectory: return File ("/usr"); + + case tempDirectory: + { + File tmp ("/var/tmp"); + + if (! tmp.isDirectory()) + { + tmp = "/tmp"; + + if (! tmp.isDirectory()) + tmp = File::getCurrentWorkingDirectory(); + } + + return tmp; + } + + case invokedExecutableFile: + if (beast_argv != nullptr && beast_argc > 0) + return File (CharPointer_UTF8 (beast_argv[0])); + // deliberate fall-through... + + case currentExecutableFile: + case currentApplicationFile: + return beast_getExecutableFile(); + + case hostApplicationPath: + return beast_readlink ("/proc/self/exe", beast_getExecutableFile()); + + default: + bassertfalse; // unknown type? + break; + } + + return File::nonexistent; +} + +//============================================================================== +String File::getVersion() const +{ + return String::empty; // xxx not yet implemented +} + +//============================================================================== +bool File::moveToTrash() const +{ + if (! exists()) + return true; + + File trashCan ("~/.Trash"); + + if (! trashCan.isDirectory()) + trashCan = "~/.local/share/Trash/files"; + + if (! trashCan.isDirectory()) + return false; + + return moveFileTo (trashCan.getNonexistentChildFile (getFileNameWithoutExtension(), + getFileExtension())); +} + +//============================================================================== +class DirectoryIterator::NativeIterator::Pimpl +{ +public: + Pimpl (const File& directory, const String& wildCard_) + : parentDir (File::addTrailingSeparator (directory.getFullPathName())), + wildCard (wildCard_), + dir (opendir (directory.getFullPathName().toUTF8())) + { + } + + ~Pimpl() + { + if (dir != nullptr) + closedir (dir); + } + + bool next (String& filenameFound, + bool* const isDir, bool* const isHidden, int64* const fileSize, + Time* const modTime, Time* const creationTime, bool* const isReadOnly) + { + if (dir != nullptr) + { + const char* wildcardUTF8 = nullptr; + + for (;;) + { + struct dirent* const de = readdir (dir); + + if (de == nullptr) + break; + + if (wildcardUTF8 == nullptr) + wildcardUTF8 = wildCard.toUTF8(); + + if (fnmatch (wildcardUTF8, de->d_name, FNM_CASEFOLD) == 0) + { + filenameFound = CharPointer_UTF8 (de->d_name); + + updateStatInfoForFile (parentDir + filenameFound, isDir, fileSize, modTime, creationTime, isReadOnly); + + if (isHidden != nullptr) + *isHidden = filenameFound.startsWithChar ('.'); + + return true; + } + } + } + + return false; + } + +private: + String parentDir, wildCard; + DIR* dir; + + BEAST_DECLARE_NON_COPYABLE (Pimpl) +}; + +DirectoryIterator::NativeIterator::NativeIterator (const File& directory, const String& wildCard) + : pimpl (new DirectoryIterator::NativeIterator::Pimpl (directory, wildCard)) +{ +} + +DirectoryIterator::NativeIterator::~NativeIterator() +{ +} + +bool DirectoryIterator::NativeIterator::next (String& filenameFound, + bool* const isDir, bool* const isHidden, int64* const fileSize, + Time* const modTime, Time* const creationTime, bool* const isReadOnly) +{ + return pimpl->next (filenameFound, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly); +} + + +//============================================================================== +static bool isFileExecutable (const String& filename) +{ + beast_statStruct info; + + return beast_stat (filename, info) + && S_ISREG (info.st_mode) + && access (filename.toUTF8(), X_OK) == 0; +} + +bool Process::openDocument (const String& fileName, const String& parameters) +{ + String cmdString (fileName.replace (" ", "\\ ",false)); + cmdString << " " << parameters; + + if (URL::isProbablyAWebsiteURL (fileName) + || cmdString.startsWithIgnoreCase ("file:") + || URL::isProbablyAnEmailAddress (fileName) + || File::createFileWithoutCheckingPath (fileName).isDirectory() + || ! isFileExecutable (fileName)) + { + // create a command that tries to launch a bunch of likely browsers + const char* const browserNames[] = { "xdg-open", "/etc/alternatives/x-www-browser", "firefox", "mozilla", + "google-chrome", "chromium-browser", "opera", "konqueror" }; + StringArray cmdLines; + + for (int i = 0; i < numElementsInArray (browserNames); ++i) + cmdLines.add (String (browserNames[i]) + " " + cmdString.trim().quoted()); + + cmdString = cmdLines.joinIntoString (" || "); + } + + const char* const argv[4] = { "/bin/sh", "-c", cmdString.toUTF8(), 0 }; + + const int cpid = fork(); + + if (cpid == 0) + { + setsid(); + + // Child process + execve (argv[0], (char**) argv, environ); + exit (0); + } + + return cpid >= 0; +} + +void File::revealToUser() const +{ + if (isDirectory()) + startAsProcess(); + else if (getParentDirectory().exists()) + getParentDirectory().startAsProcess(); +} diff --git a/Subtrees/beast/modules/beast_core/native/beast_bsd_Network.cpp b/Subtrees/beast/modules/beast_core/native/beast_bsd_Network.cpp new file mode 100644 index 000000000..9cc852ca9 --- /dev/null +++ b/Subtrees/beast/modules/beast_core/native/beast_bsd_Network.cpp @@ -0,0 +1,461 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + Portions of this file are from JUCE. + Copyright (c) 2013 - Raw Material Software Ltd. + Please visit http://www.juce.com + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +void MACAddress::findAllAddresses (Array& result) +{ +#if 1 + bassertfalse; // VFALCO TODO Implement for FreeBSD +#else + const int s = socket (AF_INET, SOCK_DGRAM, 0); + if (s != -1) + { + char buf [1024]; + struct ifconf ifc; + ifc.ifc_len = sizeof (buf); + ifc.ifc_buf = buf; + ioctl (s, SIOCGIFCONF, &ifc); + + for (unsigned int i = 0; i < ifc.ifc_len / sizeof (struct ifreq); ++i) + { + struct ifreq ifr; + strcpy (ifr.ifr_name, ifc.ifc_req[i].ifr_name); + + if (ioctl (s, SIOCGIFFLAGS, &ifr) == 0 + && (ifr.ifr_flags & IFF_LOOPBACK) == 0 + && ioctl (s, SIOCGIFHWADDR, &ifr) == 0) + { + result.addIfNotAlreadyThere (MACAddress ((const uint8*) ifr.ifr_hwaddr.sa_data)); + } + } + + close (s); + } +#endif +} + + +bool Process::openEmailWithAttachments (const String& /* targetEmailAddress */, + const String& /* emailSubject */, + const String& /* bodyText */, + const StringArray& /* filesToAttach */) +{ + bassertfalse; // xxx todo + + return false; +} + + +//============================================================================== +class WebInputStream : public InputStream +{ +public: + WebInputStream (const String& address_, bool isPost_, const MemoryBlock& postData_, + URL::OpenStreamProgressCallback* progressCallback, void* progressCallbackContext, + const String& headers_, int timeOutMs_, StringPairArray* responseHeaders) + : socketHandle (-1), levelsOfRedirection (0), + address (address_), headers (headers_), postData (postData_), position (0), + finished (false), isPost (isPost_), timeOutMs (timeOutMs_) + { + createConnection (progressCallback, progressCallbackContext); + + if (responseHeaders != nullptr && ! isError()) + { + for (int i = 0; i < headerLines.size(); ++i) + { + const String& headersEntry = headerLines[i]; + const String key (headersEntry.upToFirstOccurrenceOf (": ", false, false)); + const String value (headersEntry.fromFirstOccurrenceOf (": ", false, false)); + const String previousValue ((*responseHeaders) [key]); + responseHeaders->set (key, previousValue.isEmpty() ? value : (previousValue + "," + value)); + } + } + } + + ~WebInputStream() + { + closeSocket(); + } + + //============================================================================== + bool isError() const { return socketHandle < 0; } + bool isExhausted() { return finished; } + int64 getPosition() { return position; } + + int64 getTotalLength() + { + //xxx to do + return -1; + } + + int read (void* buffer, int bytesToRead) + { + if (finished || isError()) + return 0; + + fd_set readbits; + FD_ZERO (&readbits); + FD_SET (socketHandle, &readbits); + + struct timeval tv; + tv.tv_sec = bmax (1, timeOutMs / 1000); + tv.tv_usec = 0; + + if (select (socketHandle + 1, &readbits, 0, 0, &tv) <= 0) + return 0; // (timeout) + + const int bytesRead = bmax (0, (int) recv (socketHandle, buffer, bytesToRead, MSG_WAITALL)); + if (bytesRead == 0) + finished = true; + position += bytesRead; + return bytesRead; + } + + bool setPosition (int64 wantedPos) + { + if (isError()) + return false; + + if (wantedPos != position) + { + finished = false; + + if (wantedPos < position) + { + closeSocket(); + position = 0; + createConnection (0, 0); + } + + skipNextBytes (wantedPos - position); + } + + return true; + } + + //============================================================================== +private: + int socketHandle, levelsOfRedirection; + StringArray headerLines; + String address, headers; + MemoryBlock postData; + int64 position; + bool finished; + const bool isPost; + const int timeOutMs; + + void closeSocket() + { + if (socketHandle >= 0) + close (socketHandle); + + socketHandle = -1; + levelsOfRedirection = 0; + } + + void createConnection (URL::OpenStreamProgressCallback* progressCallback, void* progressCallbackContext) + { + closeSocket(); + + uint32 timeOutTime = Time::getMillisecondCounter(); + + if (timeOutMs == 0) + timeOutTime += 60000; + else if (timeOutMs < 0) + timeOutTime = 0xffffffff; + else + timeOutTime += timeOutMs; + + String hostName, hostPath; + int hostPort; + if (! decomposeURL (address, hostName, hostPath, hostPort)) + return; + + String serverName, proxyName, proxyPath; + int proxyPort = 0; + int port = 0; + + const String proxyURL (getenv ("http_proxy")); + if (proxyURL.startsWithIgnoreCase ("http://")) + { + if (! decomposeURL (proxyURL, proxyName, proxyPath, proxyPort)) + return; + + serverName = proxyName; + port = proxyPort; + } + else + { + serverName = hostName; + port = hostPort; + } + + struct addrinfo hints; + zerostruct (hints); + + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_NUMERICSERV; + + struct addrinfo* result = nullptr; + if (getaddrinfo (serverName.toUTF8(), String (port).toUTF8(), &hints, &result) != 0 || result == 0) + return; + + socketHandle = socket (result->ai_family, result->ai_socktype, 0); + + if (socketHandle == -1) + { + freeaddrinfo (result); + return; + } + + int receiveBufferSize = 16384; + setsockopt (socketHandle, SOL_SOCKET, SO_RCVBUF, (char*) &receiveBufferSize, sizeof (receiveBufferSize)); + setsockopt (socketHandle, SOL_SOCKET, SO_KEEPALIVE, 0, 0); + + #if BEAST_MAC + setsockopt (socketHandle, SOL_SOCKET, SO_NOSIGPIPE, 0, 0); + #endif + + if (connect (socketHandle, result->ai_addr, result->ai_addrlen) == -1) + { + closeSocket(); + freeaddrinfo (result); + return; + } + + freeaddrinfo (result); + + { + const MemoryBlock requestHeader (createRequestHeader (hostName, hostPort, proxyName, proxyPort, + hostPath, address, headers, postData, isPost)); + + if (! sendHeader (socketHandle, requestHeader, timeOutTime, progressCallback, progressCallbackContext)) + { + closeSocket(); + return; + } + } + + String responseHeader (readResponse (socketHandle, timeOutTime)); + + if (responseHeader.isNotEmpty()) + { + headerLines = StringArray::fromLines (responseHeader); + + const int statusCode = responseHeader.fromFirstOccurrenceOf (" ", false, false) + .substring (0, 3).getIntValue(); + + //int contentLength = findHeaderItem (lines, "Content-Length:").getIntValue(); + //bool isChunked = findHeaderItem (lines, "Transfer-Encoding:").equalsIgnoreCase ("chunked"); + + String location (findHeaderItem (headerLines, "Location:")); + + if (statusCode >= 300 && statusCode < 400 && location.isNotEmpty()) + { + if (! location.startsWithIgnoreCase ("http://")) + location = "http://" + location; + + if (++levelsOfRedirection <= 3) + { + address = location; + createConnection (progressCallback, progressCallbackContext); + return; + } + } + else + { + levelsOfRedirection = 0; + return; + } + } + + closeSocket(); + } + + //============================================================================== + static String readResponse (const int socketHandle, const uint32 timeOutTime) + { + int bytesRead = 0, numConsecutiveLFs = 0; + MemoryBlock buffer (1024, true); + + while (numConsecutiveLFs < 2 && bytesRead < 32768 + && Time::getMillisecondCounter() <= timeOutTime) + { + fd_set readbits; + FD_ZERO (&readbits); + FD_SET (socketHandle, &readbits); + + struct timeval tv; + tv.tv_sec = bmax (1, (int) (timeOutTime - Time::getMillisecondCounter()) / 1000); + tv.tv_usec = 0; + + if (select (socketHandle + 1, &readbits, 0, 0, &tv) <= 0) + return String::empty; // (timeout) + + buffer.ensureSize (bytesRead + 8, true); + char* const dest = (char*) buffer.getData() + bytesRead; + + if (recv (socketHandle, dest, 1, 0) == -1) + return String::empty; + + const char lastByte = *dest; + ++bytesRead; + + if (lastByte == '\n') + ++numConsecutiveLFs; + else if (lastByte != '\r') + numConsecutiveLFs = 0; + } + + const String header (CharPointer_UTF8 ((const char*) buffer.getData())); + + if (header.startsWithIgnoreCase ("HTTP/")) + return header.trimEnd(); + + return String::empty; + } + + static void writeValueIfNotPresent (MemoryOutputStream& dest, const String& headers, const String& key, const String& value) + { + if (! headers.containsIgnoreCase (key)) + dest << "\r\n" << key << ' ' << value; + } + + static void writeHost (MemoryOutputStream& dest, const bool isPost, const String& path, const String& host, const int port) + { + dest << (isPost ? "POST " : "GET ") << path << " HTTP/1.0\r\nHost: " << host; + + if (port > 0) + dest << ':' << port; + } + + static MemoryBlock createRequestHeader (const String& hostName, const int hostPort, + const String& proxyName, const int proxyPort, + const String& hostPath, const String& originalURL, + const String& userHeaders, const MemoryBlock& postData, + const bool isPost) + { + MemoryOutputStream header; + + if (proxyName.isEmpty()) + writeHost (header, isPost, hostPath, hostName, hostPort); + else + writeHost (header, isPost, originalURL, proxyName, proxyPort); + + writeValueIfNotPresent (header, userHeaders, "User-Agent:", "BEAST/" BEAST_STRINGIFY(BEAST_MAJOR_VERSION) + "." BEAST_STRINGIFY(BEAST_MINOR_VERSION) + "." BEAST_STRINGIFY(BEAST_BUILDNUMBER)); + writeValueIfNotPresent (header, userHeaders, "Connection:", "Close"); + + if (isPost) + writeValueIfNotPresent (header, userHeaders, "Content-Length:", String ((int) postData.getSize())); + + header << "\r\n" << userHeaders + << "\r\n" << postData; + + return header.getMemoryBlock(); + } + + static bool sendHeader (int socketHandle, const MemoryBlock& requestHeader, const uint32 timeOutTime, + URL::OpenStreamProgressCallback* progressCallback, void* progressCallbackContext) + { + size_t totalHeaderSent = 0; + + while (totalHeaderSent < requestHeader.getSize()) + { + if (Time::getMillisecondCounter() > timeOutTime) + return false; + + const int numToSend = bmin (1024, (int) (requestHeader.getSize() - totalHeaderSent)); + + if (send (socketHandle, static_cast (requestHeader.getData()) + totalHeaderSent, numToSend, 0) != numToSend) + return false; + + totalHeaderSent += numToSend; + + if (progressCallback != nullptr && ! progressCallback (progressCallbackContext, totalHeaderSent, requestHeader.getSize())) + return false; + } + + return true; + } + + static bool decomposeURL (const String& url, String& host, String& path, int& port) + { + if (! url.startsWithIgnoreCase ("http://")) + return false; + + const int nextSlash = url.indexOfChar (7, '/'); + int nextColon = url.indexOfChar (7, ':'); + if (nextColon > nextSlash && nextSlash > 0) + nextColon = -1; + + if (nextColon >= 0) + { + host = url.substring (7, nextColon); + + if (nextSlash >= 0) + port = url.substring (nextColon + 1, nextSlash).getIntValue(); + else + port = url.substring (nextColon + 1).getIntValue(); + } + else + { + port = 80; + + if (nextSlash >= 0) + host = url.substring (7, nextSlash); + else + host = url.substring (7); + } + + if (nextSlash >= 0) + path = url.substring (nextSlash); + else + path = "/"; + + return true; + } + + static String findHeaderItem (const StringArray& lines, const String& itemName) + { + for (int i = 0; i < lines.size(); ++i) + if (lines[i].startsWithIgnoreCase (itemName)) + return lines[i].substring (itemName.length()).trim(); + + return String::empty; + } + + BEAST_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WebInputStream) +}; + +InputStream* URL::createNativeStream (const String& address, bool isPost, const MemoryBlock& postData, + OpenStreamProgressCallback* progressCallback, void* progressCallbackContext, + const String& headers, const int timeOutMs, StringPairArray* responseHeaders) +{ + ScopedPointer wi (new WebInputStream (address, isPost, postData, + progressCallback, progressCallbackContext, + headers, timeOutMs, responseHeaders)); + + return wi->isError() ? nullptr : wi.release(); +} diff --git a/Subtrees/beast/modules/beast_core/native/beast_bsd_SystemStats.cpp b/Subtrees/beast/modules/beast_core/native/beast_bsd_SystemStats.cpp new file mode 100644 index 000000000..613ca1529 --- /dev/null +++ b/Subtrees/beast/modules/beast_core/native/beast_bsd_SystemStats.cpp @@ -0,0 +1,346 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + Portions of this file are from JUCE. + Copyright (c) 2013 - Raw Material Software Ltd. + Please visit http://www.juce.com + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +// sysinfo() from sysinfo-bsd +// https://code.google.com/p/sysinfo-bsd/ +/* + * Copyright (C) 2010 Kostas Petrikas, All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name(s) of the author(s) may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#define SI_LOAD_SHIFT 16 +struct sysinfo { + long uptime; /* Seconds since boot */ + unsigned long loads[3]; /* 1, 5, and 15 minute load averages */ + unsigned long totalram; /* Total usable main memory size */ + unsigned long freeram; /* Available memory size */ + unsigned long sharedram; /* Amount of shared memory */ + unsigned long bufferram; /* Memory used by buffers */ + unsigned long totalswap; /* Total swap space size */ + unsigned long freeswap; /* swap space still available */ + unsigned short procs; /* Number of current processes */ + unsigned short pad; /* leaving this for linux compatability */ + unsigned long totalhigh; /* Total high memory size */ + unsigned long freehigh; /* Available high memory size */ + unsigned int mem_unit; /* Memory unit size in bytes */ + char _f[20-2*sizeof(long)-sizeof(int)]; /* leaving this for linux compatability */ +}; + +#define NLOADS 3 +#define UNIT_S 1024 /*Kb*/ +#define R_IGNORE -1 + +/*the macros*/ +#define R_ERROR(_EC) {if(_EC > R_IGNORE)errno = _EC; return -1;} +#define GETSYSCTL(name, var) getsysctl((char*)name, &(var), sizeof(var)) +#define PAGE_2_UNIT(_PAGE) (((double)_PAGE * page_s) / UNIT_S) + +/*sysctl wrapper*/ +static int getsysctl(char *name, void *ptr, size_t len){ + size_t nlen = len; + if (sysctlbyname(name, ptr, &nlen, NULL, 0) == -1) + return -1; + + if (nlen != len) + return -1; + + return 0; +} + +int sysinfo(struct sysinfo *info){ + kvm_t *kvmh; + double load_avg[NLOADS]; + int page_s = getpagesize(); + + if (info == NULL) + R_ERROR(EFAULT); + + memset(info, 0, sizeof(struct sysinfo)); + info -> mem_unit = UNIT_S; + + /*kvm init*/ + if ((kvmh = kvm_open(NULL, "/dev/null", "/dev/null", + O_RDONLY, "kvm_open")) == NULL) + R_ERROR(0); + + /*load averages*/ + if (kvm_getloadavg(kvmh, load_avg, NLOADS) == -1) + R_ERROR(0); + + info -> loads[0] = (u_long)((float)load_avg[0] * USHRT_MAX); + info -> loads[1] = (u_long)((float)load_avg[1] * USHRT_MAX); + info -> loads[2] = (u_long)((float)load_avg[2] * USHRT_MAX); + + /*swap space*/ + struct kvm_swap k_swap; + + if (kvm_getswapinfo(kvmh, &k_swap, 1, 0) == -1) + R_ERROR(0); + + info -> totalswap = + (u_long)PAGE_2_UNIT(k_swap.ksw_total); + info -> freeswap = info -> totalswap - + (u_long)PAGE_2_UNIT(k_swap.ksw_used); + + /*processes*/ + int n_procs; + + if (kvm_getprocs(kvmh, KERN_PROC_ALL, 0, &n_procs) == NULL) + R_ERROR(0); + + info -> procs = (u_short)n_procs; + + /*end of kvm session*/ + if (kvm_close(kvmh) == -1) + R_ERROR(0); + + /*uptime*/ + struct timespec ts; + + if (clock_gettime(CLOCK_UPTIME, &ts) == -1) + R_ERROR(R_IGNORE); + + info -> uptime = (long)ts.tv_sec; + + /*ram*/ + int total_pages, + free_pages, + active_pages, + inactive_pages; + u_long shmmax; + + if (GETSYSCTL("vm.stats.vm.v_page_count", total_pages) == -1) + R_ERROR(R_IGNORE); + if (GETSYSCTL("vm.stats.vm.v_free_count", free_pages) == -1) + R_ERROR(R_IGNORE); + if (GETSYSCTL("vm.stats.vm.v_active_count", active_pages) == -1) + R_ERROR(R_IGNORE); + if (GETSYSCTL("vm.stats.vm.v_inactive_count", inactive_pages) == -1) + R_ERROR(R_IGNORE); + if (GETSYSCTL("kern.ipc.shmmax", shmmax) == -1) + R_ERROR(R_IGNORE); + + info -> totalram = (u_long)PAGE_2_UNIT(total_pages); + info -> freeram = (u_long)PAGE_2_UNIT(free_pages); + info -> bufferram = (u_long)PAGE_2_UNIT(active_pages); + info -> sharedram = shmmax / UNIT_S; + + /*high mem (todo)*/ + info -> totalhigh = 0; /*Does this supose to refer to HMA or reserved ram?*/ + info -> freehigh = 0; + + return 0; +} + +//============================================================================== + +void Logger::outputDebugString (const String& text) +{ + std::cerr << text << std::endl; +} + +//============================================================================== +SystemStats::OperatingSystemType SystemStats::getOperatingSystemType() +{ + return FreeBSD; +} + +String SystemStats::getOperatingSystemName() +{ + return "FreeBSD"; +} + +bool SystemStats::isOperatingSystem64Bit() + +{ + #if BEAST_64BIT + return true; + #else + //xxx not sure how to find this out?.. + return false; + #endif +} + +//============================================================================== +namespace BSDStatsHelpers +{ + String getCpuInfo (const char* const key) + { + StringArray lines; + File ("/proc/cpuinfo").readLines (lines); + + for (int i = lines.size(); --i >= 0;) // (NB - it's important that this runs in reverse order) + if (lines[i].startsWithIgnoreCase (key)) + return lines[i].fromFirstOccurrenceOf (":", false, false).trim(); + + return String::empty; + } +} + +String SystemStats::getCpuVendor() +{ + return BSDStatsHelpers::getCpuInfo ("vendor_id"); +} + +int SystemStats::getCpuSpeedInMegaherz() +{ + return roundToInt (BSDStatsHelpers::getCpuInfo ("cpu MHz").getFloatValue()); +} + +int SystemStats::getMemorySizeInMegabytes() +{ + struct sysinfo sysi; + + if (sysinfo (&sysi) == 0) + return (sysi.totalram * sysi.mem_unit / (1024 * 1024)); + + return 0; +} + +int SystemStats::getPageSize() +{ + return sysconf (_SC_PAGESIZE); +} + +//============================================================================== +String SystemStats::getLogonName() +{ + const char* user = getenv ("USER"); + + if (user == nullptr) + { + struct passwd* const pw = getpwuid (getuid()); + if (pw != nullptr) + user = pw->pw_name; + } + + return CharPointer_UTF8 (user); +} + +String SystemStats::getFullUserName() +{ + return getLogonName(); +} + +String SystemStats::getComputerName() +{ + char name [256] = { 0 }; + if (gethostname (name, sizeof (name) - 1) == 0) + return name; + + return String::empty; +} + +String getLocaleValue (nl_item key) +{ + const char* oldLocale = ::setlocale (LC_ALL, ""); + return String (const_cast (nl_langinfo (key))); + ::setlocale (LC_ALL, oldLocale); +} + +String SystemStats::getUserLanguage() +{ + return "Uknown user language"; +} + +String SystemStats::getUserRegion() +{ + return "Unknown user region"; +} + +String SystemStats::getDisplayLanguage() +{ + return getUserLanguage(); +} + +//============================================================================== +SystemStats::CPUFlags::CPUFlags() +{ + const String flags (BSDStatsHelpers::getCpuInfo ("flags")); + hasMMX = flags.contains ("mmx"); + hasSSE = flags.contains ("sse"); + hasSSE2 = flags.contains ("sse2"); + has3DNow = flags.contains ("3dnow"); + + numCpus = BSDStatsHelpers::getCpuInfo ("processor").getIntValue() + 1; +} + +//============================================================================== +uint32 beast_millisecondsSinceStartup() noexcept +{ + timespec t; + clock_gettime (CLOCK_MONOTONIC, &t); + + return t.tv_sec * 1000 + t.tv_nsec / 1000000; +} + +int64 Time::getHighResolutionTicks() noexcept +{ + timespec t; + clock_gettime (CLOCK_MONOTONIC, &t); + + return (t.tv_sec * (int64) 1000000) + (t.tv_nsec / 1000); +} + +int64 Time::getHighResolutionTicksPerSecond() noexcept +{ + return 1000000; // (microseconds) +} + +double Time::getMillisecondCounterHiRes() noexcept +{ + return getHighResolutionTicks() * 0.001; +} + +bool Time::setSystemTimeToThisTime() const +{ + timeval t; + t.tv_sec = millisSinceEpoch / 1000; + t.tv_usec = (millisSinceEpoch - t.tv_sec * 1000) * 1000; + + return settimeofday (&t, 0) == 0; +} diff --git a/Subtrees/beast/modules/beast_core/native/beast_bsd_Threads.cpp b/Subtrees/beast/modules/beast_core/native/beast_bsd_Threads.cpp new file mode 100644 index 000000000..5ce0db555 --- /dev/null +++ b/Subtrees/beast/modules/beast_core/native/beast_bsd_Threads.cpp @@ -0,0 +1,85 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + Portions of this file are from JUCE. + Copyright (c) 2013 - Raw Material Software Ltd. + Please visit http://www.juce.com + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +/* + Note that a lot of methods that you'd expect to find in this file actually + live in beast_posix_SharedCode.h! +*/ + +//============================================================================== +void Process::setPriority (const ProcessPriority prior) +{ + const int policy = (prior <= NormalPriority) ? SCHED_OTHER : SCHED_RR; + const int minp = sched_get_priority_min (policy); + const int maxp = sched_get_priority_max (policy); + + struct sched_param param; + + switch (prior) + { + case LowPriority: + case NormalPriority: param.sched_priority = 0; break; + case HighPriority: param.sched_priority = minp + (maxp - minp) / 4; break; + case RealtimePriority: param.sched_priority = minp + (3 * (maxp - minp) / 4); break; + default: bassertfalse; break; + } + + pthread_setschedparam (pthread_self(), policy, ¶m); +} + +void Process::terminate() +{ + exit (0); +} + +BEAST_API bool BEAST_CALLTYPE beast_isRunningUnderDebugger() +{ + static char testResult = 0; + + if (testResult == 0) + { + testResult = (char) ptrace (PT_TRACE_ME, 0, 0, 0); + + if (testResult >= 0) + { + ptrace (PT_DETACH, 0, (caddr_t) 1, 0); + testResult = 1; + } + } + + return testResult < 0; +} + +BEAST_API bool BEAST_CALLTYPE Process::isRunningUnderDebugger() +{ + return beast_isRunningUnderDebugger(); +} + +static void swapUserAndEffectiveUser() +{ + (void) setreuid (geteuid(), getuid()); + (void) setregid (getegid(), getgid()); +} + +void Process::raisePrivilege() { if (geteuid() != 0 && getuid() == 0) swapUserAndEffectiveUser(); } +void Process::lowerPrivilege() { if (geteuid() == 0 && getuid() != 0) swapUserAndEffectiveUser(); } diff --git a/Subtrees/beast/modules/beast_core/system/beast_StandardHeader.h b/Subtrees/beast/modules/beast_core/system/beast_StandardHeader.h index ce4e4f7ef..1c7114275 100644 --- a/Subtrees/beast/modules/beast_core/system/beast_StandardHeader.h +++ b/Subtrees/beast/modules/beast_core/system/beast_StandardHeader.h @@ -27,7 +27,7 @@ //============================================================================== /** Current BEAST version number. - See also SystemStats::getBEASTVersion() for a string version. + See also SystemStats::getBeastVersion() for a string version. */ #define BEAST_MAJOR_VERSION 0 #define BEAST_MINOR_VERSION 0 @@ -39,7 +39,7 @@ Bits 8 to 16 = minor version. Bits 0 to 8 = point release. - See also SystemStats::getBEASTVersion() for a string version. + See also SystemStats::getBeastVersion() for a string version. */ #define BEAST_VERSION ((BEAST_MAJOR_VERSION << 16) + (BEAST_MINOR_VERSION << 8) + BEAST_BUILDNUMBER) diff --git a/Subtrees/beast/modules/beast_core/system/beast_SystemStats.cpp b/Subtrees/beast/modules/beast_core/system/beast_SystemStats.cpp index 07a8b43c8..81d3b5e1c 100644 --- a/Subtrees/beast/modules/beast_core/system/beast_SystemStats.cpp +++ b/Subtrees/beast/modules/beast_core/system/beast_SystemStats.cpp @@ -27,7 +27,7 @@ const SystemStats::CPUFlags& SystemStats::getCPUFlags() return cpuFlags; } -String SystemStats::getBEASTVersion() +String SystemStats::getBeastVersion() { // Some basic tests, to keep an eye on things and make sure these types work ok // on all platforms. Let me know if any of these assertions fail on your system! @@ -41,7 +41,7 @@ String SystemStats::getBEASTVersion() static_bassert (sizeof (int64) == 8); static_bassert (sizeof (uint64) == 8); - return "BEAST v" BEAST_STRINGIFY(BEAST_MAJOR_VERSION) + return "Beast v" BEAST_STRINGIFY(BEAST_MAJOR_VERSION) "." BEAST_STRINGIFY(BEAST_MINOR_VERSION) "." BEAST_STRINGIFY(BEAST_BUILDNUMBER); } @@ -55,7 +55,7 @@ String SystemStats::getBEASTVersion() { BeastVersionPrinter() { - DBG (SystemStats::getBEASTVersion()); + DBG (SystemStats::getBeastVersion()); } }; diff --git a/Subtrees/beast/modules/beast_core/system/beast_SystemStats.h b/Subtrees/beast/modules/beast_core/system/beast_SystemStats.h index 761f7c91b..16f004ea4 100644 --- a/Subtrees/beast/modules/beast_core/system/beast_SystemStats.h +++ b/Subtrees/beast/modules/beast_core/system/beast_SystemStats.h @@ -26,7 +26,6 @@ #include "../text/beast_StringArray.h" - //============================================================================== /** Contains methods for finding out about the current hardware and OS configuration. @@ -38,7 +37,7 @@ public: /** Returns the current version of BEAST, See also the BEAST_VERSION, BEAST_MAJOR_VERSION and BEAST_MINOR_VERSION macros. */ - static String getBEASTVersion(); + static String getBeastVersion(); //============================================================================== /** The set of possible results of the getOperatingSystemType() method. */ @@ -46,16 +45,16 @@ public: { UnknownOS = 0, - Linux = 0x2000, - Android = 0x3000, - iOS = 0x8000, - MacOSX_10_4 = 0x1004, MacOSX_10_5 = 0x1005, MacOSX_10_6 = 0x1006, MacOSX_10_7 = 0x1007, MacOSX_10_8 = 0x1008, + Linux = 0x2000, + FreeBSD = 0x2001, + Android = 0x3000, + Win2000 = 0x4105, WinXP = 0x4106, WinVista = 0x4107, @@ -64,6 +63,8 @@ public: Windows = 0x4000, /**< To test whether any version of Windows is running, you can use the expression ((getOperatingSystemType() & Windows) != 0). */ + + iOS = 0x8000 }; /** Returns the type of operating system we're running on.