summaryrefslogtreecommitdiff
path: root/lib/common
diff options
context:
space:
mode:
Diffstat (limited to 'lib/common')
-rw-r--r--lib/common/Archive.h48
-rw-r--r--lib/common/BannerText.h10
-rw-r--r--lib/common/Box.h63
-rw-r--r--lib/common/BoxConfig-MSVC.h10
-rw-r--r--lib/common/BoxException.h4
-rw-r--r--lib/common/BoxPlatform.h16
-rw-r--r--lib/common/BoxPortsAndFiles.h.in12
-rw-r--r--lib/common/BoxTime.cpp52
-rw-r--r--lib/common/BoxTime.h26
-rw-r--r--lib/common/CommonException.txt13
-rw-r--r--lib/common/Database.h31
-rw-r--r--lib/common/DebugMemLeakFinder.cpp144
-rw-r--r--lib/common/ExcludeList.cpp20
-rw-r--r--lib/common/FdGetLine.cpp64
-rw-r--r--lib/common/FdGetLine.h28
-rw-r--r--lib/common/FileModificationTime.cpp12
-rw-r--r--lib/common/FileModificationTime.h6
-rw-r--r--lib/common/FileStream.cpp81
-rw-r--r--lib/common/GetLine.cpp176
-rw-r--r--lib/common/GetLine.h67
-rw-r--r--lib/common/IOStreamGetLine.cpp34
-rw-r--r--lib/common/IOStreamGetLine.h34
-rw-r--r--lib/common/Logging.cpp79
-rw-r--r--lib/common/Logging.h184
-rw-r--r--lib/common/MainHelper.h21
-rw-r--r--lib/common/MemBlockStream.cpp20
-rw-r--r--lib/common/MemBlockStream.h9
-rw-r--r--lib/common/MemLeakFinder.h13
-rw-r--r--lib/common/RateLimitingStream.cpp95
-rw-r--r--lib/common/RateLimitingStream.h71
-rw-r--r--lib/common/StreamableMemBlock.cpp4
-rw-r--r--lib/common/StreamableMemBlock.h5
-rw-r--r--lib/common/Test.cpp15
-rw-r--r--lib/common/Test.h48
-rw-r--r--lib/common/Timer.cpp227
-rw-r--r--lib/common/Timer.h15
-rw-r--r--lib/common/UnixUser.cpp8
-rw-r--r--lib/common/UnixUser.h4
-rw-r--r--lib/common/Utils.cpp147
-rw-r--r--lib/common/Utils.h5
-rw-r--r--lib/common/ZeroStream.cpp4
-rwxr-xr-xlib/common/makeexception.pl.in4
42 files changed, 1929 insertions, 0 deletions
diff --git a/lib/common/Archive.h b/lib/common/Archive.h
index b70f12c4..139cc5fd 100644
--- a/lib/common/Archive.h
+++ b/lib/common/Archive.h
@@ -45,6 +45,10 @@ public:
{
Write((int) Item);
}
+<<<<<<< HEAD
+=======
+ void WriteExact(uint32_t Item) { Write((int)Item); }
+>>>>>>> 0.12
void Write(int Item)
{
int32_t privItem = htonl(Item);
@@ -55,6 +59,10 @@ public:
int64_t privItem = box_hton64(Item);
mrStream.Write(&privItem, sizeof(privItem));
}
+<<<<<<< HEAD
+=======
+ void WriteExact(uint64_t Item) { Write(Item); }
+>>>>>>> 0.12
void Write(uint64_t Item)
{
uint64_t privItem = box_hton64(Item);
@@ -79,7 +87,11 @@ public:
int privItem;
Read(privItem);
+<<<<<<< HEAD
if (privItem)
+=======
+ if(privItem)
+>>>>>>> 0.12
{
rItemOut = true;
}
@@ -88,6 +100,16 @@ public:
rItemOut = false;
}
}
+<<<<<<< HEAD
+=======
+ void ReadIfPresent(bool &rItemOut, bool ValueIfNotPresent)
+ {
+ int privItem;
+ ReadIfPresent(privItem, ValueIfNotPresent ? 1 : 0);
+ rItemOut = privItem ? true : false;
+ }
+ void ReadExact(uint32_t &rItemOut) { Read((int&)rItemOut); }
+>>>>>>> 0.12
void Read(int &rItemOut)
{
int32_t privItem;
@@ -97,6 +119,28 @@ public:
}
rItemOut = ntohl(privItem);
}
+<<<<<<< HEAD
+=======
+ void ReadIfPresent(int &rItemOut, int ValueIfNotPresent)
+ {
+ int32_t privItem;
+ int bytesRead;
+ if(mrStream.ReadFullBuffer(&privItem, sizeof(privItem), &bytesRead))
+ {
+ rItemOut = ntohl(privItem);
+ }
+ else if(bytesRead == 0)
+ {
+ // item is simply not present
+ rItemOut = ValueIfNotPresent;
+ }
+ else
+ {
+ // bad number of remaining bytes
+ THROW_EXCEPTION(CommonException, ArchiveBlockIncompleteRead)
+ }
+ }
+>>>>>>> 0.12
void Read(int64_t &rItemOut)
{
int64_t privItem;
@@ -106,6 +150,10 @@ public:
}
rItemOut = box_ntoh64(privItem);
}
+<<<<<<< HEAD
+=======
+ void ReadExact(uint64_t &rItemOut) { Read(rItemOut); }
+>>>>>>> 0.12
void Read(uint64_t &rItemOut)
{
uint64_t privItem;
diff --git a/lib/common/BannerText.h b/lib/common/BannerText.h
index e40224da..ae3ff841 100644
--- a/lib/common/BannerText.h
+++ b/lib/common/BannerText.h
@@ -10,9 +10,19 @@
#ifndef BANNERTEXT__H
#define BANNERTEXT__H
+<<<<<<< HEAD
#define BANNER_TEXT(UtilityName) \
"Box " UtilityName " v" BOX_VERSION ", (c) Ben Summers and " \
"contributors 2003-2010"
+=======
+#ifdef NEED_BOX_VERSION_H
+# include "BoxVersion.h"
+#endif
+
+#define BANNER_TEXT(UtilityName) \
+ "Box " UtilityName " v" BOX_VERSION ", (c) Ben Summers and " \
+ "contributors 2003-2011"
+>>>>>>> 0.12
#endif // BANNERTEXT__H
diff --git a/lib/common/Box.h b/lib/common/Box.h
index 158fab7b..91b4967b 100644
--- a/lib/common/Box.h
+++ b/lib/common/Box.h
@@ -17,6 +17,11 @@
#include "BoxPlatform.h"
+<<<<<<< HEAD
+=======
+#include <memory>
+
+>>>>>>> 0.12
// uncomment this line to enable full memory leak finding on all
// malloc-ed blocks (at least, ones used by the STL)
//#define MEMLEAKFINDER_FULL_MALLOC_MONITORING
@@ -38,7 +43,10 @@
#include "Logging.h"
#ifndef BOX_RELEASE_BUILD
+<<<<<<< HEAD
+=======
+>>>>>>> 0.12
extern bool AssertFailuresToSyslog;
#define ASSERT_FAILS_TO_SYSLOG_ON {AssertFailuresToSyslog = true;}
void BoxDebugAssertFailed(const char *cond, const char *file, int line);
@@ -69,7 +77,10 @@
// Exception names
#define EXCEPTION_CODENAMES_EXTENDED
+<<<<<<< HEAD
+=======
+>>>>>>> 0.12
#else
#define ASSERT_FAILS_TO_SYSLOG_ON
#define ASSERT(cond)
@@ -80,9 +91,26 @@
// Box Backup builds release get extra information for exception logging
#define EXCEPTION_CODENAMES_EXTENDED
#define EXCEPTION_CODENAMES_EXTENDED_WITH_DESCRIPTION
+<<<<<<< HEAD
#endif
+=======
+#endif
+
+#if defined DEBUG_LEAKS
+ #ifdef PLATFORM_DISABLE_MEM_LEAK_TESTING
+ #error Compiling with DEBUG_LEAKS enabled, but not supported on this platform
+ #else
+ #define BOX_MEMORY_LEAK_TESTING
+ #endif
+#elif defined BOX_RELEASE_BUILD
+ #ifndef PLATFORM_DISABLE_MEM_LEAK_TESTING
+ #define BOX_MEMORY_LEAK_TESTING
+ #endif
+#endif // DEBUG_LEAKS || BOX_RELEASE_BUILD
+
+>>>>>>> 0.12
#ifdef BOX_MEMORY_LEAK_TESTING
// Memory leak testing
#include "MemLeakFinder.h"
@@ -103,8 +131,23 @@
#define THROW_EXCEPTION(type, subtype) \
{ \
+<<<<<<< HEAD
if(!HideExceptionMessageGuard::ExceptionsHidden()) \
{ \
+=======
+ if((!HideExceptionMessageGuard::ExceptionsHidden() \
+ && !HideSpecificExceptionGuard::IsHidden( \
+ type::ExceptionType, type::subtype)) \
+ || Logging::Guard::IsGuardingFrom(Log::EVERYTHING)) \
+ { \
+ std::auto_ptr<Logging::Guard> guard; \
+ \
+ if(Logging::Guard::IsGuardingFrom(Log::EVERYTHING)) \
+ { \
+ guard.reset(new Logging::Guard(Log::EVERYTHING)); \
+ } \
+ \
+>>>>>>> 0.12
OPTIONAL_DO_BACKTRACE \
BOX_WARNING("Exception thrown: " \
#type "(" #subtype ") " \
@@ -117,12 +160,32 @@
{ \
std::ostringstream _box_throw_line; \
_box_throw_line << message; \
+<<<<<<< HEAD
if(!HideExceptionMessageGuard::ExceptionsHidden()) \
{ \
OPTIONAL_DO_BACKTRACE \
BOX_WARNING("Exception thrown: " \
#type "(" #subtype ") (" << message << \
") at " __FILE__ "(" << __LINE__ << ")") \
+=======
+ if((!HideExceptionMessageGuard::ExceptionsHidden() \
+ && !HideSpecificExceptionGuard::IsHidden( \
+ type::ExceptionType, type::subtype)) \
+ || Logging::Guard::IsGuardingFrom(Log::EVERYTHING)) \
+ { \
+ std::auto_ptr<Logging::Guard> guard; \
+ \
+ if(Logging::Guard::IsGuardingFrom(Log::EVERYTHING)) \
+ { \
+ guard.reset(new Logging::Guard(Log::EVERYTHING)); \
+ } \
+ \
+ OPTIONAL_DO_BACKTRACE \
+ BOX_WARNING("Exception thrown: " \
+ #type "(" #subtype ") (" << \
+ _box_throw_line.str() << \
+ ") at " __FILE__ ":" << __LINE__) \
+>>>>>>> 0.12
} \
throw type(type::subtype, _box_throw_line.str()); \
}
diff --git a/lib/common/BoxConfig-MSVC.h b/lib/common/BoxConfig-MSVC.h
index bb3ffb30..bfa0dcaf 100644
--- a/lib/common/BoxConfig-MSVC.h
+++ b/lib/common/BoxConfig-MSVC.h
@@ -76,6 +76,12 @@
/* Define to 1 if you have the <execinfo.h> header file. */
/* #undef HAVE_EXECINFO_H */
+<<<<<<< HEAD
+=======
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+>>>>>>> 0.12
/* Define to 1 if you have the `flock' function. */
/* #undef HAVE_FLOCK */
@@ -182,7 +188,11 @@
/* Define to 1 if you have the `setproctitle' function. */
/* #undef HAVE_SETPROCTITLE */
+<<<<<<< HEAD
+=======
+#define HAVE_SETPROCTITLE 1
+>>>>>>> 0.12
/* Define to 1 if you have the `setxattr' function. */
/* #undef HAVE_SETXATTR */
diff --git a/lib/common/BoxException.h b/lib/common/BoxException.h
index a8f5d7a6..ad5aba4f 100644
--- a/lib/common/BoxException.h
+++ b/lib/common/BoxException.h
@@ -29,6 +29,10 @@ public:
virtual unsigned int GetType() const throw() = 0;
virtual unsigned int GetSubType() const throw() = 0;
+<<<<<<< HEAD
+=======
+ virtual const std::string& GetMessage() const = 0;
+>>>>>>> 0.12
private:
};
diff --git a/lib/common/BoxPlatform.h b/lib/common/BoxPlatform.h
index 617aa031..2c7ffcf6 100644
--- a/lib/common/BoxPlatform.h
+++ b/lib/common/BoxPlatform.h
@@ -23,7 +23,11 @@
#ifdef _MSC_VER
#include "BoxConfig-MSVC.h"
+<<<<<<< HEAD
#include "BoxVersion.h"
+=======
+#define NEED_BOX_VERSION_H
+>>>>>>> 0.12
#else
#include "BoxConfig.h"
#endif
@@ -159,7 +163,19 @@
#define INFTIM -1
#endif
+<<<<<<< HEAD
// for Unix compatibility with Windows :-)
+=======
+// Define O_BINARY for Unix compatibility with Windows :-)
+// MSVC 2010 and newer MinGW define this in fcntl.h, which is probably
+// not included by this point, so include it now so that we can detect
+// if we need O_BINARY
+
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+>>>>>>> 0.12
#ifndef O_BINARY
#define O_BINARY 0
#endif
diff --git a/lib/common/BoxPortsAndFiles.h.in b/lib/common/BoxPortsAndFiles.h.in
index 41bad0ba..55616da7 100644
--- a/lib/common/BoxPortsAndFiles.h.in
+++ b/lib/common/BoxPortsAndFiles.h.in
@@ -32,12 +32,24 @@
#define BOX_GET_DEFAULT_BBSTORED_CONFIG_FILE \
GetDefaultConfigFilePath("bbstored.conf").c_str()
#else
+<<<<<<< HEAD
#define BOX_FILE_BBACKUPD_DEFAULT_CONFIG "@sysconfdir_expanded@/boxbackup/bbackupd.conf"
#define BOX_FILE_RAIDFILE_DEFAULT_CONFIG "@sysconfdir_expanded@/boxbackup/raidfile.conf"
#define BOX_FILE_BBSTORED_DEFAULT_CONFIG "@sysconfdir_expanded@/boxbackup/bbstored.conf"
#define BOX_FILE_BBACKUPD_OLD_CONFIG "@sysconfdir_expanded@/box/bbackupd.conf"
#define BOX_FILE_RAIDFILE_OLD_CONFIG "@sysconfdir_expanded@/box/raidfile.conf"
#define BOX_FILE_BBSTORED_OLD_CONFIG "@sysconfdir_expanded@/box/bbstored.conf"
+=======
+ #define BOX_FILE_BBACKUPD_OLD_CONFIG "@sysconfdir_expanded@/box/bbackupd.conf"
+ #define BOX_FILE_RAIDFILE_OLD_CONFIG "@sysconfdir_expanded@/box/raidfile.conf"
+ #define BOX_FILE_BBSTORED_OLD_CONFIG "@sysconfdir_expanded@/box/bbstored.conf"
+ #define BOX_GET_DEFAULT_BBACKUPD_CONFIG_FILE \
+ std::string("@sysconfdir_expanded@/boxbackup/bbackupd.conf")
+ #define BOX_GET_DEFAULT_RAIDFILE_CONFIG_FILE \
+ std::string("@sysconfdir_expanded@/boxbackup/raidfile.conf")
+ #define BOX_GET_DEFAULT_BBSTORED_CONFIG_FILE \
+ std::string("@sysconfdir_expanded@/boxbackup/bbstored.conf")
+>>>>>>> 0.12
#endif
#endif // BOXPORTSANDFILES__H
diff --git a/lib/common/BoxTime.cpp b/lib/common/BoxTime.cpp
index d05c0a6c..ead3410b 100644
--- a/lib/common/BoxTime.cpp
+++ b/lib/common/BoxTime.cpp
@@ -94,3 +94,55 @@ std::string FormatTime(box_time_t time, bool includeDate, bool showMicros)
return buf.str();
}
+<<<<<<< HEAD
+=======
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: ShortSleep(box_time_t duration)
+// Purpose: Sleeps for the specified duration as accurately
+// and efficiently as possible.
+// Created: 2011/01/11
+//
+// --------------------------------------------------------------------------
+
+void ShortSleep(box_time_t duration, bool logDuration)
+{
+ if(logDuration)
+ {
+ BOX_TRACE("Sleeping for " << BoxTimeToMicroSeconds(duration) <<
+ " microseconds");
+ }
+
+#ifdef WIN32
+ Sleep(BoxTimeToMilliSeconds(duration));
+#else
+ struct timespec ts;
+ memset(&ts, 0, sizeof(ts));
+ ts.tv_sec = duration / MICRO_SEC_IN_SEC;
+ ts.tv_nsec = duration % MICRO_SEC_IN_SEC;
+
+ while (nanosleep(&ts, &ts) == -1 && errno == EINTR)
+ {
+ // FIXME evil hack for OSX, where ts.tv_sec contains
+ // a negative number interpreted as unsigned 32-bit
+ // when nanosleep() returns later than expected.
+
+ int32_t secs = (int32_t) ts.tv_sec;
+ int64_t remain_ns = ((int64_t)secs * 1000000000) + ts.tv_nsec;
+
+ if (remain_ns < 0)
+ {
+ BOX_WARNING("nanosleep interrupted " <<
+ ((float)(0 - remain_ns) / 1000000000) <<
+ " secs late");
+ return;
+ }
+
+ BOX_TRACE("nanosleep interrupted with " << remain_ns <<
+ " nanosecs remaining, sleeping again");
+ }
+#endif
+}
+
+>>>>>>> 0.12
diff --git a/lib/common/BoxTime.h b/lib/common/BoxTime.h
index 6681bbbd..d688ff10 100644
--- a/lib/common/BoxTime.h
+++ b/lib/common/BoxTime.h
@@ -11,15 +11,25 @@
#define BOXTIME__H
// Time is presented as an unsigned 64 bit integer, in microseconds
+<<<<<<< HEAD
typedef uint64_t box_time_t;
+=======
+typedef int64_t box_time_t;
+>>>>>>> 0.12
#define NANO_SEC_IN_SEC (1000000000LL)
#define NANO_SEC_IN_USEC (1000)
#define NANO_SEC_IN_USEC_LL (1000LL)
#define MICRO_SEC_IN_SEC (1000000)
#define MICRO_SEC_IN_SEC_LL (1000000LL)
+<<<<<<< HEAD
#define MILLI_SEC_IN_NANO_SEC (1000)
#define MILLI_SEC_IN_NANO_SEC_LL (1000LL)
+=======
+#define MICRO_SEC_IN_MILLI_SEC (1000)
+#define MILLI_SEC_IN_SEC (1000)
+#define MILLI_SEC_IN_SEC_LL (1000LL)
+>>>>>>> 0.12
box_time_t GetCurrentBoxTime();
@@ -27,13 +37,24 @@ inline box_time_t SecondsToBoxTime(time_t Seconds)
{
return ((box_time_t)Seconds * MICRO_SEC_IN_SEC_LL);
}
+<<<<<<< HEAD
+=======
+inline uint64_t MilliSecondsToBoxTime(int64_t milliseconds)
+{
+ return ((box_time_t)milliseconds * 1000);
+}
+>>>>>>> 0.12
inline time_t BoxTimeToSeconds(box_time_t Time)
{
return Time / MICRO_SEC_IN_SEC_LL;
}
inline uint64_t BoxTimeToMilliSeconds(box_time_t Time)
{
+<<<<<<< HEAD
return Time / MILLI_SEC_IN_NANO_SEC_LL;
+=======
+ return Time / MILLI_SEC_IN_SEC_LL;
+>>>>>>> 0.12
}
inline uint64_t BoxTimeToMicroSeconds(box_time_t Time)
{
@@ -43,4 +64,9 @@ inline uint64_t BoxTimeToMicroSeconds(box_time_t Time)
std::string FormatTime(box_time_t time, bool includeDate,
bool showMicros = false);
+<<<<<<< HEAD
+=======
+void ShortSleep(box_time_t duration, bool logDuration);
+
+>>>>>>> 0.12
#endif // BOXTIME__H
diff --git a/lib/common/CommonException.txt b/lib/common/CommonException.txt
index b2819886..885a9197 100644
--- a/lib/common/CommonException.txt
+++ b/lib/common/CommonException.txt
@@ -45,3 +45,16 @@ IOStreamGetLineNotEnoughDataToIgnore 37 Bad value passed to IOStreamGetLine::Ign
TempDirPathTooLong 38 Your temporary directory path is too long. Check the TMP and TEMP environment variables.
ArchiveBlockIncompleteRead 39 The Store Object Info File is too short or corrupted, and will be rewritten automatically when the next backup completes.
AccessDenied 40 Access to the file or directory was denied. Please check the permissions.
+<<<<<<< HEAD
+=======
+DatabaseOpenFailed 41 Failed to open the database file
+DatabaseReadFailed 42 Failed to read a record from the database file
+DatabaseWriteFailed 43 Failed to write a record from the database file
+DatabaseDeleteFailed 44 Failed to delete a record from the database file
+DatabaseCloseFailed 45 Failed to close the database file
+DatabaseRecordNotFound 46 The database does not contain the expected record
+DatabaseRecordAlreadyExists 47 The database already contains a record with this key, which was not expected
+DatabaseRecordBadSize 48 The database contains a record with an invalid size
+DatabaseIterateFailed 49 Failed to iterate over the database keys
+ReferenceNotFound 50 The database does not contain an expected reference
+>>>>>>> 0.12
diff --git a/lib/common/Database.h b/lib/common/Database.h
new file mode 100644
index 00000000..94239ab8
--- /dev/null
+++ b/lib/common/Database.h
@@ -0,0 +1,31 @@
+// --------------------------------------------------------------------------
+//
+// File
+// Name: Database.h
+// Purpose: Database (QDBM) utility macros
+// Created: 2010/03/10
+//
+// --------------------------------------------------------------------------
+
+#ifndef DATABASE__H
+#define DATABASE__H
+
+#include "Logging.h"
+
+#define BOX_DBM_MESSAGE(stuff) stuff << " (qdbm): " << dperrmsg(dpecode)
+
+#define BOX_LOG_DBM_ERROR(stuff) \
+ BOX_ERROR(BOX_DBM_MESSAGE(stuff))
+
+#define THROW_DBM_ERROR(message, filename, exception, subtype) \
+ BOX_LOG_DBM_ERROR(message << ": " << filename); \
+ THROW_EXCEPTION_MESSAGE(exception, subtype, \
+ BOX_DBM_MESSAGE(message << ": " << filename));
+
+#define ASSERT_DBM_OK(operation, message, filename, exception, subtype) \
+ if(!(operation)) \
+ { \
+ THROW_DBM_ERROR(message, filename, exception, subtype); \
+ }
+
+#endif // DATABASE__H
diff --git a/lib/common/DebugMemLeakFinder.cpp b/lib/common/DebugMemLeakFinder.cpp
index 72891cd1..ecc4eb12 100644
--- a/lib/common/DebugMemLeakFinder.cpp
+++ b/lib/common/DebugMemLeakFinder.cpp
@@ -7,11 +7,18 @@
//
// --------------------------------------------------------------------------
+<<<<<<< HEAD
#ifndef BOX_RELEASE_BUILD
#include "Box.h"
+=======
+#include "Box.h"
+
+#ifdef BOX_MEMORY_LEAK_TESTING
+
+>>>>>>> 0.12
#undef malloc
#undef realloc
#undef free
@@ -20,11 +27,21 @@
#include <unistd.h>
#endif
+<<<<<<< HEAD
#include <map>
#include <stdio.h>
#include <string.h>
#include <set>
#include <cstdlib> // for std::atexit
+=======
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <cstdlib> // for std::atexit
+#include <map>
+#include <set>
+>>>>>>> 0.12
#include "MemLeakFinder.h"
@@ -73,6 +90,16 @@ namespace
size_t sNotLeaksPreNum = 0;
}
+<<<<<<< HEAD
+=======
+void memleakfinder_report_on_signal(int unused)
+{
+ // this is not safe! do not send SIGUSR1 to a process
+ // in a production environment!
+ memleakfinder_report_usage_summary();
+}
+
+>>>>>>> 0.12
void memleakfinder_init()
{
ASSERT(!memleakfinder_initialised);
@@ -84,6 +111,24 @@ void memleakfinder_init()
}
memleakfinder_initialised = true;
+<<<<<<< HEAD
+=======
+
+ #if defined WIN32
+ // no signals, no way to trigger event yet
+ #else
+ struct sigaction newact, oldact;
+ newact.sa_handler = memleakfinder_report_on_signal;
+ newact.sa_flags = SA_RESTART;
+ sigemptyset(&newact.sa_mask);
+ if (::sigaction(SIGUSR1, &newact, &oldact) != 0)
+ {
+ BOX_ERROR("Failed to install USR1 signal handler");
+ THROW_EXCEPTION(CommonException, Internal);
+ }
+ ASSERT(oldact.sa_handler == 0);
+ #endif // WIN32
+>>>>>>> 0.12
}
MemLeakSuppressionGuard::MemLeakSuppressionGuard()
@@ -141,6 +186,19 @@ void *memleakfinder_malloc(size_t size, const char *file, int line)
return b;
}
+<<<<<<< HEAD
+=======
+void *memleakfinder_calloc(size_t blocks, size_t size, const char *file, int line)
+{
+ void *block = memleakfinder_malloc(blocks * size, file, line);
+ if (block != 0)
+ {
+ memset(block, 0, blocks * size);
+ }
+ return block;
+}
+
+>>>>>>> 0.12
void *memleakfinder_realloc(void *ptr, size_t size)
{
InternalAllocGuard guard;
@@ -346,6 +404,88 @@ int memleakfinder_numleaks()
return n;
}
+<<<<<<< HEAD
+=======
+// Summarise all blocks allocated and still allocated, for memory usage
+// diagnostics.
+void memleakfinder_report_usage_summary()
+{
+ InternalAllocGuard guard;
+
+ ASSERT(!sTrackingDataDestroyed);
+
+ typedef std::map<std::string, std::pair<uint64_t, uint64_t> > usage_map_t;
+ usage_map_t usage;
+
+ for(std::map<void *, MallocBlockInfo>::const_iterator
+ i(sMallocBlocks.begin()); i != sMallocBlocks.end(); ++i)
+ {
+ std::ostringstream buf;
+ buf << i->second.file << ":" << i->second.line;
+ std::string key = buf.str();
+
+ usage_map_t::iterator ui = usage.find(key);
+ if(ui == usage.end())
+ {
+ usage[key] = std::pair<uint64_t, uint64_t>(1,
+ i->second.size);
+ }
+ else
+ {
+ ui->second.first++;
+ ui->second.second += i->second.size;
+ }
+ }
+
+ for(std::map<void *, ObjectInfo>::const_iterator
+ i(sObjectBlocks.begin()); i != sObjectBlocks.end(); ++i)
+ {
+ std::ostringstream buf;
+ buf << i->second.file << ":" << i->second.line;
+ std::string key = buf.str();
+
+ usage_map_t::iterator ui = usage.find(key);
+ if(ui == usage.end())
+ {
+ usage[key] = std::pair<uint64_t, uint64_t>(1,
+ i->second.size);
+ }
+ else
+ {
+ ui->second.first++;
+ ui->second.second += i->second.size;
+ }
+ }
+
+ #ifndef DEBUG_LEAKS
+ BOX_WARNING("Memory use: support not compiled in :(");
+ #else
+ if(usage.empty())
+ {
+ BOX_WARNING("Memory use: none detected?!");
+ }
+ else
+ {
+ uint64_t blocks = 0, bytes = 0;
+ BOX_WARNING("Memory use: report follows");
+
+ for(usage_map_t::iterator i = usage.begin(); i != usage.end();
+ i++)
+ {
+ BOX_WARNING("Memory use: " << i->first << ": " <<
+ i->second.first << " blocks, " <<
+ i->second.second << " bytes");
+ blocks += i->second.first;
+ bytes += i->second.second;
+ }
+
+ BOX_WARNING("Memory use: report ends, total: " << blocks <<
+ " blocks, " << bytes << " bytes");
+ }
+ #endif // DEBUG_LEAKS
+}
+
+>>>>>>> 0.12
void memleakfinder_reportleaks_file(FILE *file)
{
InternalAllocGuard guard;
@@ -549,4 +689,8 @@ void operator delete(void *ptr) throw ()
internal_delete(ptr);
}
+<<<<<<< HEAD
#endif // BOX_RELEASE_BUILD
+=======
+#endif // BOX_MEMORY_LEAK_TESTING
+>>>>>>> 0.12
diff --git a/lib/common/ExcludeList.cpp b/lib/common/ExcludeList.cpp
index edbf1a6a..c7c80ed2 100644
--- a/lib/common/ExcludeList.cpp
+++ b/lib/common/ExcludeList.cpp
@@ -101,11 +101,14 @@ std::string ExcludeList::ReplaceSlashesRegex(const std::string& input) const
output.replace(pos, 1, "\\" DIRECTORY_SEPARATOR);
}
+<<<<<<< HEAD
for (std::string::iterator i = output.begin(); i != output.end(); i++)
{
*i = tolower(*i);
}
+=======
+>>>>>>> 0.12
return output;
}
#endif
@@ -185,17 +188,30 @@ void ExcludeList::AddRegexEntries(const std::string &rEntries)
try
{
std::string entry = *i;
+<<<<<<< HEAD
+=======
+ int flags = REG_EXTENDED | REG_NOSUB;
+>>>>>>> 0.12
// Convert any forward slashes in the string
// to appropriately escaped backslashes
#ifdef WIN32
entry = ReplaceSlashesRegex(entry);
+<<<<<<< HEAD
#endif
// Compile
int errcode = ::regcomp(pregex, entry.c_str(),
REG_EXTENDED | REG_NOSUB);
+=======
+ flags |= REG_ICASE; // Windows convention
+ #endif
+
+ // Compile
+ int errcode = ::regcomp(pregex, entry.c_str(),
+ flags);
+>>>>>>> 0.12
if (errcode != 0)
{
@@ -238,6 +254,10 @@ bool ExcludeList::IsExcluded(const std::string &rTest) const
std::string test = rTest;
#ifdef WIN32
+<<<<<<< HEAD
+=======
+ // converts to lower case as well
+>>>>>>> 0.12
test = ReplaceSlashesDefinite(test);
#endif
diff --git a/lib/common/FdGetLine.cpp b/lib/common/FdGetLine.cpp
index 9b53288b..2d2f7c6a 100644
--- a/lib/common/FdGetLine.cpp
+++ b/lib/common/FdGetLine.cpp
@@ -20,6 +20,7 @@
#include "MemLeakFindOn.h"
+<<<<<<< HEAD
// utility whitespace function
inline bool iw(int c)
{
@@ -27,6 +28,8 @@ inline bool iw(int c)
}
+=======
+>>>>>>> 0.12
// --------------------------------------------------------------------------
//
// Function
@@ -36,12 +39,16 @@ inline bool iw(int c)
//
// --------------------------------------------------------------------------
FdGetLine::FdGetLine(int fd)
+<<<<<<< HEAD
: mFileHandle(fd),
mLineNumber(0),
mBufferBegin(0),
mBytesInBuffer(0),
mPendingEOF(false),
mEOF(false)
+=======
+: mFileHandle(fd)
+>>>>>>> 0.12
{
if(mFileHandle < 0) {THROW_EXCEPTION(CommonException, BadArguments)}
//printf("FdGetLine buffer size = %d\n", sizeof(mBuffer));
@@ -74,6 +81,7 @@ FdGetLine::~FdGetLine()
std::string FdGetLine::GetLine(bool Preprocess)
{
if(mFileHandle == -1) {THROW_EXCEPTION(CommonException, GetLineNoHandle)}
+<<<<<<< HEAD
// EOF?
if(mEOF) {THROW_EXCEPTION(CommonException, GetLineEOF)}
@@ -194,6 +202,55 @@ std::string FdGetLine::GetLine(bool Preprocess)
// Return a sub string
return r.substr(begin, end - begin + 1);
}
+=======
+
+ std::string r;
+ bool result = GetLineInternal(r, Preprocess);
+
+ if(!result)
+ {
+ // should never fail for FdGetLine
+ THROW_EXCEPTION(CommonException, Internal);
+ }
+
+ return r;
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: FdGetLine::ReadMore()
+// Purpose: Read more bytes from the handle, possible the
+// console, into mBuffer and return the number of
+// bytes read, 0 on EOF or -1 on error.
+// Created: 2011/04/22
+//
+// --------------------------------------------------------------------------
+int FdGetLine::ReadMore(int Timeout)
+{
+ int bytes;
+
+#ifdef WIN32
+ if (mFileHandle == _fileno(stdin))
+ {
+ bytes = console_read(mBuffer, sizeof(mBuffer));
+ }
+ else
+ {
+ bytes = ::read(mFileHandle, mBuffer, sizeof(mBuffer));
+ }
+#else // !WIN32
+ bytes = ::read(mFileHandle, mBuffer, sizeof(mBuffer));
+#endif // WIN32
+
+ if(bytes == 0)
+ {
+ mPendingEOF = true;
+ }
+
+ return bytes;
+>>>>>>> 0.12
}
@@ -202,7 +259,11 @@ std::string FdGetLine::GetLine(bool Preprocess)
// Function
// Name: FdGetLine::DetachFile()
// Purpose: Detaches the file handle, setting the file pointer correctly.
+<<<<<<< HEAD
// Probably not good for sockets...
+=======
+// Probably not good for sockets...
+>>>>>>> 0.12
// Created: 2003/07/24
//
// --------------------------------------------------------------------------
@@ -225,4 +286,7 @@ void FdGetLine::DetachFile()
mFileHandle = -1;
}
+<<<<<<< HEAD
+=======
+>>>>>>> 0.12
diff --git a/lib/common/FdGetLine.h b/lib/common/FdGetLine.h
index df43c3c9..6b609fe8 100644
--- a/lib/common/FdGetLine.h
+++ b/lib/common/FdGetLine.h
@@ -12,6 +12,7 @@
#include <string>
+<<<<<<< HEAD
#ifdef BOX_RELEASE_BUILD
#define FDGETLINE_BUFFER_SIZE 1024
#elif defined WIN32
@@ -25,6 +26,9 @@
// Just a very large upper bound for line size to avoid
// people sending lots of data over sockets and causing memory problems.
#define FDGETLINE_MAX_LINE_SIZE (1024*256)
+=======
+#include "GetLine.h"
+>>>>>>> 0.12
// --------------------------------------------------------------------------
//
@@ -34,15 +38,24 @@
// Created: 2003/07/24
//
// --------------------------------------------------------------------------
+<<<<<<< HEAD
class FdGetLine
{
public:
FdGetLine(int fd);
~FdGetLine();
+=======
+class FdGetLine : public GetLine
+{
+public:
+ FdGetLine(int fd);
+ virtual ~FdGetLine();
+>>>>>>> 0.12
private:
FdGetLine(const FdGetLine &rToCopy);
public:
+<<<<<<< HEAD
std::string GetLine(bool Preprocess = false);
bool IsEOF() {return mEOF;}
int GetLineNumber() {return mLineNumber;}
@@ -59,6 +72,21 @@ private:
int mBytesInBuffer;
bool mPendingEOF;
bool mEOF;
+=======
+ virtual std::string GetLine(bool Preprocess = false);
+ // Call to detach, setting file pointer correctly to last bit read.
+ // Only works for lseek-able file descriptors.
+ void DetachFile();
+ // if we read 0 bytes from an fd, it must be end of stream,
+ // because we don't support timeouts
+ virtual bool IsStreamDataLeft() { return false; }
+
+protected:
+ int ReadMore(int Timeout = IOStream::TimeOutInfinite);
+
+private:
+ int mFileHandle;
+>>>>>>> 0.12
};
#endif // FDGETLINE__H
diff --git a/lib/common/FileModificationTime.cpp b/lib/common/FileModificationTime.cpp
index 1109b15f..bc35b7e6 100644
--- a/lib/common/FileModificationTime.cpp
+++ b/lib/common/FileModificationTime.cpp
@@ -16,7 +16,11 @@
#include "MemLeakFindOn.h"
+<<<<<<< HEAD
box_time_t FileModificationTime(EMU_STRUCT_STAT &st)
+=======
+box_time_t FileModificationTime(const EMU_STRUCT_STAT &st)
+>>>>>>> 0.12
{
#ifndef HAVE_STRUCT_STAT_ST_MTIMESPEC
box_time_t datamodified = ((int64_t)st.st_mtime) * (MICRO_SEC_IN_SEC_LL);
@@ -28,7 +32,11 @@ box_time_t FileModificationTime(EMU_STRUCT_STAT &st)
return datamodified;
}
+<<<<<<< HEAD
box_time_t FileAttrModificationTime(EMU_STRUCT_STAT &st)
+=======
+box_time_t FileAttrModificationTime(const EMU_STRUCT_STAT &st)
+>>>>>>> 0.12
{
box_time_t statusmodified =
#ifdef HAVE_STRUCT_STAT_ST_MTIMESPEC
@@ -47,7 +55,11 @@ box_time_t FileAttrModificationTime(EMU_STRUCT_STAT &st)
return statusmodified;
}
+<<<<<<< HEAD
box_time_t FileModificationTimeMaxModAndAttr(EMU_STRUCT_STAT &st)
+=======
+box_time_t FileModificationTimeMaxModAndAttr(const EMU_STRUCT_STAT &st)
+>>>>>>> 0.12
{
#ifndef HAVE_STRUCT_STAT_ST_MTIMESPEC
box_time_t datamodified = ((int64_t)st.st_mtime) * (MICRO_SEC_IN_SEC_LL);
diff --git a/lib/common/FileModificationTime.h b/lib/common/FileModificationTime.h
index e6e6c172..ffff29c7 100644
--- a/lib/common/FileModificationTime.h
+++ b/lib/common/FileModificationTime.h
@@ -14,9 +14,15 @@
#include "BoxTime.h"
+<<<<<<< HEAD
box_time_t FileModificationTime(EMU_STRUCT_STAT &st);
box_time_t FileAttrModificationTime(EMU_STRUCT_STAT &st);
box_time_t FileModificationTimeMaxModAndAttr(EMU_STRUCT_STAT &st);
+=======
+box_time_t FileModificationTime(const EMU_STRUCT_STAT &st);
+box_time_t FileAttrModificationTime(const EMU_STRUCT_STAT &st);
+box_time_t FileModificationTimeMaxModAndAttr(const EMU_STRUCT_STAT &st);
+>>>>>>> 0.12
#endif // FILEMODIFICATIONTIME__H
diff --git a/lib/common/FileStream.cpp b/lib/common/FileStream.cpp
index 5be8237c..68209b15 100644
--- a/lib/common/FileStream.cpp
+++ b/lib/common/FileStream.cpp
@@ -190,6 +190,7 @@ int FileStream::Read(void *pBuffer, int NBytes, int Timeout)
}
else
{
+<<<<<<< HEAD
BOX_LOG_WIN_ERROR("Failed to read from file: " << mFileName);
r = -1;
}
@@ -205,6 +206,24 @@ int FileStream::Read(void *pBuffer, int NBytes, int Timeout)
{
THROW_EXCEPTION(CommonException, OSFileReadError)
}
+=======
+ THROW_WIN_FILE_ERROR("Failed to read from file", mFileName,
+ CommonException, OSFileReadError);
+ }
+
+ if(r == -1)
+ {
+ THROW_EXCEPTION(CommonException, OSFileReadError)
+ }
+#else
+ int r = ::read(mOSFileHandle, pBuffer, NBytes);
+ if(r == -1)
+ {
+ THROW_SYS_FILE_ERROR("Failed to read from file", mFileName,
+ CommonException, OSFileReadError);
+ }
+#endif
+>>>>>>> 0.12
if(r == 0)
{
@@ -228,7 +247,11 @@ IOStream::pos_type FileStream::BytesLeftToRead()
EMU_STRUCT_STAT st;
if(EMU_FSTAT(mOSFileHandle, &st) != 0)
{
+<<<<<<< HEAD
THROW_EXCEPTION(CommonException, OSFileError)
+=======
+ BOX_LOG_SYS_ERROR(BOX_FILE_MESSAGE("Failed to stat file", mFileName));
+>>>>>>> 0.12
}
return st.st_size - GetPosition();
@@ -262,14 +285,24 @@ void FileStream::Write(const void *pBuffer, int NBytes)
if ((res == 0) || (numBytesWritten != (DWORD)NBytes))
{
+<<<<<<< HEAD
// DWORD err = GetLastError();
THROW_EXCEPTION(CommonException, OSFileWriteError)
+=======
+ THROW_WIN_FILE_ERROR("Failed to write to file", mFileName,
+ CommonException, OSFileWriteError);
+>>>>>>> 0.12
}
#else
if(::write(mOSFileHandle, pBuffer, NBytes) != NBytes)
{
+<<<<<<< HEAD
BOX_LOG_SYS_ERROR("Failed to write to file: " << mFileName);
THROW_EXCEPTION(CommonException, OSFileWriteError)
+=======
+ THROW_SYS_FILE_ERROR("Failed to write to file", mFileName,
+ CommonException, OSFileWriteError);
+>>>>>>> 0.12
}
#endif
}
@@ -292,18 +325,35 @@ IOStream::pos_type FileStream::GetPosition() const
#ifdef WIN32
LARGE_INTEGER conv;
+<<<<<<< HEAD
conv.HighPart = 0;
conv.LowPart = 0;
conv.LowPart = SetFilePointer(this->mOSFileHandle, 0, &conv.HighPart, FILE_CURRENT);
+=======
+ conv.HighPart = 0;
+ conv.LowPart = SetFilePointer(this->mOSFileHandle, 0, &conv.HighPart, FILE_CURRENT);
+
+ if(conv.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
+ {
+ THROW_WIN_FILE_ERROR("Failed to seek in file", mFileName,
+ CommonException, OSFileError);
+ }
+
+>>>>>>> 0.12
return (IOStream::pos_type)conv.QuadPart;
#else // ! WIN32
off_t p = ::lseek(mOSFileHandle, 0, SEEK_CUR);
if(p == -1)
{
+<<<<<<< HEAD
THROW_EXCEPTION(CommonException, OSFileError)
+=======
+ THROW_SYS_FILE_ERROR("Failed to seek in file", mFileName,
+ CommonException, OSFileError);
+>>>>>>> 0.12
}
return (IOStream::pos_type)p;
@@ -328,18 +378,31 @@ void FileStream::Seek(IOStream::pos_type Offset, int SeekType)
#ifdef WIN32
LARGE_INTEGER conv;
+<<<<<<< HEAD
+=======
+>>>>>>> 0.12
conv.QuadPart = Offset;
DWORD retVal = SetFilePointer(this->mOSFileHandle, conv.LowPart, &conv.HighPart, ConvertSeekTypeToOSWhence(SeekType));
if(retVal == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
{
+<<<<<<< HEAD
THROW_EXCEPTION(CommonException, OSFileError)
+=======
+ THROW_WIN_FILE_ERROR("Failed to seek in file", mFileName,
+ CommonException, OSFileError);
+>>>>>>> 0.12
}
#else // ! WIN32
if(::lseek(mOSFileHandle, Offset, ConvertSeekTypeToOSWhence(SeekType)) == -1)
{
+<<<<<<< HEAD
THROW_EXCEPTION(CommonException, OSFileError)
+=======
+ THROW_SYS_FILE_ERROR("Failed to seek in file", mFileName,
+ CommonException, OSFileError);
+>>>>>>> 0.12
}
#endif // WIN32
@@ -365,12 +428,26 @@ void FileStream::Close()
#ifdef WIN32
if(::CloseHandle(mOSFileHandle) == 0)
+<<<<<<< HEAD
#else
if(::close(mOSFileHandle) != 0)
#endif
{
THROW_EXCEPTION(CommonException, OSFileCloseError)
}
+=======
+ {
+ THROW_WIN_FILE_ERROR("Failed to close file", mFileName,
+ CommonException, OSFileCloseError);
+ }
+#else // ! WIN32
+ if(::close(mOSFileHandle) != 0)
+ {
+ THROW_SYS_FILE_ERROR("Failed to close file", mFileName,
+ CommonException, OSFileCloseError);
+ }
+#endif // WIN32
+>>>>>>> 0.12
mOSFileHandle = INVALID_FILE;
mIsEOF = true;
@@ -401,7 +478,11 @@ bool FileStream::StreamDataLeft()
// --------------------------------------------------------------------------
bool FileStream::StreamClosed()
{
+<<<<<<< HEAD
return mIsEOF;
+=======
+ return (mOSFileHandle == INVALID_FILE);
+>>>>>>> 0.12
}
// --------------------------------------------------------------------------
diff --git a/lib/common/GetLine.cpp b/lib/common/GetLine.cpp
new file mode 100644
index 00000000..e6b26c8a
--- /dev/null
+++ b/lib/common/GetLine.cpp
@@ -0,0 +1,176 @@
+// --------------------------------------------------------------------------
+//
+// File
+// Name: GetLine.cpp
+// Purpose: Common base class for line based file descriptor reading
+// Created: 2011/04/22
+//
+// --------------------------------------------------------------------------
+
+#include "Box.h"
+
+#include <sys/types.h>
+
+#ifdef HAVE_UNISTD_H
+ #include <unistd.h>
+#endif
+
+#include "GetLine.h"
+#include "CommonException.h"
+
+#include "MemLeakFindOn.h"
+
+// utility whitespace function
+inline bool iw(int c)
+{
+ return (c == ' ' || c == '\t' || c == '\v' || c == '\f'); // \r, \n are already excluded
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: GetLine::GetLine(int)
+// Purpose: Constructor, taking file descriptor
+// Created: 2011/04/22
+//
+// --------------------------------------------------------------------------
+GetLine::GetLine()
+: mLineNumber(0),
+ mBufferBegin(0),
+ mBytesInBuffer(0),
+ mPendingEOF(false),
+ mEOF(false)
+{ }
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: GetLine::GetLineInternal(std::string &, bool, int)
+// Purpose: Gets a line from the file, returning it in rOutput.
+// If Preprocess is true, leading and trailing
+// whitespace is removed, and comments (after #) are
+// deleted. Returns true if a line is available now,
+// false if retrying may get a line (eg timeout,
+// signal), and exceptions if it's EOF.
+// Created: 2011/04/22
+//
+// --------------------------------------------------------------------------
+bool GetLine::GetLineInternal(std::string &rOutput, bool Preprocess,
+ int Timeout)
+{
+ // EOF?
+ if(mEOF) {THROW_EXCEPTION(CommonException, GetLineEOF)}
+
+ // Initialise string to stored into
+ rOutput = mPendingString;
+ mPendingString.erase();
+
+ bool foundLineEnd = false;
+
+ while(!foundLineEnd && !mEOF)
+ {
+ // Use any bytes left in the buffer
+ while(mBufferBegin < mBytesInBuffer)
+ {
+ int c = mBuffer[mBufferBegin++];
+ if(c == '\r')
+ {
+ // Ignore nasty Windows line ending extra chars
+ }
+ else if(c == '\n')
+ {
+ // Line end!
+ foundLineEnd = true;
+ break;
+ }
+ else
+ {
+ // Add to string
+ rOutput += c;
+ }
+
+ // Implicit line ending at EOF
+ if(mBufferBegin >= mBytesInBuffer && mPendingEOF)
+ {
+ foundLineEnd = true;
+ }
+ }
+
+ // Check size
+ if(rOutput.size() > GETLINE_MAX_LINE_SIZE)
+ {
+ THROW_EXCEPTION(CommonException, GetLineTooLarge)
+ }
+
+ // Read more in?
+ if(!foundLineEnd && mBufferBegin >= mBytesInBuffer && !mPendingEOF)
+ {
+ int bytes = ReadMore(Timeout);
+
+ // Error?
+ if(bytes == -1)
+ {
+ THROW_EXCEPTION(CommonException, OSFileError)
+ }
+
+ // Adjust buffer info
+ mBytesInBuffer = bytes;
+ mBufferBegin = 0;
+
+ // No data returned?
+ if(bytes == 0 && IsStreamDataLeft())
+ {
+ // store string away
+ mPendingString = rOutput;
+ // Return false;
+ return false;
+ }
+ }
+
+ // EOF?
+ if(mPendingEOF && mBufferBegin >= mBytesInBuffer)
+ {
+ // File is EOF, and now we've depleted the buffer completely, so tell caller as well.
+ mEOF = true;
+ }
+ }
+
+ if(Preprocess)
+ {
+ // Check for comment char, but char before must be whitespace
+ // end points to a gap between characters, may equal start if
+ // the string to be extracted has zero length, and indexes the
+ // first character not in the string (== length, or a # mark
+ // or whitespace)
+ int end = 0;
+ int size = rOutput.size();
+ while(end < size)
+ {
+ if(rOutput[end] == '#' && (end == 0 || (iw(rOutput[end-1]))))
+ {
+ break;
+ }
+ end++;
+ }
+
+ // Remove whitespace
+ int begin = 0;
+ while(begin < size && iw(rOutput[begin]))
+ {
+ begin++;
+ }
+
+ while(end > begin && end <= size && iw(rOutput[end-1]))
+ {
+ end--;
+ }
+
+ // Return a sub string
+ rOutput = rOutput.substr(begin, end - begin);
+ }
+
+ return true;
+}
+
+
diff --git a/lib/common/GetLine.h b/lib/common/GetLine.h
new file mode 100644
index 00000000..0eeb3c71
--- /dev/null
+++ b/lib/common/GetLine.h
@@ -0,0 +1,67 @@
+// --------------------------------------------------------------------------
+//
+// File
+// Name: GetLine.h
+// Purpose: Common base class for line based file descriptor reading
+// Created: 2011/04/22
+//
+// --------------------------------------------------------------------------
+
+#ifndef GETLINE__H
+#define GETLINE__H
+
+#include <string>
+
+#ifdef BOX_RELEASE_BUILD
+ #define GETLINE_BUFFER_SIZE 1024
+#elif defined WIN32
+ // need enough space for at least one unicode character
+ // in UTF-8 when calling console_read() from bbackupquery
+ #define GETLINE_BUFFER_SIZE 5
+#else
+ #define GETLINE_BUFFER_SIZE 4
+#endif
+
+// Just a very large upper bound for line size to avoid
+// people sending lots of data over sockets and causing memory problems.
+#define GETLINE_MAX_LINE_SIZE (1024*256)
+
+// --------------------------------------------------------------------------
+//
+// Class
+// Name: GetLine
+// Purpose: Common base class for line based file descriptor reading
+// Created: 2011/04/22
+//
+// --------------------------------------------------------------------------
+class GetLine
+{
+protected:
+ GetLine();
+
+private:
+ GetLine(const GetLine &rToCopy);
+
+public:
+ virtual bool IsEOF() {return mEOF;}
+ int GetLineNumber() {return mLineNumber;}
+ virtual ~GetLine() { }
+
+protected:
+ bool GetLineInternal(std::string &rOutput,
+ bool Preprocess = false,
+ int Timeout = IOStream::TimeOutInfinite);
+ virtual int ReadMore(int Timeout = IOStream::TimeOutInfinite) = 0;
+ virtual bool IsStreamDataLeft() = 0;
+
+ char mBuffer[GETLINE_BUFFER_SIZE];
+ int mLineNumber;
+ int mBufferBegin;
+ int mBytesInBuffer;
+ bool mPendingEOF;
+ std::string mPendingString;
+ bool mEOF;
+};
+
+#endif // GETLINE__H
+
diff --git a/lib/common/IOStreamGetLine.cpp b/lib/common/IOStreamGetLine.cpp
index 27a77c29..9a40f3eb 100644
--- a/lib/common/IOStreamGetLine.cpp
+++ b/lib/common/IOStreamGetLine.cpp
@@ -13,6 +13,7 @@
#include "MemLeakFindOn.h"
+<<<<<<< HEAD
// utility whitespace function
inline bool iw(int c)
{
@@ -20,6 +21,8 @@ inline bool iw(int c)
}
+=======
+>>>>>>> 0.12
// --------------------------------------------------------------------------
//
// Function
@@ -29,12 +32,16 @@ inline bool iw(int c)
//
// --------------------------------------------------------------------------
IOStreamGetLine::IOStreamGetLine(IOStream &Stream)
+<<<<<<< HEAD
: mrStream(Stream),
mLineNumber(0),
mBufferBegin(0),
mBytesInBuffer(0),
mPendingEOF(false),
mEOF(false)
+=======
+: mrStream(Stream)
+>>>>>>> 0.12
{
}
@@ -66,6 +73,7 @@ IOStreamGetLine::~IOStreamGetLine()
// --------------------------------------------------------------------------
bool IOStreamGetLine::GetLine(std::string &rOutput, bool Preprocess, int Timeout)
{
+<<<<<<< HEAD
// EOF?
if(mEOF) {THROW_EXCEPTION(CommonException, GetLineEOF)}
@@ -178,6 +186,32 @@ bool IOStreamGetLine::GetLine(std::string &rOutput, bool Preprocess, int Timeout
rOutput = r.substr(begin, end - begin + 1);
return true;
}
+=======
+ return GetLineInternal(rOutput, Preprocess, Timeout);
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: IOStreamGetLine::ReadMore()
+// Purpose: Read more bytes from the handle, possible the
+// console, into mBuffer and return the number of
+// bytes read, 0 on EOF or -1 on error.
+// Created: 2011/04/22
+//
+// --------------------------------------------------------------------------
+int IOStreamGetLine::ReadMore(int Timeout)
+{
+ int bytes = mrStream.Read(mBuffer, sizeof(mBuffer), Timeout);
+
+ if(!mrStream.StreamDataLeft())
+ {
+ mPendingEOF = true;
+ }
+
+ return bytes;
+>>>>>>> 0.12
}
diff --git a/lib/common/IOStreamGetLine.h b/lib/common/IOStreamGetLine.h
index 9a5d1818..1693e8ac 100644
--- a/lib/common/IOStreamGetLine.h
+++ b/lib/common/IOStreamGetLine.h
@@ -12,6 +12,7 @@
#include <string>
+<<<<<<< HEAD
#include "IOStream.h"
#ifdef BOX_RELEASE_BUILD
@@ -24,6 +25,11 @@
// people sending lots of data over sockets and causing memory problems.
#define IOSTREAMGETLINE_MAX_LINE_SIZE (1024*256)
+=======
+#include "GetLine.h"
+#include "IOStream.h"
+
+>>>>>>> 0.12
// --------------------------------------------------------------------------
//
// Class
@@ -32,29 +38,49 @@
// Created: 2003/07/24
//
// --------------------------------------------------------------------------
+<<<<<<< HEAD
class IOStreamGetLine
{
public:
IOStreamGetLine(IOStream &Stream);
~IOStreamGetLine();
+=======
+class IOStreamGetLine : public GetLine
+{
+public:
+ IOStreamGetLine(IOStream &Stream);
+ virtual ~IOStreamGetLine();
+>>>>>>> 0.12
private:
IOStreamGetLine(const IOStreamGetLine &rToCopy);
public:
bool GetLine(std::string &rOutput, bool Preprocess = false, int Timeout = IOStream::TimeOutInfinite);
+<<<<<<< HEAD
bool IsEOF() {return mEOF;}
int GetLineNumber() {return mLineNumber;}
+=======
+>>>>>>> 0.12
// Call to detach, setting file pointer correctly to last bit read.
// Only works for lseek-able file descriptors.
void DetachFile();
+<<<<<<< HEAD
+=======
+ virtual bool IsStreamDataLeft()
+ {
+ return mrStream.StreamDataLeft();
+ }
+
+>>>>>>> 0.12
// For doing interesting stuff with the remaining data...
// Be careful with this!
const void *GetBufferedData() const {return mBuffer + mBufferBegin;}
int GetSizeOfBufferedData() const {return mBytesInBuffer - mBufferBegin;}
void IgnoreBufferedData(int BytesToIgnore);
IOStream &GetUnderlyingStream() {return mrStream;}
+<<<<<<< HEAD
private:
char mBuffer[IOSTREAMGETLINE_BUFFER_SIZE];
@@ -65,6 +91,14 @@ private:
bool mPendingEOF;
bool mEOF;
std::string mPendingString;
+=======
+
+protected:
+ int ReadMore(int Timeout = IOStream::TimeOutInfinite);
+
+private:
+ IOStream &mrStream;
+>>>>>>> 0.12
};
#endif // IOSTREAMGETLINE__H
diff --git a/lib/common/Logging.cpp b/lib/common/Logging.cpp
index 296443ea..4a7e5e0a 100644
--- a/lib/common/Logging.cpp
+++ b/lib/common/Logging.cpp
@@ -22,6 +22,12 @@
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
+<<<<<<< HEAD
+=======
+#ifdef WIN32
+ #include <process.h>
+#endif
+>>>>>>> 0.12
#include <cstring>
#include <iomanip>
@@ -43,6 +49,15 @@ Log::Level Logging::sGlobalLevel = Log::EVERYTHING;
Logging Logging::sGlobalLogging; //automatic initialisation
std::string Logging::sProgramName;
+<<<<<<< HEAD
+=======
+HideSpecificExceptionGuard::SuppressedExceptions_t
+ HideSpecificExceptionGuard::sSuppressedExceptions;
+
+int Logging::Guard::sGuardCount = 0;
+Log::Level Logging::Guard::sOriginalLevel = Log::INVALID;
+
+>>>>>>> 0.12
Logging::Logging()
{
ASSERT(!spConsole);
@@ -244,6 +259,15 @@ Logger::~Logger()
Logging::Remove(this);
}
+<<<<<<< HEAD
+=======
+bool Logger::IsEnabled(Log::Level level)
+{
+ return Logging::IsEnabled(level) &&
+ (int)mCurrentLevel >= (int)level;
+}
+
+>>>>>>> 0.12
bool Console::sShowTime = false;
bool Console::sShowTimeMicros = false;
bool Console::sShowTag = false;
@@ -343,11 +367,28 @@ bool Console::Log(Log::Level level, const std::string& rFile,
#ifdef WIN32
std::string output = buf.str();
+<<<<<<< HEAD
ConvertUtf8ToConsole(output.c_str(), output);
fprintf(target, "%s\n", output.c_str());
#else
fprintf(target, "%s\n", buf.str().c_str());
#endif
+=======
+ if(ConvertUtf8ToConsole(output.c_str(), output) == false)
+ {
+ fprintf(target, "%s (and failed to convert to console encoding)\n",
+ output.c_str());
+ }
+ else
+ {
+ fprintf(target, "%s\n", output.c_str());
+ }
+ #else
+ fprintf(target, "%s\n", buf.str().c_str());
+ #endif
+
+ fflush(target);
+>>>>>>> 0.12
return true;
}
@@ -446,13 +487,28 @@ int Syslog::GetNamedFacility(const std::string& rFacility)
bool FileLogger::Log(Log::Level Level, const std::string& rFile,
int line, std::string& rMessage)
{
+<<<<<<< HEAD
+=======
+ if (mLogFile.StreamClosed())
+ {
+ /* skip this logger to allow logging failure to open
+ the log file, without causing an infinite loop */
+ return true;
+ }
+
+>>>>>>> 0.12
if (Level > GetLevel())
{
return true;
}
/* avoid infinite loop if this throws an exception */
+<<<<<<< HEAD
Logging::Remove(this);
+=======
+ Log::Level oldLevel = GetLevel();
+ Filter(Log::NOTHING);
+>>>>>>> 0.12
std::ostringstream buf;
buf << FormatTime(GetCurrentBoxTime(), true, false);
@@ -492,7 +548,12 @@ bool FileLogger::Log(Log::Level Level, const std::string& rFile,
mLogFile.Write(output.c_str(), output.length());
+<<<<<<< HEAD
Logging::Add(this);
+=======
+ // no infinite loop, reset to saved logging level
+ Filter(oldLevel);
+>>>>>>> 0.12
return true;
}
@@ -516,3 +577,21 @@ std::string PrintEscapedBinaryData(const std::string& rInput)
return output.str();
}
+<<<<<<< HEAD
+=======
+
+bool HideSpecificExceptionGuard::IsHidden(int type, int subtype)
+{
+ for (SuppressedExceptions_t::iterator
+ i = sSuppressedExceptions.begin();
+ i != sSuppressedExceptions.end(); i++)
+ {
+ if(i->first == type && i->second == subtype)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+>>>>>>> 0.12
diff --git a/lib/common/Logging.h b/lib/common/Logging.h
index 15400711..bc0203bb 100644
--- a/lib/common/Logging.h
+++ b/lib/common/Logging.h
@@ -10,6 +10,11 @@
#ifndef LOGGING__H
#define LOGGING__H
+<<<<<<< HEAD
+=======
+#include <assert.h>
+
+>>>>>>> 0.12
#include <cerrno>
#include <cstring>
#include <iomanip>
@@ -41,6 +46,7 @@
if (Logging::IsEnabled(Log::TRACE)) \
{ BOX_LOG(Log::TRACE, stuff) }
+<<<<<<< HEAD
#define BOX_SYS_ERROR(stuff) \
stuff << ": " << std::strerror(errno) << " (" << errno << ")"
@@ -66,6 +72,48 @@ inline std::string GetNativeErrorMessage()
return _box_log_line.str();
#endif
}
+=======
+#define BOX_SYS_ERRNO_MESSAGE(error_number, stuff) \
+ stuff << ": " << std::strerror(error_number) << \
+ " (" << error_number << ")"
+
+#define BOX_FILE_MESSAGE(filename, message) \
+ message << ": " << filename
+
+#define BOX_SYS_FILE_ERRNO_MESSAGE(filename, error_number, message) \
+ BOX_SYS_ERRNO_MESSAGE(error_number, BOX_FILE_MESSAGE(filename, message))
+
+#define BOX_SYS_ERROR_MESSAGE(stuff) \
+ BOX_SYS_ERRNO_MESSAGE(errno, stuff)
+
+#define BOX_LOG_SYS_WARNING(stuff) \
+ BOX_WARNING(BOX_SYS_ERROR_MESSAGE(stuff))
+#define BOX_LOG_SYS_ERROR(stuff) \
+ BOX_ERROR(BOX_SYS_ERROR_MESSAGE(stuff))
+#define BOX_LOG_SYS_ERRNO(error_number, stuff) \
+ BOX_ERROR(BOX_SYS_ERRNO_MESSAGE(error_number, stuff))
+#define BOX_LOG_SYS_FATAL(stuff) \
+ BOX_FATAL(BOX_SYS_ERROR_MESSAGE(stuff))
+
+#define THROW_SYS_ERROR_NUMBER(message, error_number, exception, subtype) \
+ THROW_EXCEPTION_MESSAGE(exception, subtype, \
+ BOX_SYS_ERRNO_MESSAGE(error_number, message))
+
+#define THROW_SYS_ERROR(message, exception, subtype) \
+ THROW_SYS_ERROR_NUMBER(message, errno, exception, subtype)
+
+#define THROW_SYS_FILE_ERROR(message, filename, exception, subtype) \
+ THROW_SYS_ERROR_NUMBER(BOX_FILE_MESSAGE(filename, message), \
+ errno, exception, subtype)
+
+#define THROW_SYS_FILE_ERRNO(message, filename, error_number, exception, subtype) \
+ THROW_SYS_ERROR_NUMBER(BOX_FILE_MESSAGE(filename, message), \
+ error_number, exception, subtype)
+
+#define THROW_FILE_ERROR(message, filename, exception, subtype) \
+ THROW_EXCEPTION_MESSAGE(exception, subtype, \
+ BOX_FILE_MESSAGE(filename, message))
+>>>>>>> 0.12
#ifdef WIN32
#define BOX_LOG_WIN_ERROR(stuff) \
@@ -78,14 +126,40 @@ inline std::string GetNativeErrorMessage()
BOX_WARNING(stuff << ": " << GetErrorMessage(number))
#define BOX_LOG_NATIVE_ERROR(stuff) BOX_LOG_WIN_ERROR(stuff)
#define BOX_LOG_NATIVE_WARNING(stuff) BOX_LOG_WIN_WARNING(stuff)
+<<<<<<< HEAD
+=======
+ #define BOX_WIN_ERRNO_MESSAGE(error_number, stuff) \
+ stuff << ": " << GetErrorMessage(error_number)
+ #define THROW_WIN_ERROR_NUMBER(message, error_number, exception, subtype) \
+ THROW_EXCEPTION_MESSAGE(exception, subtype, \
+ BOX_WIN_ERRNO_MESSAGE(error_number, message))
+ #define THROW_WIN_FILE_ERRNO(message, filename, error_number, exception, subtype) \
+ THROW_WIN_ERROR_NUMBER(BOX_FILE_MESSAGE(filename, message), \
+ error_number, exception, subtype)
+ #define THROW_WIN_FILE_ERROR(message, filename, exception, subtype) \
+ THROW_WIN_FILE_ERRNO(message, filename, GetLastError(), \
+ exception, subtype)
+>>>>>>> 0.12
#else
#define BOX_LOG_NATIVE_ERROR(stuff) BOX_LOG_SYS_ERROR(stuff)
#define BOX_LOG_NATIVE_WARNING(stuff) BOX_LOG_SYS_WARNING(stuff)
#endif
+<<<<<<< HEAD
#define BOX_LOG_SOCKET_ERROR(_type, _name, _port, stuff) \
BOX_LOG_NATIVE_ERROR(stuff << " (type " << _type << ", name " << \
_name << ", port " << _port << ")")
+=======
+#ifdef WIN32
+# define BOX_LOG_SOCKET_ERROR(_type, _name, _port, stuff) \
+ BOX_LOG_WIN_ERROR_NUMBER(stuff << " (type " << _type << ", name " << \
+ _name << ", port " << _port << ")", WSAGetLastError())
+#else
+# define BOX_LOG_SOCKET_ERROR(_type, _name, _port, stuff) \
+ BOX_LOG_NATIVE_ERROR(stuff << " (type " << _type << ", name " << \
+ _name << ", port " << _port << ")")
+#endif
+>>>>>>> 0.12
#define BOX_FORMAT_HEX32(number) \
std::hex << \
@@ -110,6 +184,15 @@ inline std::string GetNativeErrorMessage()
std::setw(6) << \
timespec.tv_usec
+<<<<<<< HEAD
+=======
+#define BOX_FORMAT_MICROSECONDS(t) \
+ (int)((t) / 1000000) << "." << \
+ std::setw(6) << \
+ std::setfill('0') << \
+ (int)((t) % 1000000) << " seconds"
+
+>>>>>>> 0.12
#undef ERROR
namespace Log
@@ -157,8 +240,32 @@ class Logger
virtual const char* GetType() = 0;
Log::Level GetLevel() { return mCurrentLevel; }
+<<<<<<< HEAD
virtual void SetProgramName(const std::string& rProgramName) = 0;
+=======
+ bool IsEnabled(Log::Level level);
+
+ virtual void SetProgramName(const std::string& rProgramName) = 0;
+
+ class Guard
+ {
+ private:
+ Logger& mLogger;
+ Log::Level mOldLevel;
+
+ public:
+ Guard(Logger& Logger)
+ : mLogger(Logger)
+ {
+ mOldLevel = Logger.GetLevel();
+ }
+ ~Guard()
+ {
+ mLogger.Filter(mOldLevel);
+ }
+ };
+>>>>>>> 0.12
};
// --------------------------------------------------------------------------
@@ -266,22 +373,54 @@ class Logging
static void SetProgramName(const std::string& rProgramName);
static std::string GetProgramName() { return sProgramName; }
static void SetFacility(int facility);
+<<<<<<< HEAD
+=======
+ static Console& GetConsole() { return *spConsole; }
+ static Syslog& GetSyslog() { return *spSyslog; }
+>>>>>>> 0.12
class Guard
{
private:
Log::Level mOldLevel;
+<<<<<<< HEAD
+=======
+ static int sGuardCount;
+ static Log::Level sOriginalLevel;
+>>>>>>> 0.12
public:
Guard(Log::Level newLevel)
{
mOldLevel = Logging::GetGlobalLevel();
+<<<<<<< HEAD
+=======
+ if(sGuardCount == 0)
+ {
+ sOriginalLevel = mOldLevel;
+ }
+ sGuardCount++;
+>>>>>>> 0.12
Logging::SetGlobalLevel(newLevel);
}
~Guard()
{
+<<<<<<< HEAD
Logging::SetGlobalLevel(mOldLevel);
}
+=======
+ sGuardCount--;
+ Logging::SetGlobalLevel(mOldLevel);
+ }
+
+ static bool IsActive() { return (sGuardCount > 0); }
+ static Log::Level GetOriginalLevel() { return sOriginalLevel; }
+ static bool IsGuardingFrom(Log::Level originalLevel)
+ {
+ return IsActive() &&
+ (int)sOriginalLevel >= (int)originalLevel;
+ }
+>>>>>>> 0.12
};
class Tagger
@@ -290,15 +429,33 @@ class Logging
std::string mOldTag;
public:
+<<<<<<< HEAD
Tagger(const std::string& rTempTag)
{
mOldTag = Logging::GetProgramName();
+=======
+ Tagger()
+ : mOldTag(Logging::GetProgramName())
+ {
+ }
+ Tagger(const std::string& rTempTag)
+ : mOldTag(Logging::GetProgramName())
+ {
+>>>>>>> 0.12
Logging::SetProgramName(mOldTag + " " + rTempTag);
}
~Tagger()
{
Logging::SetProgramName(mOldTag);
}
+<<<<<<< HEAD
+=======
+
+ void Change(const std::string& newTempTag)
+ {
+ Logging::SetProgramName(mOldTag + " " + newTempTag);
+ }
+>>>>>>> 0.12
};
};
@@ -341,6 +498,33 @@ class HideExceptionMessageGuard
bool mOldHiddenState;
};
+<<<<<<< HEAD
+=======
+class HideSpecificExceptionGuard
+{
+ private:
+ std::pair<int, int> mExceptionCode;
+
+ public:
+ typedef std::vector<std::pair<int, int> > SuppressedExceptions_t;
+ static SuppressedExceptions_t sSuppressedExceptions;
+
+ HideSpecificExceptionGuard(int type, int subtype)
+ : mExceptionCode(std::pair<int, int>(type, subtype))
+ {
+ sSuppressedExceptions.push_back(mExceptionCode);
+ }
+ ~HideSpecificExceptionGuard()
+ {
+ SuppressedExceptions_t::reverse_iterator i =
+ sSuppressedExceptions.rbegin();
+ assert(*i == mExceptionCode);
+ sSuppressedExceptions.pop_back();
+ }
+ static bool IsHidden(int type, int subtype);
+};
+
+>>>>>>> 0.12
std::string PrintEscapedBinaryData(const std::string& rInput);
#endif // LOGGING__H
diff --git a/lib/common/MainHelper.h b/lib/common/MainHelper.h
index d91bc2f9..453b5b5f 100644
--- a/lib/common/MainHelper.h
+++ b/lib/common/MainHelper.h
@@ -12,7 +12,16 @@
#include <stdio.h>
+<<<<<<< HEAD
#include "BoxException.h"
+=======
+#ifdef NEED_BOX_VERSION_H
+# include "BoxVersion.h"
+#endif
+
+#include "BoxException.h"
+#include "Logging.h"
+>>>>>>> 0.12
#define MAINHELPER_START \
if(argc == 2 && ::strcmp(argv[1], "--version") == 0) \
@@ -20,6 +29,7 @@
MEMLEAKFINDER_INIT \
MEMLEAKFINDER_START \
try {
+<<<<<<< HEAD
#define MAINHELPER_END \
} catch(BoxException &e) { \
printf("Exception: %s (%d/%d)\n", e.what(), e.GetType(), e.GetSubType()); \
@@ -30,6 +40,17 @@
} catch(...) { \
printf("Exception: <UNKNOWN>\n"); \
return 1; }
+=======
+
+#define MAINHELPER_END \
+ } catch(std::exception &e) { \
+ BOX_FATAL(e.what()); \
+ return 1; \
+ } catch(...) { \
+ BOX_FATAL("UNKNOWN"); \
+ return 1; \
+ }
+>>>>>>> 0.12
#ifdef BOX_MEMORY_LEAK_TESTING
#define MAINHELPER_SETUP_MEMORY_LEAK_EXIT_REPORT(file, marker) \
diff --git a/lib/common/MemBlockStream.cpp b/lib/common/MemBlockStream.cpp
index 538a7ef8..554fc6ae 100644
--- a/lib/common/MemBlockStream.cpp
+++ b/lib/common/MemBlockStream.cpp
@@ -22,6 +22,23 @@
//
// Function
// Name: MemBlockStream::MemBlockStream()
+<<<<<<< HEAD
+=======
+// Purpose: Constructor with no contents
+// Created: 2012/11/07
+//
+// --------------------------------------------------------------------------
+MemBlockStream::MemBlockStream()
+: mpBuffer(NULL),
+ mBytesInBuffer(0),
+ mReadPosition(0)
+{ }
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: MemBlockStream::MemBlockStream()
+>>>>>>> 0.12
// Purpose: Constructor (doesn't copy block, careful with lifetimes)
// Created: 2003/09/05
//
@@ -69,7 +86,10 @@ MemBlockStream::MemBlockStream(const CollectInBufferStream &rBuffer)
ASSERT(mBytesInBuffer >= 0);
}
+<<<<<<< HEAD
+=======
+>>>>>>> 0.12
// --------------------------------------------------------------------------
//
// Function
diff --git a/lib/common/MemBlockStream.h b/lib/common/MemBlockStream.h
index f78ff8e6..ed0bf4ff 100644
--- a/lib/common/MemBlockStream.h
+++ b/lib/common/MemBlockStream.h
@@ -27,6 +27,10 @@ class CollectInBufferStream;
class MemBlockStream : public IOStream
{
public:
+<<<<<<< HEAD
+=======
+ MemBlockStream();
+>>>>>>> 0.12
MemBlockStream(const void *pBuffer, int Size);
MemBlockStream(const StreamableMemBlock &rBlock);
MemBlockStream(const CollectInBufferStream &rBuffer);
@@ -41,6 +45,11 @@ public:
virtual void Seek(pos_type Offset, int SeekType);
virtual bool StreamDataLeft();
virtual bool StreamClosed();
+<<<<<<< HEAD
+=======
+ virtual const void* GetBuffer() const { return mpBuffer; }
+ virtual int GetSize() const { return mBytesInBuffer; }
+>>>>>>> 0.12
private:
const char *mpBuffer;
diff --git a/lib/common/MemLeakFinder.h b/lib/common/MemLeakFinder.h
index ca207bd5..e4e9a1ae 100644
--- a/lib/common/MemLeakFinder.h
+++ b/lib/common/MemLeakFinder.h
@@ -28,6 +28,10 @@ class MemLeakSuppressionGuard
extern "C"
{
void *memleakfinder_malloc(size_t size, const char *file, int line);
+<<<<<<< HEAD
+=======
+ void *memleakfinder_calloc(size_t blocks, size_t size, const char *file, int line);
+>>>>>>> 0.12
void *memleakfinder_realloc(void *ptr, size_t size);
void memleakfinder_free(void *ptr);
}
@@ -36,6 +40,11 @@ void memleakfinder_init();
int memleakfinder_numleaks();
+<<<<<<< HEAD
+=======
+void memleakfinder_report_usage_summary();
+
+>>>>>>> 0.12
void memleakfinder_reportleaks();
void memleakfinder_reportleaks_appendfile(const char *filename, const char *markertext);
@@ -54,6 +63,10 @@ void *operator new[](size_t size, const char *file, int line);
// define the malloc functions now, if required
#ifdef MEMLEAKFINDER_FULL_MALLOC_MONITORING
#define malloc(X) memleakfinder_malloc(X, __FILE__, __LINE__)
+<<<<<<< HEAD
+=======
+ #define calloc(X, Y) memleakfinder_calloc(X, Y, __FILE__, __LINE__)
+>>>>>>> 0.12
#define realloc memleakfinder_realloc
#define free memleakfinder_free
#define MEMLEAKFINDER_MALLOC_MONITORING_DEFINED
diff --git a/lib/common/RateLimitingStream.cpp b/lib/common/RateLimitingStream.cpp
new file mode 100644
index 00000000..8876f146
--- /dev/null
+++ b/lib/common/RateLimitingStream.cpp
@@ -0,0 +1,95 @@
+// --------------------------------------------------------------------------
+//
+// File
+// Name: RateLimitingStream.cpp
+// Purpose: Rate-limiting write-only wrapper around IOStreams
+// Created: 2011/01/11
+//
+// --------------------------------------------------------------------------
+
+#include "Box.h"
+#include "RateLimitingStream.h"
+#include "CommonException.h"
+
+#include <string.h>
+
+#include "MemLeakFindOn.h"
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: RateLimitingStream::RateLimitingStream(const char *, int, int)
+// Purpose: Constructor, set up buffer
+// Created: 2011/01/11
+//
+// --------------------------------------------------------------------------
+RateLimitingStream::RateLimitingStream(IOStream& rSink, size_t targetBytesPerSecond)
+: mrSink(rSink), mStartTime(GetCurrentBoxTime()), mTotalBytesRead(0),
+ mTargetBytesPerSecond(targetBytesPerSecond)
+{ }
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: RateLimitingStream::Read(void *pBuffer, int NBytes,
+// int Timeout)
+// Purpose: Reads bytes to the underlying stream at no more than
+// a fixed rate
+// Created: 2011/01/11
+//
+// --------------------------------------------------------------------------
+int RateLimitingStream::Read(void *pBuffer, int NBytes, int Timeout)
+{
+ if(NBytes > 0 && (size_t)NBytes > mTargetBytesPerSecond)
+ {
+ // Limit to one second's worth of data for performance
+ BOX_TRACE("Reducing read size from " << NBytes << " to " <<
+ mTargetBytesPerSecond << " to smooth upload rate");
+ NBytes = mTargetBytesPerSecond;
+ }
+
+ int bytesReadThisTime = mrSink.Read(pBuffer, NBytes, Timeout);
+
+ // How many bytes we will have written after this write finishes?
+ mTotalBytesRead += bytesReadThisTime;
+
+ // When should it be completed by?
+ box_time_t desiredFinishTime = mStartTime +
+ SecondsToBoxTime(mTotalBytesRead / mTargetBytesPerSecond);
+
+ // How long do we have to wait?
+ box_time_t currentTime = GetCurrentBoxTime();
+ int64_t waitTime = desiredFinishTime - currentTime;
+
+ // How are we doing so far? (for logging only)
+ box_time_t currentDuration = currentTime - mStartTime;
+
+ // in case our timer is not very accurate, don't divide by zero on first pass
+ if(currentDuration == 0)
+ {
+ BOX_TRACE("Current rate not yet known, sending immediately");
+ return bytesReadThisTime;
+ }
+
+ uint64_t effectiveRateSoFar = (mTotalBytesRead * MICRO_SEC_IN_SEC_LL)
+ / currentDuration;
+
+ if(waitTime > 0)
+ {
+ BOX_TRACE("Current rate " << effectiveRateSoFar <<
+ " higher than desired rate " << mTargetBytesPerSecond <<
+ ", sleeping for " << BoxTimeToMilliSeconds(waitTime) <<
+ " ms");
+ ShortSleep(waitTime, false);
+ }
+ else
+ {
+ BOX_TRACE("Current rate " << effectiveRateSoFar <<
+ " lower than desired rate " << mTargetBytesPerSecond <<
+ ", sending immediately (would have sent " <<
+ (BoxTimeToMilliSeconds(-waitTime)) << " ms ago)");
+ }
+
+ return bytesReadThisTime;
+}
+
diff --git a/lib/common/RateLimitingStream.h b/lib/common/RateLimitingStream.h
new file mode 100644
index 00000000..a322b99b
--- /dev/null
+++ b/lib/common/RateLimitingStream.h
@@ -0,0 +1,71 @@
+// --------------------------------------------------------------------------
+//
+// File
+// Name: RateLimitingStream.h
+// Purpose: Rate-limiting write-only wrapper around IOStreams
+// Created: 2011/01/11
+//
+// --------------------------------------------------------------------------
+
+#ifndef RATELIMITINGSTREAM__H
+#define RATELIMITINGSTREAM__H
+
+#include "BoxTime.h"
+#include "IOStream.h"
+
+class RateLimitingStream : public IOStream
+{
+private:
+ IOStream& mrSink;
+ box_time_t mStartTime;
+ uint64_t mTotalBytesRead;
+ size_t mTargetBytesPerSecond;
+
+public:
+ RateLimitingStream(IOStream& rSink, size_t targetBytesPerSecond);
+ virtual ~RateLimitingStream() { }
+
+ // This is the only magic
+ virtual int Read(void *pBuffer, int NBytes,
+ int Timeout = IOStream::TimeOutInfinite);
+
+ // Everything else is delegated to the sink
+ virtual void Write(const void *pBuffer, int NBytes)
+ {
+ Write(pBuffer, NBytes);
+ }
+ virtual pos_type BytesLeftToRead()
+ {
+ return mrSink.BytesLeftToRead();
+ }
+ virtual pos_type GetPosition() const
+ {
+ return mrSink.GetPosition();
+ }
+ virtual void Seek(IOStream::pos_type Offset, int SeekType)
+ {
+ mrSink.Seek(Offset, SeekType);
+ }
+ virtual void Flush(int Timeout = IOStream::TimeOutInfinite)
+ {
+ mrSink.Flush(Timeout);
+ }
+ virtual void Close()
+ {
+ mrSink.Close();
+ }
+ virtual bool StreamDataLeft()
+ {
+ return mrSink.StreamDataLeft();
+ }
+ virtual bool StreamClosed()
+ {
+ return mrSink.StreamClosed();
+ }
+
+private:
+ RateLimitingStream(const RateLimitingStream &rToCopy)
+ : mrSink(rToCopy.mrSink) { /* do not call */ }
+};
+
+#endif // RATELIMITINGSTREAM__H
diff --git a/lib/common/StreamableMemBlock.cpp b/lib/common/StreamableMemBlock.cpp
index cf431022..ce2e1f98 100644
--- a/lib/common/StreamableMemBlock.cpp
+++ b/lib/common/StreamableMemBlock.cpp
@@ -3,6 +3,10 @@
// File
// Name: StreamableMemBlock.cpp
// Purpose: Memory blocks which can be loaded and saved from streams
+<<<<<<< HEAD
+=======
+// with a header indicating the size of the block.
+>>>>>>> 0.12
// Created: 2003/09/05
//
// --------------------------------------------------------------------------
diff --git a/lib/common/StreamableMemBlock.h b/lib/common/StreamableMemBlock.h
index 250c0aea..3fcc62b3 100644
--- a/lib/common/StreamableMemBlock.h
+++ b/lib/common/StreamableMemBlock.h
@@ -2,7 +2,12 @@
//
// File
// Name: StreamableMemBlock.h
+<<<<<<< HEAD
// Purpose: Memory blocks which can be loaded and saved from streams
+=======
+// Purpose: Memory blocks which can be loaded and saved from streams,
+// with a header indicating the size of the block.
+>>>>>>> 0.12
// Created: 2003/09/05
//
// --------------------------------------------------------------------------
diff --git a/lib/common/Test.cpp b/lib/common/Test.cpp
index 56638058..b627ac18 100644
--- a/lib/common/Test.cpp
+++ b/lib/common/Test.cpp
@@ -21,6 +21,10 @@
#include <unistd.h>
#endif
+<<<<<<< HEAD
+=======
+#include "BoxTime.h"
+>>>>>>> 0.12
#include "Test.h"
bool TestFileExists(const char *Filename)
@@ -43,10 +47,17 @@ bool TestDirExists(const char *Filename)
}
// -1 if doesn't exist
+<<<<<<< HEAD
int TestGetFileSize(const char *Filename)
{
EMU_STRUCT_STAT st;
if(EMU_STAT(Filename, &st) == 0)
+=======
+int TestGetFileSize(const std::string& Filename)
+{
+ EMU_STRUCT_STAT st;
+ if(EMU_STAT(Filename.c_str(), &st) == 0)
+>>>>>>> 0.12
{
return st.st_size;
}
@@ -451,6 +462,7 @@ void wait_for_operation(int seconds, const char* message)
void safe_sleep(int seconds)
{
+<<<<<<< HEAD
BOX_TRACE("sleeping for " << seconds << " seconds");
#ifdef WIN32
@@ -482,5 +494,8 @@ void safe_sleep(int seconds)
"sleeping again");
}
#endif
+=======
+ ShortSleep(SecondsToBoxTime(seconds), true);
+>>>>>>> 0.12
}
diff --git a/lib/common/Test.h b/lib/common/Test.h
index 08ba4542..a09a64af 100644
--- a/lib/common/Test.h
+++ b/lib/common/Test.h
@@ -51,6 +51,7 @@ extern std::string bbackupd_args, bbstored_args, bbackupquery_args, test_args;
#define TEST_THAT_ABORTONFAIL(condition) {if(!(condition)) TEST_ABORT_WITH_MESSAGE("Condition [" #condition "] failed")}
// NOTE: The 0- bit is to allow this to work with stuff which has negative constants for flags (eg ConnectionException)
+<<<<<<< HEAD
#define TEST_CHECK_THROWS(statement, excepttype, subtype) \
{ \
bool didthrow = false; \
@@ -76,6 +77,35 @@ extern std::string bbackupd_args, bbstored_args, bbackupquery_args, test_args;
{ \
TEST_FAIL_WITH_MESSAGE("Didn't throw exception " #excepttype "(" #subtype ")") \
} \
+=======
+#define TEST_CHECK_THROWS(statement, excepttype, subtype) \
+ { \
+ bool didthrow = false; \
+ HideExceptionMessageGuard hide; \
+ BOX_TRACE("Exception logging disabled at " __FILE__ ":" \
+ << __LINE__); \
+ try \
+ { \
+ statement; \
+ } \
+ catch(excepttype &e) \
+ { \
+ if(e.GetSubType() != ((unsigned int)excepttype::subtype) \
+ && e.GetSubType() != (unsigned int)(0-excepttype::subtype)) \
+ { \
+ throw; \
+ } \
+ didthrow = true; \
+ } \
+ catch(...) \
+ { \
+ throw; \
+ } \
+ if(!didthrow) \
+ { \
+ TEST_FAIL_WITH_MESSAGE("Didn't throw exception " #excepttype "(" #subtype ")") \
+ } \
+>>>>>>> 0.12
}
// utility macro for comparing two strings in a line
@@ -91,7 +121,11 @@ extern std::string bbackupd_args, bbstored_args, bbackupquery_args, test_args;
\
if(_exp_str != _found_str) \
{ \
+<<<<<<< HEAD
BOX_WARNING("Expected <" << _exp_str << "> but found <" << \
+=======
+ BOX_ERROR("Expected <" << _exp_str << "> but found <" << \
+>>>>>>> 0.12
_found_str << ">"); \
\
std::ostringstream _oss3; \
@@ -127,20 +161,34 @@ extern std::string bbackupd_args, bbstored_args, bbackupquery_args, test_args;
} \
}
+<<<<<<< HEAD
+=======
+>>>>>>> 0.12
// utility macro for testing a line
#define TEST_LINE(_condition, _line) \
TEST_THAT(_condition); \
if (!(_condition)) \
{ \
+<<<<<<< HEAD
printf("Test failed on <%s>\n", _line.c_str()); \
+=======
+ std::ostringstream _ossl; \
+ _ossl << _line; \
+ std::string _line_str = _ossl.str(); \
+ printf("Test failed on <%s>\n", _line_str.c_str()); \
+>>>>>>> 0.12
}
bool TestFileExists(const char *Filename);
bool TestDirExists(const char *Filename);
// -1 if doesn't exist
+<<<<<<< HEAD
int TestGetFileSize(const char *Filename);
+=======
+int TestGetFileSize(const std::string& Filename);
+>>>>>>> 0.12
std::string ConvertPaths(const std::string& rOriginal);
int RunCommand(const std::string& rCommandLine);
bool ServerIsAlive(int pid);
diff --git a/lib/common/Timer.cpp b/lib/common/Timer.cpp
index 137ad45f..390ddf8e 100644
--- a/lib/common/Timer.cpp
+++ b/lib/common/Timer.cpp
@@ -8,12 +8,25 @@
//
// --------------------------------------------------------------------------
+<<<<<<< HEAD
#ifdef WIN32
#define _WIN32_WINNT 0x0500
#endif
#include "Box.h"
+=======
+#include "Box.h"
+
+#ifdef WIN32
+# ifndef _WIN32_WINNT
+# define _WIN32_WINNT 0x0500
+# elif _WIN32_WINNT < 0x0500
+# error Timers require at least Windows 2000 headers
+# endif
+#endif
+
+>>>>>>> 0.12
#include <signal.h>
#include <cstring>
@@ -26,7 +39,11 @@ std::vector<Timer*>* Timers::spTimers = NULL;
bool Timers::sRescheduleNeeded = false;
#define TIMER_ID "timer " << mName << " (" << this << ") "
+<<<<<<< HEAD
#define TIMER_ID_OF(t) "timer " << (t).GetName() << " (" << &(t) << ") "
+=======
+#define TIMER_ID_OF(t) "timer " << (t).GetName() << " (" << &(t) << ")"
+>>>>>>> 0.12
typedef void (*sighandler_t)(int);
@@ -115,6 +132,10 @@ void Timers::Add(Timer& rTimer)
{
ASSERT(spTimers);
ASSERT(&rTimer);
+<<<<<<< HEAD
+=======
+ BOX_TRACE(TIMER_ID_OF(rTimer) " added to global queue, rescheduling");
+>>>>>>> 0.12
spTimers->push_back(&rTimer);
Reschedule();
}
@@ -132,6 +153,10 @@ void Timers::Remove(Timer& rTimer)
{
ASSERT(spTimers);
ASSERT(&rTimer);
+<<<<<<< HEAD
+=======
+ BOX_TRACE(TIMER_ID_OF(rTimer) " removed from global queue, rescheduling");
+>>>>>>> 0.12
bool restart = true;
while (restart)
@@ -166,10 +191,13 @@ void Timers::RescheduleIfNeeded()
}
}
+<<<<<<< HEAD
#define FORMAT_MICROSECONDS(t) \
(int)(t / 1000000) << "." << \
(int)(t % 1000000) << " seconds"
+=======
+>>>>>>> 0.12
// --------------------------------------------------------------------------
//
// Function
@@ -232,6 +260,7 @@ void Timers::Reschedule()
if (timeToExpiry <= 0)
{
+<<<<<<< HEAD
/*
BOX_TRACE("timer " << *i << " has expired, "
"triggering it");
@@ -239,6 +268,11 @@ void Timers::Reschedule()
BOX_TRACE(TIMER_ID_OF(**i) "has expired, "
"triggering " <<
FORMAT_MICROSECONDS(-timeToExpiry) <<
+=======
+ BOX_TRACE(TIMER_ID_OF(**i) " has expired, "
+ "triggering " <<
+ BOX_FORMAT_MICROSECONDS(-timeToExpiry) <<
+>>>>>>> 0.12
" late");
rTimer.OnExpire();
spTimers->erase(i);
@@ -248,8 +282,13 @@ void Timers::Reschedule()
else
{
/*
+<<<<<<< HEAD
BOX_TRACE("timer " << *i << " has not "
"expired, triggering in " <<
+=======
+ BOX_TRACE(TIMER_ID_OF(**i) " has not expired, "
+ "triggering in " <<
+>>>>>>> 0.12
FORMAT_MICROSECONDS(timeToExpiry) <<
" seconds");
*/
@@ -290,8 +329,13 @@ void Timers::Reschedule()
}
else
{
+<<<<<<< HEAD
BOX_TRACE("timer: next event: " << nameOfNextEvent <<
" expires in " << FORMAT_MICROSECONDS(timeToNextEvent));
+=======
+ BOX_TRACE("timer: next event: " << nameOfNextEvent << " at " <<
+ FormatTime(timeNow + timeToNextEvent, false, true));
+>>>>>>> 0.12
}
struct itimerval timeout;
@@ -331,7 +375,11 @@ void Timers::SignalHandler(int unused)
// --------------------------------------------------------------------------
//
// Function
+<<<<<<< HEAD
// Name: Timer::Timer(size_t timeoutSecs,
+=======
+// Name: Timer::Timer(size_t timeoutMillis,
+>>>>>>> 0.12
// const std::string& rName)
// Purpose: Standard timer constructor, takes a timeout in
// seconds from now, and an optional name for
@@ -340,14 +388,20 @@ void Timers::SignalHandler(int unused)
//
// --------------------------------------------------------------------------
+<<<<<<< HEAD
Timer::Timer(size_t timeoutSecs, const std::string& rName)
: mExpires(GetCurrentBoxTime() + SecondsToBoxTime(timeoutSecs)),
+=======
+Timer::Timer(size_t timeoutMillis, const std::string& rName)
+: mExpires(0),
+>>>>>>> 0.12
mExpired(false),
mName(rName)
#ifdef WIN32
, mTimerHandle(INVALID_HANDLE_VALUE)
#endif
{
+<<<<<<< HEAD
#ifndef BOX_RELEASE_BUILD
if (timeoutSecs == 0)
{
@@ -370,72 +424,125 @@ Timer::Timer(size_t timeoutSecs, const std::string& rName)
Timers::Add(*this);
Start(timeoutSecs * MICRO_SEC_IN_SEC_LL);
}
+=======
+ Set(timeoutMillis, true /* isInit */);
+>>>>>>> 0.12
}
// --------------------------------------------------------------------------
//
// Function
// Name: Timer::Start()
+<<<<<<< HEAD
// Purpose: This internal function initialises an OS TimerQueue
// timer on Windows, while on Unixes there is only a
// single global timer, managed by the Timers class,
// so this method does nothing.
+=======
+// Purpose: This internal function recalculates the remaining
+// time (timeout) from the expiry time, and then calls
+// Start(timeoutMillis).
+>>>>>>> 0.12
// Created: 27/07/2008
//
// --------------------------------------------------------------------------
void Timer::Start()
{
+<<<<<<< HEAD
#ifdef WIN32
+=======
+>>>>>>> 0.12
box_time_t timeNow = GetCurrentBoxTime();
int64_t timeToExpiry = mExpires - timeNow;
if (timeToExpiry <= 0)
{
BOX_WARNING(TIMER_ID << "fudging expiry from -" <<
+<<<<<<< HEAD
FORMAT_MICROSECONDS(-timeToExpiry))
timeToExpiry = 1;
}
Start(timeToExpiry);
#endif
+=======
+ BOX_FORMAT_MICROSECONDS(-timeToExpiry))
+ timeToExpiry = 1;
+ }
+
+ Start(timeToExpiry / MICRO_SEC_IN_MILLI_SEC);
+>>>>>>> 0.12
}
// --------------------------------------------------------------------------
//
// Function
+<<<<<<< HEAD
// Name: Timer::Start(int64_t delayInMicros)
// Purpose: This internal function initialises an OS TimerQueue
// timer on Windows, with a specified delay already
// calculated to save us doing it again. Like
// Timer::Start(), on Unixes it does nothing.
+=======
+// Name: Timer::Start(int64_t timeoutMillis)
+// Purpose: This internal function adds this timer to the global
+// timer list, and on Windows it initialises an OS
+// TimerQueue timer for it.
+>>>>>>> 0.12
// Created: 27/07/2008
//
// --------------------------------------------------------------------------
+<<<<<<< HEAD
void Timer::Start(int64_t delayInMicros)
{
+=======
+void Timer::Start(int64_t timeoutMillis)
+{
+ ASSERT(mExpires != 0);
+ Timers::Add(*this);
+
+>>>>>>> 0.12
#ifdef WIN32
// only call me once!
ASSERT(mTimerHandle == INVALID_HANDLE_VALUE);
+<<<<<<< HEAD
int64_t delayInMillis = delayInMicros / 1000;
+=======
+>>>>>>> 0.12
// Windows XP always seems to fire timers up to 20 ms late,
// at least on my test laptop. Not critical in practice, but our
// tests are precise enough that they will fail if we don't
// correct for it.
+<<<<<<< HEAD
delayInMillis -= 20;
// Set a system timer to call our timer routine
if (CreateTimerQueueTimer(&mTimerHandle, NULL, TimerRoutine,
(PVOID)this, delayInMillis, 0, WT_EXECUTEINTIMERTHREAD)
+=======
+ timeoutMillis -= 20;
+
+ // Set a system timer to call our timer routine
+ if (CreateTimerQueueTimer(&mTimerHandle, NULL, TimerRoutine,
+ (PVOID)this, timeoutMillis, 0, WT_EXECUTEINTIMERTHREAD)
+>>>>>>> 0.12
== FALSE)
{
BOX_ERROR(TIMER_ID "failed to create timer: " <<
GetErrorMessage(GetLastError()));
mTimerHandle = INVALID_HANDLE_VALUE;
}
+<<<<<<< HEAD
+=======
+ else
+ {
+ BOX_INFO(TIMER_ID << "set for " << timeoutMillis << " ms");
+ }
+>>>>>>> 0.12
#endif
}
@@ -443,15 +550,29 @@ void Timer::Start(int64_t delayInMicros)
//
// Function
// Name: Timer::Stop()
+<<<<<<< HEAD
// Purpose: This internal function deletes the associated OS
// TimerQueue timer on Windows, and on Unixes does
// nothing.
+=======
+// Purpose: This internal function removes us from the global
+// list of timers, resets our expiry time, and on
+// Windows it deletes the associated OS TimerQueue timer.
+>>>>>>> 0.12
// Created: 27/07/2008
//
// --------------------------------------------------------------------------
void Timer::Stop()
{
+<<<<<<< HEAD
+=======
+ if (mExpires != 0)
+ {
+ Timers::Remove(*this);
+ }
+
+>>>>>>> 0.12
#ifdef WIN32
if (mTimerHandle != INVALID_HANDLE_VALUE)
{
@@ -481,10 +602,37 @@ Timer::~Timer()
BOX_TRACE(TIMER_ID "destroyed");
#endif
+<<<<<<< HEAD
Timers::Remove(*this);
Stop();
}
+=======
+ Stop();
+}
+
+void Timer::LogAssignment(const Timer &From)
+{
+ #ifndef BOX_RELEASE_BUILD
+ BOX_TRACE(TIMER_ID "initialised from " << TIMER_ID_OF(From));
+
+ if (From.mExpired)
+ {
+ BOX_TRACE(TIMER_ID "already expired, will not fire");
+ }
+ else if (From.mExpires == 0)
+ {
+ BOX_TRACE(TIMER_ID "has no expiry time, will not fire");
+ }
+ else
+ {
+ BOX_TRACE(TIMER_ID "will fire at " <<
+ FormatTime(From.mExpires, false, true));
+ }
+ #endif
+}
+
+>>>>>>> 0.12
// --------------------------------------------------------------------------
//
// Function
@@ -504,6 +652,7 @@ Timer::Timer(const Timer& rToCopy)
, mTimerHandle(INVALID_HANDLE_VALUE)
#endif
{
+<<<<<<< HEAD
#ifndef BOX_RELEASE_BUILD
if (mExpired)
{
@@ -527,6 +676,12 @@ Timer::Timer(const Timer& rToCopy)
if (!mExpired && mExpires != 0)
{
Timers::Add(*this);
+=======
+ LogAssignment(rToCopy);
+
+ if (!mExpired && mExpires != 0)
+ {
+>>>>>>> 0.12
Start();
}
}
@@ -545,6 +700,7 @@ Timer::Timer(const Timer& rToCopy)
Timer& Timer::operator=(const Timer& rToCopy)
{
+<<<<<<< HEAD
#ifndef BOX_RELEASE_BUILD
if (rToCopy.mExpired)
{
@@ -566,6 +722,10 @@ Timer& Timer::operator=(const Timer& rToCopy)
#endif
Timers::Remove(*this);
+=======
+ LogAssignment(rToCopy);
+
+>>>>>>> 0.12
Stop();
mExpires = rToCopy.mExpires;
@@ -574,7 +734,10 @@ Timer& Timer::operator=(const Timer& rToCopy)
if (!mExpired && mExpires != 0)
{
+<<<<<<< HEAD
Timers::Add(*this);
+=======
+>>>>>>> 0.12
Start();
}
@@ -584,6 +747,70 @@ Timer& Timer::operator=(const Timer& rToCopy)
// --------------------------------------------------------------------------
//
// Function
+<<<<<<< HEAD
+=======
+// Name: Timer::Reset(size_t timeoutMillis)
+// Purpose: Simple reset operation for an existing Timer. Avoids
+// the need to create a temporary timer just to modify
+// an existing one.
+// Created: 17/11/2012
+//
+// --------------------------------------------------------------------------
+
+void Timer::Reset(size_t timeoutMillis)
+{
+ Set(timeoutMillis, false /* isInit */);
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: Timer::Reset(size_t timeoutMillis)
+// Purpose: Internal set/reset operation for an existing Timer.
+// Shared by constructor and Reset().
+// Created: 17/11/2012
+//
+// --------------------------------------------------------------------------
+
+void Timer::Set(size_t timeoutMillis, bool isInit)
+{
+ Stop();
+ mExpired = false;
+
+ if (timeoutMillis == 0)
+ {
+ mExpires = 0;
+ }
+ else
+ {
+ mExpires = GetCurrentBoxTime() +
+ MilliSecondsToBoxTime(timeoutMillis);
+ }
+
+ #ifndef BOX_RELEASE_BUILD
+ if (timeoutMillis == 0)
+ {
+ BOX_TRACE(TIMER_ID << (isInit ? "initialised" : "reset") <<
+ " for " << timeoutMillis << " ms, will not fire");
+ }
+ else
+ {
+ BOX_TRACE(TIMER_ID << (isInit ? "initialised" : "reset") <<
+ " for " << timeoutMillis << " ms, to fire at " <<
+ FormatTime(mExpires, false, true));
+ }
+ #endif
+
+ if (mExpires != 0)
+ {
+ Start(timeoutMillis);
+ }
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+>>>>>>> 0.12
// Name: Timer::OnExpire()
// Purpose: Method called by Timers::Reschedule (on Unixes)
// on next poll after timer expires, or from
diff --git a/lib/common/Timer.h b/lib/common/Timer.h
index 42b2e00f..d3e46b2a 100644
--- a/lib/common/Timer.h
+++ b/lib/common/Timer.h
@@ -53,7 +53,11 @@ class Timers
class Timer
{
public:
+<<<<<<< HEAD
Timer(size_t timeoutSecs, const std::string& rName = "");
+=======
+ Timer(size_t timeoutMillis, const std::string& rName = "");
+>>>>>>> 0.12
virtual ~Timer();
Timer(const Timer &);
Timer &operator=(const Timer &);
@@ -67,6 +71,10 @@ public:
}
const std::string& GetName() const { return mName; }
+<<<<<<< HEAD
+=======
+ virtual void Reset(size_t timeoutMillis);
+>>>>>>> 0.12
private:
box_time_t mExpires;
@@ -74,8 +82,15 @@ private:
std::string mName;
void Start();
+<<<<<<< HEAD
void Start(int64_t delayInMicros);
void Stop();
+=======
+ void Start(int64_t timeoutMillis);
+ void Stop();
+ void LogAssignment(const Timer &From);
+ virtual void Set(size_t timeoutMillis, bool isReset);
+>>>>>>> 0.12
#ifdef WIN32
HANDLE mTimerHandle;
diff --git a/lib/common/UnixUser.cpp b/lib/common/UnixUser.cpp
index f81b474c..7e69b10a 100644
--- a/lib/common/UnixUser.cpp
+++ b/lib/common/UnixUser.cpp
@@ -31,13 +31,21 @@
// Created: 21/1/04
//
// --------------------------------------------------------------------------
+<<<<<<< HEAD
UnixUser::UnixUser(const char *Username)
+=======
+UnixUser::UnixUser(const std::string& Username)
+>>>>>>> 0.12
: mUID(0),
mGID(0),
mRevertOnDestruction(false)
{
// Get password info
+<<<<<<< HEAD
struct passwd *pwd = ::getpwnam(Username);
+=======
+ struct passwd *pwd = ::getpwnam(Username.c_str());
+>>>>>>> 0.12
if(pwd == 0)
{
THROW_EXCEPTION(CommonException, CouldNotLookUpUsername)
diff --git a/lib/common/UnixUser.h b/lib/common/UnixUser.h
index c895eb2a..361971b8 100644
--- a/lib/common/UnixUser.h
+++ b/lib/common/UnixUser.h
@@ -13,7 +13,11 @@
class UnixUser
{
public:
+<<<<<<< HEAD
UnixUser(const char *Username);
+=======
+ UnixUser(const std::string& Username);
+>>>>>>> 0.12
UnixUser(uid_t UID, gid_t GID);
~UnixUser();
private:
diff --git a/lib/common/Utils.cpp b/lib/common/Utils.cpp
index 6f21330d..3137d980 100644
--- a/lib/common/Utils.cpp
+++ b/lib/common/Utils.cpp
@@ -24,9 +24,23 @@
#include <cxxabi.h>
#endif
+<<<<<<< HEAD
#include "Utils.h"
#include "CommonException.h"
#include "Logging.h"
+=======
+#ifdef HAVE_DLFCN_H
+ #include <dlfcn.h>
+#endif
+
+#ifdef NEED_BOX_VERSION_H
+# include "BoxVersion.h"
+#endif
+
+#include "CommonException.h"
+#include "Logging.h"
+#include "Utils.h"
+>>>>>>> 0.12
#include "MemLeakFindOn.h"
@@ -73,16 +87,84 @@ void SplitString(const std::string &String, char SplitOn, std::vector<std::strin
}
#ifdef SHOW_BACKTRACE_ON_EXCEPTION
+<<<<<<< HEAD
void DumpStackBacktrace()
{
void *array[10];
size_t size = backtrace (array, 10);
char **strings = backtrace_symbols (array, size);
+=======
+static std::string demangle(const std::string& mangled_name)
+{
+ #ifdef HAVE_CXXABI_H
+ int status;
+
+#include "MemLeakFindOff.h"
+ char* result = abi::__cxa_demangle(mangled_name.c_str(),
+ NULL, NULL, &status);
+#include "MemLeakFindOn.h"
+
+ if (result == NULL)
+ {
+ if (status == 0)
+ {
+ BOX_WARNING("Demangle failed but no error: " <<
+ mangled_name);
+ }
+ else if (status == -1)
+ {
+ BOX_WARNING("Demangle failed with "
+ "memory allocation error: " <<
+ mangled_name);
+ }
+ else if (status == -2)
+ {
+ // Probably non-C++ name, don't demangle
+ /*
+ BOX_WARNING("Demangle failed with "
+ "with invalid name: " <<
+ mangled_name);
+ */
+ }
+ else if (status == -3)
+ {
+ BOX_WARNING("Demangle failed with "
+ "with invalid argument: " <<
+ mangled_name);
+ }
+ else
+ {
+ BOX_WARNING("Demangle failed with "
+ "with unknown error " << status <<
+ ": " << mangled_name);
+ }
+
+ return std::string(mangled_name);
+ }
+ else
+ {
+ std::string output = result;
+#include "MemLeakFindOff.h"
+ free(result);
+#include "MemLeakFindOn.h"
+ return output;
+ }
+ #else // !HAVE_CXXABI_H
+ return mangled_name;
+ #endif // HAVE_CXXABI_H
+}
+
+void DumpStackBacktrace()
+{
+ void *array[10];
+ size_t size = backtrace(array, 10);
+>>>>>>> 0.12
BOX_TRACE("Obtained " << size << " stack frames.");
for(size_t i = 0; i < size; i++)
{
+<<<<<<< HEAD
// Demangling code copied from
// cctbx_sources/boost_adaptbx/meta_ext.cpp, BSD license
@@ -155,6 +237,40 @@ void DumpStackBacktrace()
#include "MemLeakFindOn.h"
}
#endif
+=======
+ std::ostringstream output;
+ output << "Stack frame " << i << ": ";
+
+ #ifdef HAVE_DLADDR
+ Dl_info info;
+ int result = dladdr(array[i], &info);
+
+ if(result == 0)
+ {
+ BOX_LOG_SYS_WARNING("Failed to resolve "
+ "backtrace address " << array[i]);
+ output << "unresolved address " << array[i];
+ }
+ else if(info.dli_sname == NULL)
+ {
+ output << "unknown address " << array[i];
+ }
+ else
+ {
+ uint64_t diff = (uint64_t) array[i];
+ diff -= (uint64_t) info.dli_saddr;
+ output << demangle(info.dli_sname) << "+" <<
+ (void *)diff;
+ }
+ #else
+ output << "address " << array[i];
+ #endif // HAVE_DLADDR
+
+ BOX_TRACE(output.str());
+ }
+}
+#endif // SHOW_BACKTRACE_ON_EXCEPTION
+>>>>>>> 0.12
@@ -313,3 +429,34 @@ std::string FormatUsageLineStart(const std::string& rName,
return result.str();
}
+<<<<<<< HEAD
+=======
+
+std::string BoxGetTemporaryDirectoryName()
+{
+#ifdef WIN32
+ // http://msdn.microsoft.com/library/default.asp?
+ // url=/library/en-us/fileio/fs/creating_and_using_a_temporary_file.asp
+
+ DWORD dwRetVal;
+ char lpPathBuffer[1024];
+ DWORD dwBufSize = sizeof(lpPathBuffer);
+
+ // Get the temp path.
+ dwRetVal = GetTempPath(dwBufSize, // length of the buffer
+ lpPathBuffer); // buffer for path
+ if (dwRetVal > dwBufSize)
+ {
+ THROW_EXCEPTION(CommonException, TempDirPathTooLong)
+ }
+
+ return std::string(lpPathBuffer);
+#elif defined TEMP_DIRECTORY_NAME
+ return std::string(TEMP_DIRECTORY_NAME);
+#else
+ #error non-static temporary directory names not supported yet
+#endif
+}
+
+
+>>>>>>> 0.12
diff --git a/lib/common/Utils.h b/lib/common/Utils.h
index 8d98a520..8a938981 100644
--- a/lib/common/Utils.h
+++ b/lib/common/Utils.h
@@ -39,6 +39,11 @@ std::string FormatUsageBar(int64_t Blocks, int64_t Bytes, int64_t Max,
std::string FormatUsageLineStart(const std::string& rName,
bool MachineReadable);
+<<<<<<< HEAD
+=======
+std::string BoxGetTemporaryDirectoryName();
+
+>>>>>>> 0.12
#include "MemLeakFindOff.h"
#endif // UTILS__H
diff --git a/lib/common/ZeroStream.cpp b/lib/common/ZeroStream.cpp
index 9d87d76a..26fd62cb 100644
--- a/lib/common/ZeroStream.cpp
+++ b/lib/common/ZeroStream.cpp
@@ -152,7 +152,11 @@ void ZeroStream::Close()
// --------------------------------------------------------------------------
bool ZeroStream::StreamDataLeft()
{
+<<<<<<< HEAD
return false;
+=======
+ return (BytesLeftToRead() > 0);
+>>>>>>> 0.12
}
// --------------------------------------------------------------------------
diff --git a/lib/common/makeexception.pl.in b/lib/common/makeexception.pl.in
index 76b9b02b..593740da 100755
--- a/lib/common/makeexception.pl.in
+++ b/lib/common/makeexception.pl.in
@@ -191,7 +191,11 @@ unsigned int ${class}Exception::GetSubType() const throw()
const char *${class}Exception::what() const throw()
{
#ifdef EXCEPTION_CODENAMES_EXTENDED
+<<<<<<< HEAD
if(mSubType < 0 || mSubType > (sizeof(whats) / sizeof(whats[0])))
+=======
+ if(mSubType > (sizeof(whats) / sizeof(whats[0])))
+>>>>>>> 0.12
{
return "${class}";
}