9 #define _CRT_SECURE_NO_WARNINGS
19#include <mach/vm_statistics.h>
20#include <mach/host_info.h>
21#include <mach/task_info.h>
22#include <mach/thread_act.h>
23#include <sys/sysctl.h>
53 std::map<std::string, utils::Semaphore*>::iterator si;
68 std::map<std::string, utils::Event*>::iterator ei;
83 std::map<std::string, utils::Mutex*>::iterator mi;
132 return "String info";
134 return "Binary info";
136 return "Message info";
138 return "Unknown type";
143 if ((
stricmp(typeName,
"string") == 0) || (
stricmp(typeName,
"text") == 0))
145 else if (
stricmp(typeName,
"time") == 0)
147 else if ((
stricmp(typeName,
"integer") == 0) || (
stricmp(typeName,
"int") == 0))
149 else if ((
stricmp(typeName,
"float") == 0) || (
stricmp(typeName,
"double") == 0))
151 else if (
stricmp(typeName,
"binary") == 0)
153 else if (
stricmp(typeName,
"message") == 0)
155 else if (
stricmp(typeName,
"string info") == 0)
157 else if (
stricmp(typeName,
"binary info") == 0)
159 else if (
stricmp(typeName,
"message info") == 0)
242 return (
char*)
this+
sizeof(
LogEntry);
251 if (avail < (int32)len)
253 memcpy((
char*)
this+
sizeof(
LogEntry), text, len);
254 *((
char*)
this+
sizeof(
LogEntry)+len) = 0;
260 const char* text =
getText(len);
262 "{ \"time\": %llu, \"level\": %u, \"source\": %u, \"subject\": %u, \"type\": %u, \"text\": \"%s\" }",
268 const char* text =
getText(len);
270 "<entry time=\"%llu\" level=\"%u\" source=\"%u\" subject=\"%u\" type=\"%u\" text=\"%s\" />\n",
322 va_start(args, formatstring);
335 entry->
level = level;
346 std::cout << strline;
370 va_start(args, formatstring);
383 entry->
level = level;
404 static int macos_pthread_mutex_timedlock(pthread_mutex_t *mutex,
const struct timespec *abs_timeout)
414 while ((rv = pthread_mutex_trylock(mutex)) == EBUSY) {
416 gettimeofday(&now, NULL);
417 if (now.tv_sec > abs_timeout->tv_sec ||
418 (now.tv_sec == abs_timeout->tv_sec &&
419 (
long)(now.tv_usec) * 1000L >= abs_timeout->tv_nsec))
421 struct timespec nap = { 0, 1000000 };
422 nanosleep(&nap, NULL);
435 if (gettimeofday(&now, NULL) != 0)
438 timeout.tv_sec = now.tv_sec + (ms / 1000);
439 int64 us = (int64)(now.tv_usec) + ((ms % 1000)*1000);
440 while (us >= 1000000) {
444 timeout.tv_nsec = (long)(us * 1000);
450 if ( gettimeofday(&tv, NULL))
452 return (tv.tv_usec + tv.tv_sec * 1000000LL);
459 VOID CALLBACK
DrumBeatCallback(PVOID lpParameter, BOOLEAN TimerOrWaitFired) {
460 DrumBeatInfo* info = (DrumBeatInfo*) lpParameter;
462 if (!info->id || !info->createdTime || !info->started || !func)
465 if (!info->func(info->id, info->count))
506 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
507 dispatch_source_t timer_source = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
509 info->
handle = timer_source;
512 struct sigevent timer_event;
519 timer_event.sigev_notify = SIGEV_THREAD;
520 timer_event.sigev_notify_attributes = NULL;
522 timer_event.sigev_value.sival_ptr = (
void *)info;
523 int ret = timer_create(CLOCK_REALTIME, &timer_event, &info->
handle);
552 uint64 intervalNs = (uint64)info->
interval * 1000000;
553 dispatch_source_set_timer(info->
handle, dispatch_time(DISPATCH_TIME_NOW, (int64_t)intervalNs), intervalNs, 0);
555 dispatch_source_set_event_handler(info->
handle, ^{
557 if (!inf->func(inf->id, inf->count))
558 StopDrumBeat(inf->id);
560 dispatch_resume(info->
handle);
564 struct itimerspec newtv;
566 newtv.it_interval.tv_sec = p / 1000000;
567 newtv.it_interval.tv_nsec = (p % 1000000)*1000;
568 newtv.it_value.tv_sec = p / 1000000;
569 newtv.it_value.tv_nsec = (p % 1000000)*1000;
571 int ret = timer_settime(info->
handle, 0, &newtv, NULL);
592 DeleteTimerQueueTimer(NULL, info->
handle, NULL);
598 dispatch_suspend(info->
handle);
602 struct itimerspec newtv;
603 memset(&newtv, 0,
sizeof(itimerspec));
604 int ret = timer_settime(info->
handle, 0, &newtv, NULL);
628 dispatch_suspend(info->
handle);
629 dispatch_source_cancel(info->
handle);
630 dispatch_release(info->
handle);
635 timer_delete(info->
handle);
649bool EnterMutex(
const char* name, uint32 ms,
bool autocreate) {
666 mutex =
new Mutex(name);
678 mutex =
new Mutex(name);
686 return (mutex->
enter(ms));
699 return (i->second->leave());
748 semaphore = i->second;
761 semaphore = i->second;
787 semaphore = i->second;
800 semaphore = i->second;
801 return (semaphore->
wait(ms));
823 semaphore = i->second;
832 semaphore = i->second;
833 return (semaphore->
signal());
881 event =
new Event(name);
893 event =
new Event(name);
914 return (i->second->signal());
960 mutex =
new pthread_mutex_t;
961 pthread_mutexattr_t attr;
962 pthread_mutexattr_init(&attr);
963 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
964 pthread_mutex_init(
mutex, &attr);
972 pthread_mutexattr_destroy(&attr);
985 mutex = ::CreateMutex(NULL,
FALSE, this->name);
999 mutex = (pthread_mutex_t*) data;
1006 mutex = (pthread_mutex_t*) data;
1007 pthread_mutexattr_t attr;
1008 pthread_mutexattr_init(&attr);
1009 pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
1010 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
1011 pthread_mutex_init(
mutex, &attr);
1012 pthread_mutexattr_destroy(&attr);
1019bool CloseMutexHandle(HANDLE mutex) {
1025 __except (EXCEPTION_EXECUTE_HANDLER) {
1039 CloseMutexHandle(
mutex);
1044 pthread_mutex_destroy(
mutex);
1050 pthread_mutex_destroy(
mutex);
1062 if ( (reply = WaitForSingleObject(
mutex, INFINITE)) == WAIT_OBJECT_0) {
1071 if (reply != WAIT_ABANDONED) {
1080 int error = pthread_mutex_lock(
mutex);
1101 if ((reply = WaitForSingleObject(
mutex, timeout)) == WAIT_OBJECT_0) {
1117 if (reply == WAIT_TIMEOUT) {
1118 LogPrint(0,
LOG_SYSTEM, 0,
"[%u]Mutex enter timeout[%p](%s) - currently held by %u, count %u, total %u",
1123 else if (reply == WAIT_FAILED) {
1124 DWORD mtxErr = GetLastError();
1125 if (mtxErr == ERROR_INVALID_HANDLE)
1127 char* msg =
new char[2048];
1128 int length = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
1129 NULL, mtxErr, 0, msg, 2048, NULL);
1131 LogPrint(0,
LOG_SYSTEM, 0,
"[%u]Mutex enter failed[%p](%s): %s - currently held by %u, count %u, total %u",
1137 LogPrint(0,
LOG_SYSTEM,0,
"[%u]Mutex enter error[%p](%s): %d - currently held by %u, count %u, total %u",
1145 int error = macos_pthread_mutex_timedlock(
mutex, &ts);
1147 int error = pthread_mutex_timedlock(
mutex, &ts);
1157 else if (error == EINVAL) {
1159 errorMsg ? errorMsg :
"-", error, timeout, (uint64)(ts.tv_sec), (int64)(ts.tv_nsec));
1163 LogPrint(0,
LOG_SYSTEM,0,
"Mutex enter timeout %u: '%s' (%d) [%p] - held by %u", timeout, errorMsg ? errorMsg :
"-", error,
this,
osid);
1199 uint32 osid2 =
osid;
1207 if (ReleaseMutex(
mutex) != 0) {
1224 if (pthread_mutex_unlock(
mutex) != 0)
1270 semaphore_impl = dispatch_semaphore_create(0);
1295 snprintf(shmemname,
sizeof(shmemname),
"Semaphore_%s",
name);
1300 pthread_mutex_t* m = (pthread_mutex_t*)data;
1301 pthread_mutexattr_t attr;
1302 pthread_mutexattr_init(&attr);
1303 pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
1304 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
1305 pthread_mutex_init(m, &attr);
1306 pthread_mutexattr_destroy(&attr);
1307 pthread_cond_t* c = (pthread_cond_t*)(data +
sizeof(pthread_mutex_t));
1308 pthread_condattr_t cattr;
1309 pthread_condattr_init(&cattr);
1310 pthread_condattr_setpshared(&cattr, PTHREAD_PROCESS_SHARED);
1311 pthread_cond_init(c, &cattr);
1312 pthread_condattr_destroy(&cattr);
1313 uint32* cnt = (uint32*)(data +
sizeof(pthread_mutex_t) +
sizeof(pthread_cond_t));
1317 semaphore_impl = data;
1321 semaphore = sem_open(this->name, O_CREAT, 0666, 1);
1341 dispatch_release((dispatch_semaphore_t)semaphore_impl);
1342 semaphore_impl = NULL;
1345 if (semaphore_impl) {
1347 semaphore_impl = NULL;
1367 return (WaitForSingleObject(
semaphore, INFINITE) == WAIT_OBJECT_0);
1371 return dispatch_semaphore_wait((dispatch_semaphore_t)semaphore_impl, DISPATCH_TIME_FOREVER) == 0;
1373 char* data = (
char*)semaphore_impl;
1374 if (!data)
return false;
1375 pthread_mutex_t* m = (pthread_mutex_t*)data;
1376 pthread_cond_t* c = (pthread_cond_t*)(data +
sizeof(pthread_mutex_t));
1377 uint32* cnt = (uint32*)(data +
sizeof(pthread_mutex_t) +
sizeof(pthread_cond_t));
1378 pthread_mutex_lock(m);
1380 pthread_cond_wait(c, m);
1382 pthread_mutex_unlock(m);
1394 return (WaitForSingleObject(
semaphore, timeout) == WAIT_OBJECT_0);
1398 dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, (int64_t)timeout * 1000000);
1399 return dispatch_semaphore_wait((dispatch_semaphore_t)semaphore_impl, when) == 0;
1402 char* data = (
char*)semaphore_impl;
1403 if (!data)
return false;
1404 pthread_mutex_t* m = (pthread_mutex_t*)data;
1405 pthread_cond_t* c = (pthread_cond_t*)(data +
sizeof(pthread_mutex_t));
1406 uint32* cnt = (uint32*)(data +
sizeof(pthread_mutex_t) +
sizeof(pthread_cond_t));
1407 pthread_mutex_lock(m);
1411 int r = pthread_cond_timedwait(c, m, &t);
1412 if (r == ETIMEDOUT) {
1413 pthread_mutex_unlock(m);
1417 pthread_mutex_unlock(m);
1422 pthread_mutex_unlock(m);
1436 return (ReleaseSemaphore(
1443 return dispatch_semaphore_signal((dispatch_semaphore_t)semaphore_impl) != 0;
1445 char* data = (
char*)semaphore_impl;
1446 if (!data)
return false;
1447 pthread_mutex_t* m = (pthread_mutex_t*)data;
1448 pthread_cond_t* c = (pthread_cond_t*)(data +
sizeof(pthread_mutex_t));
1449 uint32* cnt = (uint32*)(data +
sizeof(pthread_mutex_t) +
sizeof(pthread_cond_t));
1450 pthread_mutex_lock(m);
1452 pthread_cond_signal(c);
1453 pthread_mutex_unlock(m);
1488 event = CreateEvent(
1494 event =
new pthread_cond_t;
1495 pthread_cond_init(
event, NULL);
1497 mutex =
new pthread_mutex_t;
1498 pthread_mutex_init(
mutex, NULL);
1508 event = CreateEvent(
1516 mutex = (pthread_mutex_t*) data;
1517 event = (pthread_cond_t*) (data +
sizeof(pthread_mutex_t));
1523 mutex = (pthread_mutex_t*) data;
1524 pthread_mutexattr_t attr;
1525 pthread_mutexattr_init(&attr);
1526 pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
1527 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
1528 pthread_mutex_init(
mutex, &attr);
1529 pthread_mutexattr_destroy(&attr);
1531 event = (pthread_cond_t*) (data +
sizeof(pthread_mutex_t));
1532 pthread_condattr_t cattr;
1533 pthread_condattr_init(&cattr);
1534 pthread_condattr_setpshared(&cattr, PTHREAD_PROCESS_SHARED);
1536 pthread_cond_init(
event, &cattr);
1537 pthread_mutexattr_destroy(&attr);
1552 pthread_cond_destroy(
event);
1554 pthread_mutex_destroy(
mutex);
1558 pthread_cond_destroy(
event);
1559 pthread_mutex_destroy(
mutex);
1570 return (WaitForSingleObject(
event, INFINITE) == WAIT_OBJECT_0);
1572 pthread_mutex_lock(
mutex);
1574 pthread_mutex_unlock(
mutex);
1581 return (WaitForSingleObject(
event, timeout) == WAIT_OBJECT_0);
1583 pthread_mutex_lock(
mutex);
1586 int r = pthread_cond_timedwait(
event,
mutex, &t);
1587 pthread_mutex_unlock(
mutex);
1594 if (!SetEvent(
event))
1600 pthread_mutex_lock(
mutex);
1601 int r = pthread_cond_broadcast(
event);
1602 pthread_mutex_unlock(
mutex);
1634 timers =
new std::map<uint32, Timer*>;
1638 (*timers)[globalID] =
this;
1646 std::map<uint32, TimerSchedule*>::iterator it = schedules.begin();
1647 std::map<uint32, TimerSchedule*>::iterator itEnd = schedules.end();
1653 std::list<TimerSchedule*>::iterator it2 = oldSchedules.begin();
1654 std::list<TimerSchedule*>::iterator it2End = oldSchedules.end();
1655 while (it2 != it2End)
1657 oldSchedules.clear();
1664 if (schedules[
id]) {
1673 schedule->
start = start;
1674 schedule->
end = end;
1676 schedules[id] = schedule;
1679 uint32 firstDelay = 0;
1680 if (start && (start > now))
1681 firstDelay = (uint32)(start - now)/1000;
1685 if (!CreateTimerQueueTimer(&schedule->
handle, NULL,
TimerCallback, schedule, firstDelay, interval, WT_EXECUTEINTIMERTHREAD)) {
1686 schedules[id] = NULL;
1693 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
1694 dispatch_source_t timer_source = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
1695 if (!timer_source) {
1696 schedules[id] = NULL;
1701 schedule->
handle = timer_source;
1702 uint64 firstDelayNs = (uint64)firstDelay * 1000000;
1703 uint64 intervalNs = (uint64)interval * 1000000;
1704 dispatch_source_set_timer(timer_source, dispatch_time(DISPATCH_TIME_NOW, (int64_t)firstDelayNs), intervalNs, 0);
1705 dispatch_source_set_event_handler(timer_source, ^{
1715 dispatch_resume(timer_source);
1717 struct sigaction sa;
1718 struct sigevent timer_event;
1720 sigemptyset(&sa.sa_mask);
1721 sa.sa_flags = SA_SIGINFO;
1723 sigaction(SIGRTMIN, &sa, NULL);
1725 timer_event.sigev_notify = SIGEV_SIGNAL;
1726 timer_event.sigev_signo = SIGRTMIN;
1727 timer_event.sigev_value.sival_ptr = (
void *)schedule;
1728 if (timer_create(CLOCK_REALTIME, &timer_event, &schedule->
handle) != 0) {
1729 schedules[id] = NULL;
1735 struct itimerspec newtv;
1738 uint64 period = interval * 1000;
1739 newtv.it_value.tv_sec = firstDelay / 1000000;
1740 newtv.it_value.tv_nsec = (firstDelay % 1000000)*1000;
1741 newtv.it_interval.tv_sec = period / 1000000;
1742 newtv.it_interval.tv_nsec = (period % 1000000)*1000;
1744 if (timer_settime(schedule->
handle, 0, &newtv, NULL) != 0) {
1745 timer_delete(schedule->
handle);
1746 schedules[id] = NULL;
1751 sigemptyset(&allsigs);
1768 schedules[id] = NULL;
1771 DeleteTimerQueueTimer(NULL, schedule->
handle, NULL);
1774 dispatch_source_cancel(schedule->
handle);
1775 dispatch_release(schedule->
handle);
1777 timer_delete(schedule->
handle);
1781 oldSchedules.push_back(schedule);
1795 trigger->
id = schedule->
id;
1798 triggers.push(trigger);
1801 if ( schedule->
end && ((int32)(schedule->
end - trigger->
time) < (int32)schedule->
interval))
1814 while (!triggers.size()) {
1816 if ( (timeleft = (int32)timeout -
GetTimeAgeMS(start)) <= 0)
1818 semaphore.wait((uint32)timeleft);
1822 trigger = triggers.front();
1825 time = trigger->
time;
1832 void CALLBACK
TimerCallback(PVOID arg, BOOLEAN TimerOrWaitFired) {
1869 if (!timer->
addTimer(1, 1000, now+50000, now+10000000)) {
1874 if (!timer->
addTimer(2, 2000, now+55000, now+15000000)) {
1879 if (!timer->
addTimer(3, 3000, now+60000, now+20000000)) {
1886 uint32 triggers = 0;
1887 double totalLatencyUs = 0;
1891 for (uint32 n = 0; n < 60; n++) {
1895 totalLatencyUs += (double)(now - time);
1896 unittest::detail(
"Timer %u triggered %.3f ms ago",
id, (now - time) / 1000.0);
1907 if (triggers == 0) {
1914 unittest::metric(
"avg_trigger_latency", totalLatencyUs / (
double)triggers,
"us",
false);
1924 uint32 slotCount = 350;
1926 char* bitField =
new char[bitFieldSize];
1935 unittest::fail(
"GetLastOccupiedBitLoc: loc %u, expected: false", loc);
1941 unittest::fail(
"GetFirstFreeBitLoc failed: %u, expected: 0", loc);
1946 unittest::fail(
"GetFirstFreeBitLocN failed: %u, expected: 0", loc);
1960 unittest::fail(
"GetFirstFreeBitLoc 2 failed: %u, expected: 0", loc);
1965 unittest::fail(
"GetFirstFreeBitLocN 2 failed: %u, expected: 0", loc);
1972 unittest::fail(
"GetFirstFreeBitLocN 3 failed: %u, expected: 11", loc);
1977 unittest::fail(
"GetLastOccupiedBitLoc: loc %u, expected: 10", loc);
1996 unittest::fail(
"GetFirstFreeBitLoc 4 failed: %u, expected: 1", loc);
2001 unittest::fail(
"GetFirstFreeBitLocN 5 failed: %u, expected: 11", loc);
2006 unittest::fail(
"GetFirstFreeBitLocN 6 failed: %u, expected: 11", loc);
2011 unittest::fail(
"GetFirstFreeBitLocN 7 failed: %u, expected: 150", loc);
2016 unittest::fail(
"GetLastOccupiedBitLoc: loc %u, expected: 149", loc);
2030 unittest::fail(
"GetFirstFreeBitLoc 8 failed: %u, expected: 1", loc);
2035 unittest::fail(
"GetFirstFreeBitLocN 9 failed: %u, expected: 11", loc);
2040 unittest::fail(
"GetFirstFreeBitLocN 10 failed: %u, expected: 11", loc);
2045 unittest::fail(
"GetFirstFreeBitLocN 11 failed: %u, expected: 250", loc);
2050 unittest::fail(
"GetFirstFreeBitLocN 12 failed: %u, expected: false", loc);
2056 unittest::fail(
"GetLastOccupiedBitLoc: loc %u, expected: 249", loc);
2070 unittest::fail(
"GetFirstFreeBitLoc 13 failed: %u, expected: 1", loc);
2075 unittest::fail(
"GetFirstFreeBitLocN 14 failed: %u, expected: 11", loc);
2080 unittest::fail(
"GetFirstFreeBitLocN 15 failed: %u, expected: 11", loc);
2085 unittest::fail(
"GetFirstFreeBitLocN 16 failed: %u, expected: 11", loc);
2090 unittest::fail(
"GetFirstFreeBitLocN 17 failed: %u, expected: 250", loc);
2095 unittest::fail(
"GetLastOccupiedBitLoc: loc %u, expected: 249", loc);
2108 unittest::fail(
"GetFirstFreeBitLoc 18 failed: %u, expected: 1", loc);
2113 unittest::fail(
"GetFirstFreeBitLocN 19 failed: %u, expected: 11", loc);
2118 unittest::fail(
"GetFirstFreeBitLocN 20 failed: %u, expected: 11", loc);
2123 unittest::fail(
"GetFirstFreeBitLocN 21 failed: %u, expected: 250", loc);
2128 unittest::fail(
"GetFirstFreeBitLocN 22 failed: %u, expected: 250", loc);
2133 unittest::fail(
"GetFirstFreeBitLocN 23 failed: %u, expected: false", loc);
2138 unittest::fail(
"GetLastOccupiedBitLoc: loc %u, expected: 249", loc);
2165 hMapFile = CreateFileMapping(
2166 INVALID_HANDLE_VALUE,
2169 (uint32)((size >> 32) & 0xffffffff),
2170 (uint32)(size & 0xffffffff),
2173 if (hMapFile == NULL) {
2179 pBuf = (
char*) MapViewOfFile(hMapFile,
2180 FILE_MAP_ALL_ACCESS,
2184 int error = GetLastError();
2185 CloseHandle(hMapFile);
2192 (*SharedMemoryFileHandleMap)[pBuf] = hMapFile;
2201 int fd = open(memname, O_CREAT | O_RDWR, 0666);
2203 LogPrint(0,
LOG_SYSTEM,0,
"Couldn't create shared memory: '%s' (err: %d)...", memname, errno);
2207 if (ftruncate(fd, size) == -1) {
2208 LogPrint(0,
LOG_SYSTEM,0,
"Couldn't truncate shared memory: '%s' size: %u (%d) (err: %d)...", memname, size, fd, errno);
2213 char* pBuf = (
char*)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
2214 if (pBuf == MAP_FAILED) {
2215 LogPrint(0,
LOG_SYSTEM,0,
"Couldn't map created shared memory: '%s' (err: %d)...", memname, errno);
2222 (*SharedMemoryFileHandleMap)[pBuf] = std::string(memname);
2229 int fd = shm_open(memname, O_CREAT | O_RDWR, 0666);
2231 LogPrint(0,
LOG_SYSTEM,0,
"Couldn't create shared memory: '%s' (err: %d)...", memname, errno);
2235 if (ftruncate(fd, size) == -1) {
2236 LogPrint(0,
LOG_SYSTEM,0,
"Couldn't truncate shared memory: '%s' size: %u (%d) (err: %d)...", memname, size, fd, errno);
2241 char* pBuf = (
char*)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
2242 if (pBuf == MAP_FAILED) {
2243 LogPrint(0,
LOG_SYSTEM,0,
"Couldn't map created shared memory: '%s' (err: %d)...", memname, errno);
2250 (*SharedMemoryFileHandleMap)[pBuf] = memname;
2268 hMapFile = OpenFileMapping(
2269 FILE_MAP_ALL_ACCESS,
2273 if (hMapFile == NULL) {
2279 pBuf = (
char*) MapViewOfFile(hMapFile,
2280 FILE_MAP_ALL_ACCESS,
2287 CloseHandle(hMapFile);
2295 (*SharedMemoryFileHandleMap)[pBuf] = hMapFile;
2302 int fd = open(memname, O_RDWR);
2308 uint64 memSize = size;
2315 if (fstat(fd, &st) == -1 || st.st_size <= 0) {
2320 memSize = (uint64) st.st_size;
2322 pBuf = (
char*)mmap(NULL, memSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
2323 if (pBuf == MAP_FAILED) {
2330 (*SharedMemoryFileHandleMap)[pBuf] = std::string(memname);
2337 int fd = shm_open(memname, O_RDWR, 0666);
2343 uint64 memSize = size;
2349 if (fstat(fd, &st) == -1 || st.st_size <= 0) {
2350 LogPrint(0,
LOG_SYSTEM,0,
"Couldn't stat opened shared memory: '%s' (err: %d)...", memname, errno);
2355 memSize = (uint64) st.st_size;
2357 pBuf = (
char*)mmap(NULL, memSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
2358 if (pBuf == MAP_FAILED) {
2365 (*SharedMemoryFileHandleMap)[pBuf] = memname;
2378 UnmapViewOfFile(data);
2416 uint8 *data = (uint8*)&rval;
2417 data[0] = (uint8)(*input >> 56);
2418 data[1] = (uint8)(*input >> 48);
2419 data[2] = (uint8)(*input >> 40);
2420 data[3] = (uint8)(*input >> 32);
2421 data[4] = (uint8)(*input >> 24);
2422 data[5] = (uint8)(*input >> 16);
2423 data[6] = (uint8)(*input >> 8);
2424 data[7] = (uint8)(*input >> 0);
2436 return ((bitsize + 31) >> 5) << 2;
2440 memset(bitfield, 255, bytesize);
2446 uint32* data = (uint32*)bitfield;
2447 uint32* src = (uint32*)data;
2450 while ((*src == 0)) {
2452 if (src - data > (int32)bytesize)
2456 _BitScanForward((DWORD*)&index, *src);
2458 index = ffsl(*src) - 1;
2460 index = ffsl(*src) - 1;
2463 loc = ((uint32)(src-data)*32) + index;
2469 uint32* data = (uint32*)bitfield;
2470 uint32* src = (uint32*)data;
2476 uint32 foundBlock = 0;
2478 while ((*src == 0)) {
2480 if (src - data > (int32)bytesize)
2484 _BitScanForward((DWORD*)&index, *src);
2486 index = ffsl(*src) - 1;
2488 index = ffsl(*src) - 1;
2490 loc = ((uint32)(src - data) * 32) + index;
2494 if ((l + 7) >> 3 > bytesize)
2497 uint32* word = (uint32*)bitfield + (l >> 5);
2500 val = (_bittest((
long*)word, n) != 0);
2502 val = (bit)((*word & (
static_cast<uint32
>(1) << n)) != 0);
2504 val = (bit)((*word & (
static_cast<uint32
>(1) << n)) != 0);
2512 if (foundBlock >= num)
2514 if (index % 32 == 0) {
2515 while ((num - foundBlock > 31) && (*src ==
MAXVALUINT32)) {
2520 if ((num - foundBlock > 15) && (*(uint16*)src ==
MAXVALUINT16)) {
2524 if ((num - foundBlock > 7) && (*((
unsigned char*)src+2) == 255)) {
2530 else if ((num - foundBlock > 7) && (*(
unsigned char*)src == 255)) {
2536 if (foundBlock >= num)
2543 if (index % 32 == 0)
2546 if ((l + 7) >> 3 > bytesize)
2549 uint32* word = (uint32*)bitfield + (l >> 5);
2552 val = (_bittest((
long*)word, n) != 0);
2554 val = (bit)((*word & (
static_cast<uint32
>(1) << n)) != 0);
2556 val = (bit)((*word & (
static_cast<uint32
>(1) << n)) != 0);
2561 src += (uint32)(index / 32);
2569bool SetBit(uint32 loc, bit value,
char* bitfield, uint32 bytesize) {
2570 if ((loc + 7) >> 3 > bytesize)
2572 uint32* data = (uint32*)bitfield;
2573 uint32* src = (uint32*)data;
2582 _bittestandset((
long*)src, n);
2584 _bittestandreset((
long*)src, n);
2601bool SetBitN(uint32 loc, uint32 num, bit value,
char* bitfield, uint32 bytesize) {
2602 if ((loc + 7) >> 3 > bytesize)
2604 uint32* data = (uint32*)bitfield;
2605 uint32* src = (uint32*)data;
2612 for (uint32 i = 0; i < num; i++) {
2614 while (num - i > 31) {
2624 *((
unsigned char*)src + 2) = (value ? 255 : 0);
2629 else if (num - i > 7) {
2630 *(
unsigned char*)src = (value ? 255 : 0);
2639 _bittestandset((
long*)src, n);
2641 _bittestandreset((
long*)src, n);
2664bool GetBit(uint32 loc,
const char* bitfield, uint32 bytesize, bit& val) {
2665 if ((loc + 7) >> 3 > bytesize)
2667 uint32* data = (uint32*)bitfield;
2668 uint32* src = (uint32*)data;
2676 val = (_bittest((
long*)src, n) != 0);
2678 uint32 mask =
static_cast<uint32
>( 1 << n ) ;
2679 val = (bit)(mask & *src);
2681 uint32 mask =
static_cast<uint32
>(1 << n);
2682 val = (bit)(mask & *src);
2690 uint32* data = (uint32*)bitfield;
2691 uint32* src = (uint32*)(bitfield + bytesize - 4);
2695 while ((*src == 0xFFFFFFFF)) {
2702 _BitScanReverse((DWORD*)&index, ~(*src));
2704 index = 31 - __builtin_clz(~(*src));
2706 index = 31 - __builtin_clz(~(*src));
2708 loc = ((uint32)(src - data) * 32) + index;
2716 str.reserve(bytesize * 9);
2719 for(i = 0; i < bytesize; i++) {
2720 for(j = 0; j < 8; j++) {
2722 str.push_back((bitfield[i] & (1 << j)) ?
'_' :
'0');
2735 uint32 strSize = (uint32)str.size();
2740 return StringFormat(
"%s [%u]: %s\n", title, size, str.c_str());
2749 while (loc < strSize-1) {
2750 str2 += str.substr(loc, 36) +
"\n";
2754 str2 += str.substr(loc) +
"\n";
2764 return InterlockedIncrement((LONG*)&v);
2767 __sync_add_and_fetch(&v, 1);
2774 return InterlockedIncrement64((LONGLONG*)&v);
2777 __sync_add_and_fetch(&v, 1);
2784 return InterlockedDecrement((LONG*)&v);
2787 __sync_add_and_fetch(&v, -1);
2794 return InterlockedDecrement64((LONGLONG*)&v);
2797 __sync_add_and_fetch(&v, -1);
2813 std::string tracePrint;
2816 std::list<std::string>::iterator i = trace.begin(), e = trace.end();
2820 if ((++line > startLine) && (!endLine || (line <= endLine)))
2821 tracePrint +=
" -" + (*i) +
"\n";
2828 std::list<std::string> trace;
2857 size = backtrace(array, 200);
2858 strings = backtrace_symbols(array, size);
2859 for (i = 0; i < size; i++)
2860 trace.push_back(strings[i]);
2875 (LPTHREAD_START_ROUTINE) func,
2880 if (thread != NULL) {
2881 osID = ::GetThreadId(thread);
2888 pthread_attr_t attr;
2889 pthread_attr_init(&attr);
2891 pthread_attr_setschedpolicy(&attr, SCHED_RR);
2892 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
2896 if ((res=pthread_create(&thread, &attr, func, args)) != 0)
2899 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
2900 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate);
2903 pthread_threadid_np(thread, &tid);
2906 osID = (uint32) thread;
2916 int res = WaitForSingleObject(hThread, 0);
2917 if (res != WAIT_OBJECT_0)
2930 return (pthread_kill(hThread, 0) != 0);
2933 int res = pthread_tryjoin_np(hThread, NULL);
2947 int res = WaitForSingleObject(hThread, timeoutMS ? timeoutMS : INFINITE);
2948 if(res != WAIT_OBJECT_0)
2958 return (pthread_join(hThread, NULL) == 0);
2966 while (pthread_kill(hThread, 0) == 0) {
2967 if (waited >= timeoutMS)
2973 pthread_join(hThread, NULL);
2979 if (pthread_timedjoin_np(hThread, NULL, &ts) != 0)
2985 if (pthread_join(hThread, NULL) != 0)
3002 char* msg =
new char[2048];
3003 int length = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
3004 NULL, GetLastError(), 0, msg,
sizeof(msg), NULL);
3010 CloseHandle(hThread);
3016 pthread_cancel(hThread);
3017 if (pthread_join(hThread, NULL) != 0)
3025 return (SuspendThread(hThread) >= 0);
3027 return (pthread_kill(hThread, SIGSTOP) == 0);
3035 while ( (count = ResumeThread(hThread)) > 1);
3036 return (count == 1);
3038 return (pthread_kill(hThread, SIGCONT) == 0);
3049 tid = ::GetCurrentThreadId();
3054 pthread_threadid_np(pthread_self(), &
id);
3057 tid = (uint32) pthread_self();
3065 tid = ::GetCurrentThreadId();
3070 if (pthread_threadid_np(pthread_self(), &
id) != 0)
3074 int id = syscall(SYS_gettid);
3088 thread = pthread_self();
3096 if (!GetExitCodeThread(hThread, &code))
3098 return (code == STILL_ACTIVE);
3111 return (pthread_kill(hThread, 0) == 0);
3114 return (pthread_tryjoin_np(hThread, NULL) != 0);
3123 #if defined RUSAGE_THREAD
3137 uint64 cpuTicks = 0;
3138 LARGE_INTEGER perfFreq;
3139 if (!QueryPerformanceFrequency(&perfFreq) || !perfFreq.QuadPart)
3141 if (!QueryThreadCycleTime(hThread, &cpuTicks))
3143 ticks = cpuTicks / (perfFreq.QuadPart / 1000000);
3156 mach_port_t machThread = pthread_mach_thread_np(hThread);
3157 if (machThread == MACH_PORT_NULL)
3159 thread_basic_info_data_t info;
3160 mach_msg_type_number_t infoCount = THREAD_BASIC_INFO_COUNT;
3161 if (thread_info(machThread, THREAD_BASIC_INFO, (thread_info_t)&info, &infoCount) != KERN_SUCCESS)
3163 ticks = (uint64)info.user_time.seconds * 1000000 + info.user_time.microseconds
3164 + (uint64)info.system_time.seconds * 1000000 + info.system_time.microseconds;
3168 if (pthread_getcpuclockid(hThread, &cid) != 0)
3171 if (clock_gettime(cid, &ts) != -1 ) {
3172 ticks = ((uint64)ts.tv_sec * 1000000) + (ts.tv_nsec/1000);
3187 uint64 cpuTicks = 0;
3188 LARGE_INTEGER perfFreq;
3189 if (!QueryPerformanceFrequency(&perfFreq) || !perfFreq.QuadPart)
3193 ticks = cpuTicks / (perfFreq.QuadPart / 1000000);
3205 if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts) != -1 ) {
3206 ticks = ((uint64)ts.tv_sec * 1000000) + (ts.tv_nsec/1000);
3229 HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS,
FALSE, osProcID);
3235 uint64 cpuTicks = 0;
3236 LARGE_INTEGER perfFreq;
3237 if (!QueryPerformanceFrequency(&perfFreq) || !perfFreq.QuadPart)
3239 if (!QueryProcessCycleTime(hProcess, &cpuTicks))
3241 ticks = cpuTicks / (perfFreq.QuadPart / 1000000);
3254 if ((pid_t)osProcID != getpid())
3257 if (getrusage(RUSAGE_SELF, &ru) != 0)
3259 ticks = ((uint64)ru.ru_utime.tv_sec * 1000000) + (uint64)ru.ru_utime.tv_usec
3260 + ((uint64)ru.ru_stime.tv_sec * 1000000) + (uint64)ru.ru_stime.tv_usec;
3264 if (clock_getcpuclockid(osProcID, &clockid) != 0)
3267 if (clock_gettime(clockid, &ts) != -1 ) {
3268 ticks = ((uint64)ts.tv_sec * 1000000) + (ts.tv_nsec/1000);
3296 uint64 cpuTicks = 0;
3297 LARGE_INTEGER perfFreq;
3298 if (!QueryPerformanceFrequency(&perfFreq) || !perfFreq.QuadPart)
3300 if (!QueryProcessCycleTime(::GetCurrentProcess(), &cpuTicks))
3302 ticks = cpuTicks / (perfFreq.QuadPart / 1000000);
3315 if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts) != -1 ) {
3316 ticks = ((uint64)ts.tv_sec * 1000000) + (ts.tv_nsec/1000);
3336bool GetProcAndOSCPUUsage(
double& procPercentUse,
double& osPercentUse, uint64 &prevOSTicks, uint64 &prevOSIdleTicks, uint64 &prevProcTicks) {
3338 return GetProcAndOSCPUUsage(0, procPercentUse, osPercentUse, prevOSTicks, prevOSIdleTicks, prevProcTicks);
3340 return GetProcAndOSCPUUsage(getpid(), procPercentUse, osPercentUse, prevOSTicks, prevOSIdleTicks, prevProcTicks);
3345bool GetProcAndOSCPUUsage(uint32 osProcID,
double& procPercentUse,
double& osPercentUse, uint64 &prevOSTicks, uint64 &prevOSIdleTicks, uint64 &prevProcTicks) {
3346 procPercentUse = osPercentUse = 0;
3348 uint64 totalTicks, kernelTicks, userTicks, idleTicks, procTotalTicks, procUserTicks, procKernelTicks;
3351 FILETIME idleTime, kernelTime, userTime;
3352 if (!GetSystemTimes(&idleTime, &kernelTime, &userTime))
3355 idleTicks = FileTimeToUint64(idleTime);
3356 kernelTicks = FileTimeToUint64(kernelTime);
3357 userTicks = FileTimeToUint64(userTime);
3358 totalTicks = kernelTicks + userTicks;
3360 FILETIME procCreationTime, procExitTime, procKernelTime, procUserTime;
3363 if (!GetProcessTimes(GetCurrentProcess(), &procCreationTime, &procExitTime, &procKernelTime, &procUserTime))
3367 HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS,
FALSE, osProcID);
3371 if (!GetProcessTimes(hProcess, &procCreationTime, &procExitTime, &procKernelTime, &procUserTime))
3375 procKernelTicks = FileTimeToUint64(procKernelTime);
3376 procUserTicks = FileTimeToUint64(procUserTime);
3377 procTotalTicks = procKernelTicks + procUserTicks;
3382 host_cpu_load_info_data_t cpuInfo;
3383 mach_msg_type_number_t count = HOST_CPU_LOAD_INFO_COUNT;
3384 if (host_statistics64(mach_host_self(), HOST_CPU_LOAD_INFO, (host_info64_t)&cpuInfo, &count) != KERN_SUCCESS)
3388 long ticksPerSec = sysconf(_SC_CLK_TCK);
3389 uint64 usPerTick = (ticksPerSec > 0) ? (1000000 / ticksPerSec) : 10000;
3390 totalTicks = ((uint64)cpuInfo.cpu_ticks[CPU_STATE_USER] + cpuInfo.cpu_ticks[CPU_STATE_SYSTEM] + cpuInfo.cpu_ticks[CPU_STATE_IDLE] + cpuInfo.cpu_ticks[CPU_STATE_NICE]) * usPerTick;
3391 idleTicks = (uint64)cpuInfo.cpu_ticks[CPU_STATE_IDLE] * usPerTick;
3392 if (osProcID == 0 || osProcID == (uint32)getpid()) {
3393 task_thread_times_info_data_t threadTimes;
3394 count = TASK_THREAD_TIMES_INFO_COUNT;
3395 if (task_info(mach_task_self(), TASK_THREAD_TIMES_INFO, (task_info_t)&threadTimes, &count) == KERN_SUCCESS)
3396 procTotalTicks = (uint64)threadTimes.user_time.seconds * 1000000 + threadTimes.user_time.microseconds + (uint64)threadTimes.system_time.seconds * 1000000 + threadTimes.system_time.microseconds;
3404 std::string statLine, procStatLine;
3405 std::ifstream statFile (
"/proc/stat");
3406 std::ifstream procStatFile (
StringFormat(
"/proc/%d/stat", osProcID).c_str());
3407 if (statFile.is_open())
3408 getline (statFile, statLine);
3412 if (procStatFile.is_open())
3413 getline (procStatFile, procStatLine);
3417 if (!statLine.length() || !procStatLine.length())
3422 int retval = sscanf(statLine.c_str(),
"cpu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu",
3423 &fields[0], &fields[1], &fields[2], &fields[3], &fields[4],
3424 &fields[5], &fields[6], &fields[7], &fields[8], &fields[9]);
3426 for (
int i=0; i<10; i++)
3427 totalTicks += fields[i];
3428 idleTicks = fields[3];
3430 uint64 utime_ticks, stime_ticks, cutime_ticks, cstime_ticks;
3431 retval = sscanf(procStatLine.c_str(),
"%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %llu %llu %llu %llu",
3432 &utime_ticks, &stime_ticks, &cutime_ticks, &cstime_ticks);
3434 procTotalTicks = utime_ticks + stime_ticks + cutime_ticks + cstime_ticks;
3437 uint64 totalTicksSinceLastTime = totalTicks - prevOSTicks;
3438 uint64 idleTicksSinceLastTime = idleTicks - prevOSIdleTicks;
3439 uint64 procTicksSinceLastTime = procTotalTicks - prevProcTicks;
3441 osPercentUse = 1.0f-((totalTicksSinceLastTime > 0) ? ((double)idleTicksSinceLastTime)/totalTicksSinceLastTime : 0);
3442 procPercentUse = ((totalTicksSinceLastTime > 0) ? ((double)procTicksSinceLastTime)/totalTicksSinceLastTime : 0);
3447 prevOSTicks = totalTicks;
3448 prevOSIdleTicks = idleTicks;
3449 prevProcTicks = procTotalTicks;
3457 static uint64 PreviousTotalTicks = 0;
3458 static uint64 PreviousIdleTicks = 0;
3460 uint64 totalTicks, kernelTicks, userTicks, idleTicks;
3464 FILETIME idleTime, kernelTime, userTime;
3465 if (!GetSystemTimes(&idleTime, &kernelTime, &userTime))
3468 idleTicks = FileTimeToUint64(idleTime);
3469 kernelTicks = FileTimeToUint64(kernelTime);
3470 userTicks = FileTimeToUint64(userTime);
3471 totalTicks = kernelTicks + userTicks;
3474 host_cpu_load_info_data_t cpuInfo;
3475 mach_msg_type_number_t count = HOST_CPU_LOAD_INFO_COUNT;
3476 if (host_statistics64(mach_host_self(), HOST_CPU_LOAD_INFO, (host_info64_t)&cpuInfo, &count) != KERN_SUCCESS)
3478 totalTicks = (uint64)cpuInfo.cpu_ticks[CPU_STATE_USER] + cpuInfo.cpu_ticks[CPU_STATE_SYSTEM] + cpuInfo.cpu_ticks[CPU_STATE_IDLE] + cpuInfo.cpu_ticks[CPU_STATE_NICE];
3479 idleTicks = (uint64)cpuInfo.cpu_ticks[CPU_STATE_IDLE];
3481 std::string statLine;
3482 std::ifstream statFile(
"/proc/stat");
3483 if (!statFile.is_open() || !getline(statFile, statLine) || !statLine.length())
3487 if (sscanf(statLine.c_str(),
"cpu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu",
3488 &fields[0], &fields[1], &fields[2], &fields[3], &fields[4],
3489 &fields[5], &fields[6], &fields[7], &fields[8], &fields[9]) < 10)
3492 for (
int i = 0; i < 10; i++)
3493 totalTicks += fields[i];
3494 idleTicks = fields[3];
3497 uint64 totalTicksSinceLastTime = totalTicks - PreviousTotalTicks;
3498 uint64 idleTicksSinceLastTime = idleTicks - PreviousIdleTicks;
3500 percentUse = 1.0f-((totalTicksSinceLastTime > 0) ? ((double)idleTicksSinceLastTime)/totalTicksSinceLastTime : 0);
3505 PreviousTotalTicks = totalTicks;
3506 PreviousIdleTicks = idleTicks;
3517 struct sched_param sched;
3520 policy = SCHED_OTHER;
3522 policy = sched_getscheduler(0);
3526 if (pthread_getschedparam(hThread, &policy, &sched) != 0)
3539 struct sched_param sched;
3540 memset(&sched, 0,
sizeof(
struct sched_param));
3542 policy = SCHED_FIFO;
3546 int res = pthread_setschedparam(hThread, policy, &sched);
3558 val = THREAD_PRIORITY_NORMAL;
3560 val = THREAD_PRIORITY_TIME_CRITICAL;
3562 val = THREAD_PRIORITY_HIGHEST;
3564 val = THREAD_PRIORITY_ABOVE_NORMAL;
3566 val = THREAD_PRIORITY_NORMAL;
3568 val = THREAD_PRIORITY_BELOW_NORMAL;
3570 val = THREAD_PRIORITY_LOWEST;
3572 val = THREAD_PRIORITY_IDLE;
3605 case THREAD_PRIORITY_TIME_CRITICAL:
3607 case THREAD_PRIORITY_HIGHEST:
3609 case THREAD_PRIORITY_ABOVE_NORMAL:
3611 case THREAD_PRIORITY_NORMAL:
3613 case THREAD_PRIORITY_BELOW_NORMAL:
3615 case THREAD_PRIORITY_LOWEST:
3646 const HWND hDesktop = GetDesktopWindow();
3648 if (!GetWindowRect(hDesktop, &desktop))
3653 width = (uint32)desktop.right;
3654 height = (uint32)desktop.bottom;
3665 char* oldName =
new char[1024];
3666 if (!GetConsoleTitle(oldName, 1024)) {
3670 char* newName =
StringFormat(size,
"%s - %s", name, oldName);
3671 bool res = (SetConsoleTitle(name) != 0);
3677 return (SetConsoleTitle(name) != 0);
3685 char* consoleName =
new char[1024];
3686 if (!GetConsoleTitle(consoleName, 1024)) {
3687 delete [] consoleName;
3690 HWND handle = FindWindow(NULL, consoleName);
3692 delete [] consoleName;
3696 if (!GetWindowRect(handle, &wRect)) {
3697 delete [] consoleName;
3701 int conX = (x<0) ? wRect.left : x;
3702 int conY = (y<0) ? wRect.top : y;
3703 int conW = (w<0) ? wRect.right - wRect.left : w;
3704 int conH = (h<0) ? wRect.bottom - wRect.top : h;
3706 bool res = (MoveWindow(handle, conX, conY, conW, conH,
true) != 0);
3707 delete [] consoleName;
3722 return (uint32)GetCurrentProcessId();
3724 return (uint32)getpid();
3729int RunOSCommand(
const char* cmdline,
const char* initdir, uint32 timeout, std::string& stdoutString, std::string& stderrString) {
3730 if (!cmdline || !strlen(cmdline))
3734 HANDLE g_hChildStd_OUT_Rd = NULL;
3735 HANDLE g_hChildStd_OUT_Wr = NULL;
3736 HANDLE g_hChildStd_ERR_Rd = NULL;
3737 HANDLE g_hChildStd_ERR_Wr = NULL;
3739 SECURITY_ATTRIBUTES sa;
3741 sa.nLength =
sizeof(SECURITY_ATTRIBUTES);
3742 sa.bInheritHandle =
TRUE;
3743 sa.lpSecurityDescriptor = NULL;
3745 if ( ! CreatePipe(&g_hChildStd_ERR_Rd, &g_hChildStd_ERR_Wr, &sa, 0) ) {
3749 if ( ! SetHandleInformation(g_hChildStd_ERR_Rd, HANDLE_FLAG_INHERIT, 0) ){
3753 if ( ! CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &sa, 0) ) {
3757 if ( ! SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0) ){
3760 PROCESS_INFORMATION piProcInfo;
3761 STARTUPINFO siStartInfo;
3762 bool bSuccess =
FALSE;
3765 ZeroMemory( &piProcInfo,
sizeof(PROCESS_INFORMATION) );
3769 ZeroMemory( &siStartInfo,
sizeof(STARTUPINFO) );
3770 siStartInfo.cb =
sizeof(STARTUPINFO);
3771 siStartInfo.hStdError = g_hChildStd_ERR_Wr;
3772 siStartInfo.hStdOutput = g_hChildStd_OUT_Wr;
3773 siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
3779 bSuccess = (CreateProcess(NULL,
3789 CloseHandle(g_hChildStd_ERR_Wr);
3790 CloseHandle(g_hChildStd_OUT_Wr);
3802 bSuccess=(ReadFile( g_hChildStd_OUT_Rd, chBuf,
PROCBUFSIZE, &dwRead, NULL) != 0);
3803 if( ! bSuccess || dwRead == 0 )
break;
3804 std::string s(chBuf, dwRead);
3810 bSuccess=(ReadFile( g_hChildStd_ERR_Rd, chBuf,
PROCBUFSIZE, &dwRead, NULL) != 0);
3811 if( ! bSuccess || dwRead == 0 )
break;
3812 std::string s(chBuf, dwRead);
3819 if (GetExitCodeProcess(piProcInfo.hProcess, &exitcode) == STILL_ACTIVE) {
3820 TerminateProcess(piProcInfo.hProcess, 1);
3822 CloseHandle(g_hChildStd_ERR_Rd);
3823 CloseHandle(g_hChildStd_OUT_Rd);
3824 CloseHandle(piProcInfo.hProcess);
3825 CloseHandle(piProcInfo.hThread);
3830 FILE* runfile = popen(cmdline,
"r");
3831 if (runfile == NULL)
3838 char* buffer =
new char[size+1];
3840 res = fread(buffer, 1, size, runfile);
3842 status = pclose(runfile);
3843 exitcode = WEXITSTATUS(status);
3849 stdoutString += buffer;
3850 }
while (res = fread(buffer, 1, size, runfile));
3852 status = pclose(runfile);
3853 exitcode = WEXITSTATUS(status);
3922uint32
NewProcess(
const char* cmdline,
const char* initdir,
const char* title, int16 x, int16 y, int16 w, int16 h) {
3924 if (!cmdline || !strlen(cmdline))
3929 if (!ProcessInformationMap) {
3930 ProcessInformationMap =
new std::map<uint32, ProcessData*>;
3931 ghJob = CreateJobObject(NULL, NULL);
3933 JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0 };
3935 jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
3936 SetInformationJobObject(ghJob, JobObjectExtendedLimitInformation, &jeli,
sizeof(jeli));
3940 ProcessData* pData =
new ProcessData;
3942 ZeroMemory(&(pData->procInfo),
sizeof(pData->procInfo));
3943 ZeroMemory(&(pData->si),
sizeof(pData->si));
3944 pData->si.cb =
sizeof(pData->si);
3945 pData->si.wShowWindow = SW_SHOWNOACTIVATE;
3947 if ( (x>=0) && (y>=0) && (w>=0) && (h>=0) ) {
3948 pData->si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USEPOSITION | STARTF_USESIZE;
3951 pData->si.dwXSize = w;
3952 pData->si.dwYSize = h;
3955 pData->si.dwFlags = STARTF_USESHOWWINDOW;
3959 char* titleCopy = NULL;
3962 pData->si.lpTitle = titleCopy;
3969 int res = CreateProcess(NULL, cmd, NULL, NULL,
TRUE, CREATE_NEW_CONSOLE, NULL, initdir, &pData->si, &pData->procInfo);
3970 delete [] titleCopy;
3973 char* msg =
new char[2048];
3974 int length = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
3975 NULL, GetLastError(), 0, msg,
sizeof(msg), NULL);
3984 AssignProcessToJobObject(ghJob, pData->procInfo.hProcess);
3986 ProcessInformationMap->insert(Proc_Pair((uint32)pData->procInfo.dwProcessId, pData));
3987 return pData->procInfo.dwProcessId;
4007 pid_t ppid_before_fork = getpid();
4015 else if (pid == 0) {
4017 if ( initdir && (chdir(initdir) != 0) ) {
4018 LogPrint(0,
LOG_SYSTEM,0,
"Could not run process '%s' from starup dir '%s'\n", cmdline, initdir);
4023 int r = prctl(PR_SET_PDEATHSIG, SIGTERM);
4024 if (r == -1) { perror(0); exit(1); }
4027 if (getppid() != ppid_before_fork)
4031 execvp(argv[0],argv);
4053 std::map<uint32, ProcessData*>::iterator i = ProcessInformationMap->find(proc);
4054 if (i != ProcessInformationMap->end()) {
4055 ProcessData* pData = i->second;
4056 if (GetExitCodeProcess(pData->procInfo.hProcess, &exitcode) == STILL_ACTIVE) {
4060 ProcessInformationMap->erase(i);
4061 CloseHandle(pData->procInfo.hProcess);
4062 CloseHandle(pData->procInfo.hThread);
4064 returncode = exitcode;
4070 HANDLE hproc = OpenProcess(NULL,
false, (DWORD)proc);
4073 if (GetExitCodeProcess(hproc, &exitcode) == STILL_ACTIVE) {
4084 int res = waitpid(proc, &status, WNOHANG);
4096 returncode = WEXITSTATUS(status);
4100 else if (res == 0) {
4109 if (!ProcessInformationMap)
4111 std::map<uint32, ProcessData*>::iterator i = ProcessInformationMap->find(proc);
4112 if (i != ProcessInformationMap->end()) {
4113 ProcessData* pData = i->second;
4114 TerminateProcess(pData->procInfo.hProcess, 1);
4115 CloseHandle(pData->procInfo.hProcess);
4116 CloseHandle(pData->procInfo.hThread);
4117 ProcessInformationMap->erase(i);
4122 HANDLE hproc = OpenProcess(NULL, NULL, (DWORD)proc);
4125 if (TerminateProcess(hproc, 1) == 0) {
4135 return (kill(proc, SIGKILL) == 0);
4142 std::map<uint32, ProcessData*>::iterator i = ProcessInformationMap->find(proc);
4143 if (i != ProcessInformationMap->end()) {
4144 ProcessData* pData = i->second;
4145 if (WaitForSingleObject(pData->procInfo.hProcess, timeout) == WAIT_OBJECT_0) {
4146 if (GetExitCodeProcess(pData->procInfo.hProcess, &exitcode) == STILL_ACTIVE) {
4150 returncode = exitcode;
4151 CloseHandle(pData->procInfo.hProcess);
4152 CloseHandle(pData->procInfo.hThread);
4153 ProcessInformationMap->erase(i);
4161 HANDLE hproc = OpenProcess(NULL, NULL, (DWORD)proc);
4165 if (WaitForSingleObject(hproc, timeout) == WAIT_OBJECT_0) {
4166 if (GetExitCodeProcess(hproc, &exitcode) == STILL_ACTIVE) {
4171 returncode = exitcode;
4215 for (n=1; n<argc; n++) {
4218 val = strchr(argv[n],
'=');
4257 if (p1 == std::string::npos) {
4258 if (p2 == std::string::npos)
4263 else if (p2 == std::string::npos)
4280 if (p1 == std::string::npos) {
4281 if (p2 == std::string::npos)
4286 else if (p2 == std::string::npos)
4313 std::map<std::string, std::string>::const_iterator it =
4329 FreeLibrary(handle);
4343 std::string realLibName;
4345 realLibName = filename;
4349 int32 filenameStart;
4350 if ( (filenameStart = realLibName.find_last_of(
'/') == std::string::npos ))
4356 realLibName.insert(filenameStart,
"lib");
4358 if (!filenameStart) {
4360 realLibName.insert(0,
"./");
4362 realLibName.insert(0, path);
4372 std::string errorText;
4379 if (handle == NULL) {
4381 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
4382 NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
4383 (LPTSTR)&lpMsgBuf, 0, NULL);
4384 LogPrint(0,
LOG_SYSTEM, 0,
"Could not find or load debug library '%sDebug': %s", filename, lpMsgBuf);
4385 LocalFree(lpMsgBuf);
4389 handle = LoadLibrary(filename);
4390 if (handle == NULL) {
4392 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
4393 NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
4394 (LPTSTR) &lpMsgBuf, 0, NULL);
4395 LogPrint(0,
LOG_SYSTEM, 0,
"Could not find or load library '%s': %s", filename, lpMsgBuf);
4396 LocalFree(lpMsgBuf);
4402 const char* dlErrorText;
4409 std::string debugName = realLibName;
4412 handle = dlopen(debugName.c_str(), RTLD_NOW | RTLD_GLOBAL);
4414 dlErrorText = dlerror();
4416 if (dlErrorText && strlen(dlErrorText) &&
4417 !(strstr(dlErrorText,
"No such file") && strstr(dlErrorText, debugName.c_str())))
4418 errorText = dlErrorText;
4422 if (!handle && !errorText.size()) {
4425 dlErrorText = dlerror();
4427 if (dlErrorText && strlen(dlErrorText) &&
4428 !(strstr(dlErrorText,
"No such file") && strstr(dlErrorText, realLibName.c_str())))
4429 errorText = dlErrorText;
4433 if (!handle && !errorText.size() && !strchr(filename,
'/')) {
4436 handle = dlopen(realLibName.c_str(), RTLD_NOW | RTLD_GLOBAL);
4438 dlErrorText = dlerror();
4440 if (dlErrorText && strlen(dlErrorText) &&
4441 !(strstr(dlErrorText,
"No such file") && strstr(dlErrorText, realLibName.c_str())))
4442 errorText = dlErrorText;
4446 if (handle == NULL) {
4447 if (errorText.size())
4448 LogPrint(0,
LOG_SYSTEM, 0,
"Could not load library file '%s': %s", realLibName.c_str(), errorText.c_str());
4460 if (!strlen(funcName))
4471 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
4472 NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
4473 (LPTSTR) &lpMsgBuf, 0, NULL);
4474 LogPrint(0,
LOG_SYSTEM, 0,
"Could not find library function: %s: %s", funcName, lpMsgBuf);
4476 LocalFree(lpMsgBuf);
4484 if (errmsg != NULL) {
4485 LogPrint(0,
LOG_SYSTEM, 0,
"Could not find library function: %s: %s", (
char*) funcName, (
char*) errmsg);
4494 if (!lib->
load(libName)) {
4512 char* name =
new char[1024];
4543 std::string outString, errString;
4544 if (!
RunOSCommand(
"uname -n", NULL, 1000, outString, errString)) {
4560 HANDLE hProcess = GetCurrentProcess();
4561 PROCESS_MEMORY_COUNTERS pmc;
4562 if (hProcess == NULL)
4564 if ( GetProcessMemoryInfo( hProcess, &pmc,
sizeof(pmc)) != 0)
4565 return (uint64)pmc.WorkingSetSize;
4569 struct task_basic_info_64 info;
4570 mach_msg_type_number_t count = TASK_BASIC_INFO_64_COUNT;
4571 if (task_info(mach_task_self(), TASK_BASIC_INFO_64, (task_info_t)&info, &count) == KERN_SUCCESS)
4572 return (uint64)info.resident_size;
4578 if ( (fp = fopen(
"/proc/self/statm",
"r" )) == NULL )
4580 if ( fscanf( fp,
"%*s%ld", &rss ) != 1 ) {
4585 return (uint64)rss * (uint64)sysconf( _SC_PAGESIZE);
4592 HANDLE hProcess = GetCurrentProcess();
4593 PROCESS_MEMORY_COUNTERS pmc;
4594 if (hProcess == NULL)
4596 if ( GetProcessMemoryInfo( hProcess, &pmc,
sizeof(pmc)) != 0)
4597 return (uint64)pmc.PeakWorkingSetSize;
4602 struct rusage usage;
4603 getrusage(RUSAGE_SELF, &usage);
4604 return (uint64)usage.ru_maxrss;
4607 struct rusage usage;
4608 getrusage( RUSAGE_SELF, &usage );
4609 return ((uint64)usage.ru_maxrss) * 1024L;
4631 SYSTEM_INFO siSysInfo;
4632 GetSystemInfo(&siSysInfo);
4633 return (uint16) siSysInfo.dwNumberOfProcessors;
4636 size_t len =
sizeof(ncpu);
4637 if (sysctlbyname(
"hw.ncpu", &ncpu, &len, NULL, 0) == 0 && ncpu > 0)
4638 return (uint16)(ncpu > 65535 ? 65535 : ncpu);
4641 long n = sysconf(_SC_NPROCESSORS_ONLN);
4643 return (uint16)(n > 65535 ? 65535 : (uint16)n);
4650 SYSTEM_INFO siSysInfo;
4651 GetSystemInfo(&siSysInfo);
4652 switch(siSysInfo.wProcessorArchitecture) {
4653 case PROCESSOR_ARCHITECTURE_AMD64:
4655 case PROCESSOR_ARCHITECTURE_IA64:
4657 case PROCESSOR_ARCHITECTURE_INTEL:
4663 #if defined(__x86_64__)
4665 #elif defined(__i386__)
4667 #elif defined(__aarch64__)
4673 #if defined(__x86_64__)
4675 #elif defined(__i386__)
4677 #elif defined(__aarch64__)
4709 size_t len =
sizeof(freq);
4710 if (sysctlbyname(
"hw.cpufrequency", &freq, &len, NULL, 0) == 0)
4715 std::ifstream cpuinfo(
"/proc/cpuinfo");
4717 while (cpuinfo && getline(cpuinfo, line)) {
4718 if (line.compare(0, 7,
"cpu MHz") == 0) {
4719 size_t colon = line.find(
':');
4720 if (colon != std::string::npos) {
4722 if (sscanf(line.c_str() + colon + 1,
"%lf", &mhz) == 1 && mhz > 0)
4723 return (uint64)(mhz * 1000000.0);
4734 MEMORYSTATUS memstat;
4735 GlobalMemoryStatus(&memstat);
4736 return (uint64)memstat.dwTotalPhys;
4740 size_t len =
sizeof(memsize);
4741 if (sysctlbyname(
"hw.memsize", &memsize, &len, NULL, 0) == 0)
4745 struct sysinfo info;
4746 if (sysinfo(&info) == 0)
4747 return info.totalram;
4757 MEMORYSTATUSEX memstat;
4758 memset(&memstat, 0,
sizeof(MEMORYSTATUSEX));
4759 memstat.dwLength =
sizeof(MEMORYSTATUSEX);
4760 if (!GlobalMemoryStatusEx(&memstat)) {
4761 int a = GetLastError();
4764 totalRAM = (uint64)memstat.ullTotalPhys;
4765 freeRAM = (uint64)memstat.ullAvailPhys;
4770 size_t len =
sizeof(memsize);
4771 if (sysctlbyname(
"hw.memsize", &memsize, &len, NULL, 0) != 0)
4774 vm_statistics64_data_t vm_stat;
4775 mach_msg_type_number_t count = HOST_VM_INFO64_COUNT;
4776 if (host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info64_t)&vm_stat, &count) != KERN_SUCCESS)
4778 vm_size_t page_size;
4779 if (host_page_size(mach_host_self(), &page_size) != KERN_SUCCESS)
4781 freeRAM = (uint64)vm_stat.free_count * (uint64)page_size;
4784 struct sysinfo info;
4785 if (sysinfo(&info) == 0) {
4786 totalRAM = info.totalram;
4787 freeRAM = info.freeram;
4799 SYSTEM_INFO siSysInfo;
4800 GetSystemInfo(&siSysInfo);
4802 switch(siSysInfo.wProcessorArchitecture) {
4803 case PROCESSOR_ARCHITECTURE_UNKNOWN:
4805 case PROCESSOR_ARCHITECTURE_INTEL:
4806 switch(siSysInfo.wProcessorLevel) {
4832 case PROCESSOR_ARCHITECTURE_MIPS:
4835 case PROCESSOR_ARCHITECTURE_ALPHA:
4838 case PROCESSOR_ARCHITECTURE_PPC:
4841 case PROCESSOR_ARCHITECTURE_IA64:
4844 case PROCESSOR_ARCHITECTURE_AMD64:
4858 if (strlen(
OSName) == 0) {
4894 BOOL bOsVersionInfoEx;
4899 ZeroMemory(&osvi,
sizeof(OSVERSIONINFO));
4900 osvi.dwOSVersionInfoSize =
sizeof(OSVERSIONINFO);
4902 if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
4904 osvi.dwOSVersionInfoSize =
sizeof (OSVERSIONINFO);
4905 if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) )
4909 major = osvi.dwMajorVersion;
4910 minor = osvi.dwMinorVersion;
4911 if (strlen((
char*)osvi.szCSDVersion) < textSize)
4915 OSVERSIONINFOEX osvi;
4916 BOOL bOsVersionInfoEx;
4921 ZeroMemory(&osvi,
sizeof(OSVERSIONINFOEX));
4922 osvi.dwOSVersionInfoSize =
sizeof(OSVERSIONINFOEX);
4924 if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
4926 osvi.dwOSVersionInfoSize =
sizeof (OSVERSIONINFO);
4927 if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) )
4931 switch (osvi.dwPlatformId)
4934 case VER_PLATFORM_WIN32_NT:
4938 if( osvi.dwMajorVersion == 4 &&
4939 lstrcmpi( osvi.szCSDVersion,
"Service Pack 6" ) == 0 )
4945 lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
4946 "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009",
4947 0, KEY_QUERY_VALUE, &hKey );
4948 if( lRet == ERROR_SUCCESS ) {
4951 build = osvi.dwBuildNumber & 0xFFFF;
4955 major = (uint16)osvi.dwMajorVersion;
4956 minor = (uint16)osvi.dwMinorVersion;
4957 build = (uint16)osvi.dwBuildNumber & 0xFFFF;
4958 if (strlen((
char*)osvi.szCSDVersion) < textSize)
4961 RegCloseKey( hKey );
4965 major = (uint16)osvi.dwMajorVersion;
4966 minor = (uint16)osvi.dwMinorVersion;
4967 build = (uint16)osvi.dwBuildNumber & 0xFFFF;
4969 if (strlen((
char*)osvi.szCSDVersion) < textSize)
5036char*
Int2Ascii(int64 value,
char* result, uint16 size, uint8 base) {
5037 if (base < 2 || base > 36) {
5042 char* ptr = result, *ptr1 = result, tmp_char;
5048 *ptr++ =
"zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];
5063char*
Uint2Ascii(uint64 value,
char* result, uint16 size, uint8 base) {
5064 if (base < 2 || base > 36) {
5069 char* ptr = result, *ptr1 = result, tmp_char;
5075 *ptr++ =
"zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];
5088 size = (len * 2) + 4;
5089 unsigned char* result =
new unsigned char[size];
5093 const char* src = ascii;
5094 for (uint32 n = 0; n < len; n++) {
5101 size = (len * 2) + 2;
5106bool GetSocketError(
int error,
char* errorString, uint16 errorStringMaxSize,
bool* isRecoverable) {
5108 if (errorStringMaxSize < 128)
5113 if (error == WSANOTINITIALISED) {
5114 utils::strcpyavail(errorString,
"Cannot initialize WinSock!", errorStringMaxSize,
true);
5115 *isRecoverable =
false;
5117 else if (error == WSAENETDOWN) {
5118 utils::strcpyavail(errorString,
"The network subsystem or the associated service provider has failed", errorStringMaxSize,
true);
5119 *isRecoverable =
false;
5121 else if (error == WSAEAFNOSUPPORT) {
5122 utils::strcpyavail(errorString,
"The specified address family is not supported", errorStringMaxSize,
true);
5123 *isRecoverable =
false;
5125 else if (error == WSAEINPROGRESS) {
5126 utils::strcpyavail(errorString,
"A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function", errorStringMaxSize,
true);
5127 *isRecoverable =
true;
5129 else if (error == WSAEMFILE) {
5130 utils::strcpyavail(errorString,
"No more socket descriptors are available", errorStringMaxSize,
true);
5131 *isRecoverable =
false;
5133 else if (error == WSAENOBUFS) {
5134 utils::strcpyavail(errorString,
"No buffer space is available. The socket cannot be created", errorStringMaxSize,
true);
5135 *isRecoverable =
false;
5137 else if (error == WSAEPROTONOSUPPORT) {
5138 utils::strcpyavail(errorString,
"The specified protocol is not supported", errorStringMaxSize,
true);
5139 *isRecoverable =
false;
5141 else if (error == WSAEPROTOTYPE) {
5142 utils::strcpyavail(errorString,
"The specified protocol is the wrong type for this socket", errorStringMaxSize,
true);
5143 *isRecoverable =
false;
5145 else if (error == WSAESOCKTNOSUPPORT) {
5146 utils::strcpyavail(errorString,
"The specified socket type is not supported in this address family", errorStringMaxSize,
true);
5147 *isRecoverable =
false;
5149 else if (error == WSAEADDRINUSE) {
5150 utils::strcpyavail(errorString,
"The socket's local address is already in use and the socket was not marked to allow address reuse with SO_REUSEADDR. This error usually occurs during execution of the bind function, but could be delayed until this function if the bind was to a partially wildcard address (involving ADDR_ANY) and if a specific address needs to be committed at the time of this function", errorStringMaxSize,
true);
5151 *isRecoverable =
false;
5153 else if (error == WSAEINVAL) {
5154 utils::strcpyavail(errorString,
"The socket has not been bound with bind", errorStringMaxSize,
true);
5155 *isRecoverable =
false;
5157 else if (error == WSAEISCONN) {
5158 utils::strcpyavail(errorString,
"The socket is already connected", errorStringMaxSize,
true);
5159 *isRecoverable =
false;
5161 else if (error == WSAENOTSOCK) {
5162 utils::strcpyavail(errorString,
"The descriptor is not a socket", errorStringMaxSize,
true);
5163 *isRecoverable =
false;
5165 else if (error == WSAEOPNOTSUPP) {
5166 utils::strcpyavail(errorString,
"The referenced socket is not of a type that supports the listen operation", errorStringMaxSize,
true);
5167 *isRecoverable =
false;
5169 else if (error == WSAEADDRNOTAVAIL) {
5170 utils::strcpyavail(errorString,
"The specified address is not a valid address for this machine", errorStringMaxSize,
true);
5171 *isRecoverable =
false;
5173 else if (error == WSAEFAULT) {
5174 utils::strcpyavail(errorString,
"The name or namelen parameter is not a valid part of the user address space", errorStringMaxSize,
true);
5175 *isRecoverable =
false;
5177 else if (error == WSAEMFILE) {
5178 utils::strcpyavail(errorString,
"The queue is nonempty upon entry to accept and there are no descriptors available", errorStringMaxSize,
true);
5179 *isRecoverable =
false;
5182 utils::strcpyavail(errorString,
"The socket is marked as nonblocking and no connections are present to be accepted", errorStringMaxSize,
true);
5183 *isRecoverable =
false;
5185 else if (error == WSAETIMEDOUT) {
5186 utils::strcpyavail(errorString,
"Attempt to connect timed out without establishing a connection", errorStringMaxSize,
true);
5187 *isRecoverable =
false;
5189 else if (error == WSAENETUNREACH) {
5190 utils::strcpyavail(errorString,
"The network cannot be reached from this host at this time", errorStringMaxSize,
true);
5191 *isRecoverable =
false;
5193 else if (error == WSAEISCONN) {
5194 utils::strcpyavail(errorString,
"The socket is already connected (connection-oriented sockets only)", errorStringMaxSize,
true);
5195 *isRecoverable =
false;
5197 else if (error == WSAECONNREFUSED) {
5198 utils::strcpyavail(errorString,
"The attempt to connect was forcefully rejected", errorStringMaxSize,
true);
5199 *isRecoverable =
false;
5201 else if (error == WSAEAFNOSUPPORT) {
5202 utils::strcpyavail(errorString,
"Addresses in the specified family cannot be used with this socket", errorStringMaxSize,
true);
5203 *isRecoverable =
false;
5205 else if (error == WSAEADDRNOTAVAIL) {
5206 utils::strcpyavail(errorString,
"The remote address is not a valid address (such as ADDR_ANY)", errorStringMaxSize,
true);
5207 *isRecoverable =
false;
5209 else if (error == WSAEALREADY) {
5210 utils::strcpyavail(errorString,
"A nonblocking connect call is in progress on the specified socket", errorStringMaxSize,
true);
5211 *isRecoverable =
false;
5213 else if (error == WSAECONNRESET) {
5215 *isRecoverable =
false;
5217 else if (error == WSAECONNABORTED) {
5218 utils::strcpyavail(errorString,
"Software caused connection abort", errorStringMaxSize,
true);
5219 *isRecoverable =
false;
5222 snprintf(errorString, errorStringMaxSize,
"TCP error with no description: %d", error);
5223 *isRecoverable =
false;
5229 utils::strcpyavail(errorString,
"Cannot initialise socket", errorStringMaxSize,
true);
5230 *isRecoverable =
false;
5234 *isRecoverable =
false;
5244 int err = WSAGetLastError();
5255 DWORD error = GetLastError();
5256 uint32 len = FormatMessage(
5257 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
5258 NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
5259 (LPTSTR) &lpMsgBuf, 0, NULL);
5260 std::string str = (
char*)lpMsgBuf;
5261 LocalFree(lpMsgBuf);
5291 ldiv_t d = ldiv(timeout*1000, 1000000);
5297 return( select(maxfd, NULL, &wds, NULL, &tv) > 0);
5323 ldiv_t d = ldiv(timeout*1000, 1000000);
5330 int ret = select(maxfd, &rdds, NULL, NULL, &tv);
5338 #if defined(WINDOWS)
5339 unsigned long parm = 1;
5340 ioctlsocket(s, FIONBIO, &parm);
5342 long parm = fcntl(s, F_GETFL);
5344 fcntl(s, F_SETFL, parm);
5350 #if defined(WINDOWS)
5351 unsigned long parm = 0;
5352 ioctlsocket(s, FIONBIO, &parm);
5354 long parm = fcntl(s, F_GETFL);
5355 parm &= ~O_NONBLOCK;
5356 fcntl(s, F_SETFL, parm);
5363 if ( (name == NULL) || (strlen(name) == 0) )
5366 struct hostent* hent;
5379 struct addrinfo hints, *res;
5381 const char *cause = NULL;
5383 memset(&hints, 0,
sizeof(hints));
5386 hints.ai_family = AF_INET;
5387 hints.ai_socktype = SOCK_STREAM;
5388 hints.ai_protocol = IPPROTO_TCP;
5390 error = getaddrinfo(name, NULL, &hints, &res);
5392 __except (EXCEPTION_CONTINUE_EXECUTION) {
5397 memcpy(&address, res->ai_addr->sa_data + 2,
sizeof(address));
5407 struct addrinfo hints, *res;
5409 const char *cause = NULL;
5411 memset(&hints, 0,
sizeof(hints));
5413 hints.ai_family = PF_UNSPEC;
5414 hints.ai_socktype = SOCK_STREAM;
5415 error = getaddrinfo(name, NULL, &hints, &res);
5417 memcpy(&address, res->ai_addr->sa_data+2, 4);
5427 bool IsNetworkInitialised =
false;
5428 bool CheckNetworkInit() {
5429 if (IsNetworkInitialised)
return true;
5431 if (WSAStartup(MAKEWORD(1,1), &info) != 0) {
5435 IsNetworkInitialised =
true;
5442 struct hostent *pHost;
5444 unsigned char* addrChars = (
unsigned char*)&address;
5446 char* addrString =
new char[20];
5447 snprintf(addrString, 20,
"%u.%u.%u.%u", addrChars[0], addrChars[1], addrChars[2], addrChars[3]);
5450 pHost = gethostbyname(addrString);
5451 delete [] addrString;
5452 if (pHost == NULL) {
5455 if (strlen(pHost->h_name) > maxSize-1) {
5463 pHost = gethostbyname(addrString);
5464 delete [] addrString;
5468 if (strlen(pHost->h_name) > maxSize-1)
5475 pHost =
new struct hostent;
5478 gethostbyname_r(addrString, pHost, bf, 2000, &pHost, &er);
5479 delete [] addrString;
5485 if (strlen(pHost->h_name) > maxSize-1)
5497 char* name =
new char[256];
5503 std::string sname = name;
5511 if (gethostname(name, maxSize) == 0)
5572 for (uint32 i=0; i<c; i++) {
5573 if ( (interfaces[i].address != 0) && (interfaces[i].address !=
LOCALHOSTIP) )
5574 address = interfaces[i].
mac;
5576 delete [] interfaces;
5577 return (address != 0);
5585 uint64* addresses =
new uint64[c];
5587 for (uint32 i=0; i<c; i++) {
5588 if ( (interfaces[i].address != 0) && (interfaces[i].address !=
LOCALHOSTIP) )
5589 addresses[p++] = interfaces[i].
mac;
5606 if ((addresses == NULL) || (count == 0)) {
5607 delete [] addresses;
5612 for (n=0; n<count; n++) {
5613 if (addresses[n] == address) {
5614 delete [] addresses;
5618 delete [] addresses;
5626 if ((addresses == NULL) || (count == 0)) {
5627 delete [] addresses;
5632 bool localhostPresent =
false;
5633 for (n=0; n<count; n++) {
5635 if (addresses[n] != 0) {
5636 address = addresses[n];
5637 delete [] addresses;
5642 localhostPresent =
true;
5644 delete [] addresses;
5646 if (localhostPresent) {
5657 uint32 maxSize = 128;
5658 uint32* addresses =
new uint32[maxSize];
5663 char* szHostName =
new char[255];
5665 bool canAskHost =
true;
5666 if( gethostname(szHostName, 255) != 0 ) {
5669 if (err == WSANOTINITIALISED) {
5671 if (WSAStartup(MAKEWORD(1,1), &info) != 0) {
5672 delete [] szHostName;
5676 if( gethostname(szHostName, 255) != 0 )
5687 struct hostent * pHost;
5695 pHost = gethostbyname(szHostName);
5699 pHost = gethostbyname(szHostName);
5704 pHost =
new struct hostent;
5705 char* bf =
new char[2000];
5707 int res = gethostbyname_r(szHostName, pHost, bf, 2000, &pHost, &er);
5709 if ((er != 0) && (res == 0)) {
5718 for( i = 0; pHost!= NULL && pHost->h_addr_list[i]!= NULL; i++ )
5721 memcpy(&addr, ((
unsigned char*)pHost->h_addr_list[i]),
sizeof(uint32));
5723 for (j=0; j<count; j++) {
5724 if (addresses[j] == addr) {
5730 addresses[count++] = addr;
5746 for (i=0; i<c; i++) {
5748 if ( (interfaces[i].address != 0) && (interfaces[i].address !=
LOCALHOSTIP) ) {
5749 for (j=0; j<count; j++) {
5750 if (addresses[j] == interfaces[i].address) {
5756 addresses[count++] = interfaces[i].
address;
5759 delete [] interfaces;
5760 delete [] szHostName;
5767 uint32 maxSize = 128;
5780 ULONG flags = GAA_FLAG_INCLUDE_PREFIX;
5783 ULONG family = AF_INET;
5785 LPVOID lpMsgBuf = NULL;
5787 PIP_ADAPTER_ADDRESSES pAddresses = NULL;
5788 ULONG outBufLen = 0;
5789 ULONG Iterations = 0;
5791 PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
5792 PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL;
5793 PIP_ADAPTER_ANYCAST_ADDRESS pAnycast = NULL;
5794 PIP_ADAPTER_MULTICAST_ADDRESS pMulticast = NULL;
5795 IP_ADAPTER_DNS_SERVER_ADDRESS *pDnServer = NULL;
5796 IP_ADAPTER_PREFIX *pPrefix = NULL;
5803 pAddresses = (IP_ADAPTER_ADDRESSES *)
MALLOC(outBufLen);
5804 if (pAddresses == NULL)
5808 GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen);
5810 if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
5819 }
while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (Iterations < 10));
5822 if (dwRetVal == NO_ERROR) {
5824 pCurrAddresses = pAddresses;
5825 while (pCurrAddresses) {
5826 if ( (pCurrAddresses->OperStatus == IfOperStatusUp) && (pCurrAddresses->IfIndex != 0)) {
5829 pUnicast = pCurrAddresses->FirstUnicastAddress;
5830 if (pUnicast != NULL) {
5831 for (i = 0; pUnicast != NULL; i++) {
5832 addr = *(uint32*)(((
unsigned char*) ((
SOCKADDR*)(pUnicast->Address.lpSockaddr))->sa_data) + 2);
5834 interfaces[count].
address = addr;
5835 interfaces[count].
mac = 0;
5836 if (pCurrAddresses->PhysicalAddressLength == 6)
5837 memcpy(&(interfaces[count].mac), &(pCurrAddresses->PhysicalAddress), 6);
5838 WideCharToMultiByte( CP_ACP, 0, pCurrAddresses->Description, -1, interfaces[count].
name,
MAXKEYNAMELEN, NULL, NULL );
5839 WideCharToMultiByte( CP_ACP, 0, pCurrAddresses->FriendlyName, -1, interfaces[count].
friendlyName,
MAXKEYNAMELEN, NULL, NULL );
5842 pUnicast = pUnicast->Next;
5847 pCurrAddresses = pCurrAddresses->Next;
5858 struct sockaddr_in *saptr = NULL;
5859 struct if_nameindex *iflist = NULL, *listsave = NULL;
5862 if( (sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
5867 iflist = listsave = if_nameindex();
5869 if (iflist == NULL) {
5877 for(; iflist->if_index != 0; iflist++) {
5879 strncpy(ifreq.ifr_name, iflist->if_name, IF_NAMESIZE);
5881 if(ioctl(sock, SIOCGIFADDR, &ifreq) != 0) {
5886 saptr = (
struct sockaddr_in *)&ifreq.ifr_addr;
5889 memcpy(&(interfaces[count].address), &(saptr->sin_addr.s_addr),
sizeof(uint32));
5892 interfaces[count].
mac = 0;
5895 interfaces[count].
mac = 0;
5896 ioctl(sock, SIOCGIFHWADDR, &ifreq);
5897 memcpy(&(interfaces[count].mac), &(ifreq.ifr_hwaddr.sa_data), 6);
5902 if_freenameindex(listsave);
5914 struct sockaddr_in addr;
5915 addr.sin_family= AF_INET;
5916 addr.sin_addr.s_addr=INADDR_ANY;
5917 bool result =
false;
5919 nextPort = lastPort + 1;
5920 while (nextPort < lastPort + 1000) {
5921 if((socket=::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==
INVALID_SOCKET)
5928 setsockopt(socket, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (
char *) &one,
sizeof(one));
5940 setsockopt(socket,SOL_SOCKET,SO_REUSEADDR,&one,
sizeof(one));
5943 addr.sin_port=htons(nextPort);
5959 printf(
"Testing Utils...\n\n");
5961 char hostname[1024];
5963 printf(
"Error GetLocalHostname\n");
5966 printf(
"Local Hostname: '%s'\n\n", hostname);
5969 unsigned char* addrChars = (
unsigned char*) &addr;
5971 printf(
"Error GetLocalIPAddress\n");
5974 printf(
"Local IP Address: %u.%u.%u.%u\n\n", addrChars[0], addrChars[1], addrChars[2], addrChars[3]);
5978 if (addresses == NULL) {
5979 printf(
"Error GetLocalIPAddresses\n");
5983 for (n=0; n<count; n++) {
5984 addrChars = (
unsigned char*) &addresses[n];
5985 printf(
"Local IP Address[%u]: %u.%u.%u.%u (%u,%u)\n\n", n, addrChars[0], addrChars[1], addrChars[2], addrChars[3], addresses[n],
LOCALHOSTIP);
5987 delete [] addresses;
5990 for (n=0; n<count; n++) {
5991 addrChars = (
unsigned char*) &(interfaces[n]);
5992 printf(
"Local Interface[%u] %s: %u.%u.%u.%u (%llX)\n\n", n, interfaces[n].name,
5993 addrChars[0], addrChars[1], addrChars[2], addrChars[3], interfaces[n].mac);
5995 delete [] interfaces;
6000void PrintBinary(
void* p, uint32 size,
bool asInt,
const char* title) {
6002 printf(
"--- %s %u ---\n", title, size);
6004 for (uint32 n=0; n<size; n++) {
6005 c = *(((
unsigned char*)p)+n);
6007 printf(
"[%u] ", (
unsigned int)c);
6010 if ( (n > 0) && ((n+1)%10 == 0) )
6035const char*
stristr(
const char *str,
const char *substr, uint32 len) {
6036 if (!str || !substr)
return NULL;
6037 uint32 sslen = (uint32)strlen(substr);
6038 if (sslen == 0)
return (
const char*)str;
6041 for (; *str; str++, n++) {
6046 while ((*a++ | 32) == (*b++ | 32)) {
6049 if (len && (++m > len))
6056uint32
strcpyavail(
char* dst,
const char* src, uint32 maxlen,
bool copyAvailable) {
6057 if ( !dst || ! src || !maxlen )
6059 uint32 len = (uint32)strlen(src);
6060 if (len > maxlen-1) {
6064 memcpy(dst, src, maxlen-1);
6070 memcpy(dst, src, len+1);
6078 for (len = 0; len < size; len++) {
6080 if (str[len] == 13) {
6081 crSize = ( (len < size-1) && (str[len+1] == 10 ) ) ? 2 : 1;
6085 if (str[len] == 10) {
6096 std::string str = text;
6099 std::string::iterator i = str.begin(), e = str.end();
6103 std::transform(i, e, i, ::tolower);
6108 std::string str = text;
6109 std::transform(str.begin(), str.end(), str.begin(), ::toupper);
6114 std::string str = text;
6115 std::transform(str.begin(), str.end(), str.begin(), ::tolower);
6121 std::vector<std::string>::iterator i = lines.begin(), e = lines.end();
6131 uint32 len = (uint32)strlen(text);
6132 if (!len)
return "";
6137 uint32 s = 0, p = 0;
6139 while ( ((text[s] ==
'\n') || (text[s] ==
'\r')) && (s < len))
6142 while ((text[p] <= 32) && (p < len))
6144 std::string indentString = std::string(text+s, p-s);
6145 std::string str = text;
6153 uint32 begin = 0, end = (uint32)strlen(text);
6156 while ((begin < end) && (text[begin] <= 32) || (text[begin] ==
'\"') || (text[begin] ==
'\''))
6160 while ((end > begin) && (text[end-1] <= 32) || (text[end-1] ==
'\"') || (text[end-1] ==
'\''))
6162 return std::string(text+begin, end-begin);
6171 uint32 begin = 0, end = (uint32)strlen(text);
6174 while ((text[begin] <= 32) && (begin < end))
6176 while ((end > begin) && (text[end-1] <= 32))
6178 return std::string(text+begin, end-begin);
6184std::multimap<std::string, std::string>
TextMultiMapSplit(
const char* text,
const char* outersplit,
const char* innersplit) {
6185 std::multimap<std::string, std::string> result;
6186 typedef std::pair <std::string, std::string> Map_String_Pair;
6188 if (!text || !outersplit || !innersplit)
6191 const char* pstr = text, *lstr = text;
6192 const char* src = text;
6194 while (pstr = strstr(src, outersplit)) {
6195 if ((lstr = strstr(src, innersplit)) && (lstr < pstr)) {
6197 result.insert(Map_String_Pair(
TextTrim(std::string(src, lstr-src).c_str()),
TextTrim(std::string(lstr+1, pstr-lstr-1).c_str())));
6201 pstr = src + strlen(src);
6202 if ((lstr = strstr(src, innersplit)) && (lstr < pstr)) {
6204 result.insert(Map_String_Pair(
TextTrim(std::string(src, lstr-src).c_str()),
TextTrim(std::string(lstr+1, pstr-lstr-1).c_str())));
6211std::map<std::string, std::string>
TextMapSplit(
const char* text,
const char* outersplit,
const char* innersplit) {
6212 std::map<std::string, std::string> result;
6213 typedef std::pair <std::string, std::string> Map_String_Pair;
6215 if (!text || !outersplit || !innersplit)
6218 const char* pstr = text, *lstr = text;
6219 const char* src = text;
6221 while (pstr = strstr(src, outersplit)) {
6222 if ((lstr = strstr(src, innersplit)) && (lstr < pstr)) {
6224 result.insert(Map_String_Pair(
TextTrim(std::string(src, lstr - src).c_str()),
TextTrim(std::string(lstr + 1, pstr - lstr - 1).c_str())));
6228 pstr = src + strlen(src);
6229 if ((lstr = strstr(src, innersplit)) && (lstr < pstr)) {
6231 result.insert(Map_String_Pair(
TextTrim(std::string(src, lstr - src).c_str()),
TextTrim(std::string(lstr + 1, pstr - lstr - 1).c_str())));
6239 uint32 size = (uint32)args.size();
6243 char** argv =
new char*[size+1];
6245 std::vector<std::string>::iterator i = args.begin(), e = args.end();
6247 argv[c] =
new char[(*i).length()+1];
6248 strcpy(argv[c], (*i).c_str());
6259 uint32 size = (uint32)args.size();
6263 wchar_t** argv =
new wchar_t*[size+1];
6265 std::vector<std::string>::iterator i = args.begin(), e = args.end();
6267 argv[c] =
new wchar_t[(*i).length()+1];
6268 mbstowcs(argv[c], (*i).c_str(), (*i).length() + 1);
6278 for (uint32 n=0; n<(uint32)argc; n++)
6286 bool insideQuotes =
false;
6287 bool lastWasWhiteSpace =
false;
6288 std::vector<std::string> vect;
6289 std::string arg, val, str;
6292 uint32 len = (uint32)strlen(cmdline);
6294 bool keepQuotes =
false;
6296 for (uint32 n=0; n<len; n++) {
6299 if (!insideQuotes) {
6300 if (!lastWasWhiteSpace) {
6302 vect.push_back(str);
6308 lastWasWhiteSpace =
true;
6314 else if (ch ==
'"') {
6315 insideQuotes = !insideQuotes;
6318 lastWasWhiteSpace =
false;
6322 lastWasWhiteSpace =
false;
6326 if (str.length() > 0) {
6327 vect.push_back(str);
6335 if (!text || !strlen(text))
6336 return std::vector<std::string>();
6338 if (strstr(text,
"\r\n"))
6340 else if (strstr(text,
"\n\r"))
6342 else if (strstr(text,
"\n"))
6344 else if (strstr(text,
"\r"))
6347 std::vector<std::string> result;
6348 result.push_back(text);
6353 if (!text || !strlen(text))
6354 return std::vector<std::string>();
6357 std::vector<std::string> result;
6358 uint32 s = 0, n = 0, len = (uint32)strlen(text);
6361 if (text[n] == 13) {
6363 result.push_back(
"");
6365 str = std::string(text + s, n - s);
6366 result.push_back(
TextTrim(str.c_str()));
6368 if ((n < len - 1) && (text[n + 1] == 10))
6374 else if (text[n] == 10) {
6376 result.push_back(
"");
6378 str = std::string(text + s, n - s);
6379 result.push_back(
TextTrim(str.c_str()));
6381 if ((n < len - 1) && (text[n + 1] == 13))
6387 else if ((n-s < maxLineLength) && (text[n] == 32)) {
6390 else if (n - s >= maxLineLength) {
6392 result.push_back(
"");
6398 str = std::string(text + s, p);
6399 result.push_back(
TextTrim(str.c_str()));
6405 str = std::string(text + s, maxLineLength);
6406 result.push_back(
TextTrim(str.c_str()));
6415 str = std::string(text + s, n - s);
6416 result.push_back(
TextTrim(str.c_str()));
6430std::string
TextJoin(std::vector<std::string> &list,
const char* split, uint32 start, uint32 count) {
6431 std::ostringstream o;
6432 std::vector<std::string>::iterator i = list.begin(), e = list.end();
6433 uint32 l = 0, c = 0;
6435 if (!count || ((l >= start) && (c < count))) {
6436 if (c++) o << split;
6445std::string
TextJoin(std::list<std::string> &list,
const char* split, uint32 start, uint32 count) {
6446 std::ostringstream o;
6447 std::list<std::string>::iterator i = list.begin(), e = list.end();
6448 uint32 l = 0, c = 0;
6450 if (!count || ((l >= start) && (c < count))) {
6451 if (c++) o << split;
6460std::string
TextJoin(std::map<std::string, std::string> &map,
const char* innersplit,
const char* outersplit,
bool keyquotes,
bool valquotes) {
6461 std::ostringstream o;
6462 std::map<std::string, std::string>::iterator i = map.begin(), e = map.end();
6465 if (c++) o << outersplit;
6466 if (keyquotes && valquotes)
6467 o <<
"\"" << i->first <<
"\"" << innersplit <<
"\"" << i->second <<
"\"";
6469 o << i->first << innersplit <<
"\"" << i->second <<
"\"";
6471 o << i->first << innersplit << i->second;
6478 std::ostringstream o;
6479 std::map<std::string, std::string>::iterator i = map.begin(), e = map.end();
6493std::string
TextJoinXML(std::map<std::string, std::string> &map,
const char* innernodeName,
const char* outernodeName) {
6494 if (!innernodeName || !strlen(innernodeName))
6496 std::ostringstream o;
6497 std::map<std::string, std::string>::iterator i = map.begin(), e = map.end();
6498 if (outernodeName && strlen(outernodeName))
6499 o <<
"<" << outernodeName <<
">\n";
6504 if (outernodeName && strlen(outernodeName))
6505 o <<
"</" << outernodeName <<
">\n";
6511std::vector<std::string>
TextListSplit(
const char* text,
const char* split,
bool keepEmpty,
bool autoTrim) {
6512 std::vector<std::string> result;
6513 if (!text || !split)
6516 uint32 splitLen = (uint32)strlen(split);
6517 const char* pstr = text;
6518 const char* src = text;
6520 while (pstr = strstr(src, split)) {
6521 if (pstr - src || keepEmpty) {
6523 result.push_back(
TextTrim(std::string(src, pstr - src).c_str()));
6525 result.push_back(std::string(src, pstr - src).c_str());
6527 src = pstr + splitLen;
6529 pstr = src + strlen(src);
6532 result.push_back(
TextTrim(std::string(src, pstr - src).c_str()));
6534 result.push_back(std::string(src, pstr - src).c_str());
6541 std::vector<std::string>::iterator i, e;
6542 for (i=vect.begin(), e=vect.end(); i!=e; i++) {
6543 if (allowEmpty || (*i).size()) {
6553 if (strlen(format) == 0) {
6559 va_start(args, format);
6570 int len = _vscprintf(format, orig_args) + 10;
6571 str = (
char*)malloc(len+1);
6573 len = vsnprintf(str, len, format, orig_args);
6575 len = _vsnprintf_s(str, len, len+1, format, orig_args);
6579 size = (uint32)strlen(str);
6586 int len = vasprintf(&str, format, orig_args);
6597 if (!dst || !maxsize)
6599 if (strlen(format) == 0) {
6606 va_start(args, format);
6610 if (len > maxsize) {
6627 if (strlen(format) == 0)
6633 va_start(args, format);
6645 if (!text.size() || !key.size())
6650 uint32 keylen = (uint32)key.size();
6652 while ( (p = text.find(key, p)) != std::string::npos) {
6653 text.replace(p, keylen, value);
6663 if (!text.size() || !map.size())
6668 std::map<std::string, std::string>::iterator it, itEnd;
6669 for (it = map.begin(), itEnd = map.end(); it != itEnd; ++it)
6696uint32
StringScriptReplace(std::string& text, std::string name, std::list<std::map<std::string, std::string> >& list) {
6697 if (!text.size() || !name.size())
6702 char* start =
new char[name.size() + 50];
6703 snprintf(start, name.size()+50,
"<!-- start:%s -->", name.c_str());
6704 char* end =
new char[name.size() + 50];
6705 snprintf(end, name.size()+50,
"<!-- end:%s -->", name.c_str());
6708 size_t a1 = text.find(start);
6709 if (a1 == std::string::npos) {
6714 size_t b1 = text.find(end);
6715 if (b1 == std::string::npos) {
6721 uint32 a2 = (uint32)(a1 + strlen(start));
6722 uint32 b2 = (uint32)(b1 + strlen(end));
6725 std::string section = text.substr(a2, b1-a2);
6729 std::list<std::map<std::string, std::string> >::iterator it, itEnd;
6730 for (it = list.begin(), itEnd = list.end(); it != itEnd; ++it) {
6736 text.replace(a1, b2-a1, result);
6745 unsigned char c = (
unsigned char) strtol(str, NULL, 16);
6753 unsigned char c = (
unsigned char) strtol(str, NULL, 10);
6761 float64 diff = a - b;
6762 if ((diff < std::numeric_limits<float64>::epsilon()) && (-diff < std::numeric_limits<float64>::epsilon()))
6771#define poly 0xEDB88320
6779int CRC32(
const char *addr, uint32 length, int32 crc) {
6781 for (; length>0; length--) {
6782 crc = crc ^ *addr++;
6783 for (i=0; i<8; i++) {
6785 crc = (crc >> 1) ^
poly;
6799 char* data =
ReadAFile(filename.c_str(), length,
false);
6800 if (!data || !length)
6802 std::string dataString = data;
6807char*
ReadAFile(
const char* dir,
const char* filename, uint32& length,
bool binary) {
6808 if (!dir || !filename || strlen(filename) == 0)
6811 char* fullname =
new char[strlen(dir) + strlen(filename) + 5];
6812 snprintf(fullname, strlen(dir) + strlen(filename) + 5,
"%s/%s", dir, filename);
6813 char* res =
ReadAFile(fullname, length, binary);
6818char*
ReadAFile(
const char* filename, uint32& length,
bool binary) {
6819 if (!filename || strlen(filename) == 0)
6826 file = fopen(filename,
"rb");
6828 file = fopen(filename,
"r");
6834 fseek(file, 0, SEEK_END);
6835 length = ftell(file);
6836 fseek(file, 0, SEEK_SET);
6844 char* data =
new char[length+1];
6846 int res = (int)fread(data, 1, length, file);
6848 if ((res <= 0) || (res != length)) {
6849 int error = ferror(file);
6850 int eof = feof(file);
6854 LogPrint(0,0,0,
"File %s has no data", filename);
6861 length = (uint32)res;
6866bool WriteAFile(
const char* dir,
const char* filename,
const char* data, uint32 length,
bool binary) {
6867 if (!dir || !filename || strlen(filename) == 0)
6870 char* fullname =
new char[strlen(dir) + strlen(filename) + 5];
6871 snprintf(fullname, strlen(dir) + strlen(filename) + 5,
"%s/%s", dir, filename);
6872 bool res =
WriteAFile(fullname, data, length, binary);
6877bool WriteAFile(
const char* filename,
const char* data, uint32 length,
bool binary) {
6878 if (!filename || strlen(filename) == 0)
6883 file = fopen(filename,
"wb");
6885 file = fopen(filename,
"w");
6889 int res = (int)fwrite(data, 1, length, file);
6891 return (res == length);
6894bool AppendToAFile(
const char* dir,
const char* filename,
const char* data, uint32 length,
bool binary) {
6895 if (!dir || !filename || strlen(filename) == 0)
6898 char* fullname =
new char[strlen(dir) + strlen(filename) + 5];
6899 snprintf(fullname, strlen(dir) + strlen(filename) + 5,
"%s/%s", dir, filename);
6905bool AppendToAFile(
const char* filename,
const char* data, uint32 length,
bool binary) {
6906 if (!filename || strlen(filename) == 0)
6911 file = fopen(filename,
"ab");
6913 file = fopen(filename,
"a");
6917 int res = (int)fwrite(data, 1, length, file);
6919 return (res == length);
6923 if (!dir || !filename || strlen(filename) == 0)
6926 char* fullname =
new char[strlen(dir) + strlen(filename) + 5];
6927 snprintf(fullname, strlen(dir) + strlen(filename) + 5,
"%s/%s", dir, filename);
6938 if (!filename || strlen(filename) == 0)
6942 return (SetFileAttributes(filename, FILE_ATTRIBUTE_READONLY) != 0);
6944 return (SetFileAttributes(filename, FILE_ATTRIBUTE_NORMAL) != 0);
6947 return (chmod(filename,S_IREAD | S_IWRITE) != 0);
6949 return (chmod(filename,S_IREAD) == 0);
6951 return (chmod(filename,S_IWRITE) == 0);
6953 return (chmod(filename,0) == 0);
6957bool MoveAFile(
const char* oldfilename,
const char* newfilename,
bool force) {
6961 result = (MoveFileEx(oldfilename, newfilename, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED) != 0);
6963 result = (MoveFileEx(oldfilename, newfilename, MOVEFILE_COPY_ALLOWED) != 0);
6969 if (rename(oldfilename, newfilename) == 0)
6975 delete(newfilename);
6976 if (rename(oldfilename, newfilename) == 0)
6980 if (error == EXDEV) {
6981 if (
CopyAFile(newfilename, oldfilename)) {
6990bool MoveAFile(
const char* olddir,
const char* oldfilename,
const char* newdir,
const char* newfilename,
bool force) {
6991 if (!newdir || !newfilename || !strlen(newfilename) ||
6992 !olddir || !oldfilename || !strlen(oldfilename) )
6995 char* oldname =
new char[strlen(olddir) + strlen(oldfilename) + 5];
6996 snprintf(oldname, strlen(olddir) + strlen(oldfilename) + 5,
"%s/%s", olddir, oldfilename);
6997 char* newname =
new char[strlen(newdir) + strlen(newfilename) + 5];
6998 snprintf(newname, strlen(newdir) + strlen(newfilename) + 5,
"%s/%s", newdir, newfilename);
6999 bool res =
MoveAFile(newname, oldname, force);
7005bool CopyAFile(
const char* oldfilename,
const char* newfilename,
bool force) {
7008 return (CopyFile(oldfilename, newfilename,
FALSE) != 0);
7010 return (CopyFile(oldfilename, newfilename,
TRUE) != 0);
7018 char* data =
ReadAFile(oldfilename, size,
true);
7019 if (!data || !size) {
7029 if (!
WriteAFile(newfilename, data, size,
true)) {
7038bool CopyAFile(
const char* olddir,
const char* oldfilename,
const char* newdir,
const char* newfilename,
bool force) {
7039 if (!newdir || !newfilename || !strlen(newfilename) ||
7040 !olddir || !oldfilename || !strlen(oldfilename) )
7043 char* oldname =
new char[strlen(olddir) + strlen(oldfilename) + 5];
7044 snprintf(oldname, strlen(olddir) + strlen(oldfilename) + 5,
"%s/%s", olddir, oldfilename);
7045 char* newname =
new char[strlen(newdir) + strlen(newfilename) + 5];
7046 snprintf(newname, strlen(newdir) + strlen(newfilename) + 5,
"%s/%s", newdir, newfilename);
7047 bool res =
CopyAFile(newname, oldname, force);
7054 if (!dirname || strlen(dirname) == 0)
7067 if (CreateDirectory(dirname, NULL) != 0)
7072 if (mkdir(dirname, S_IRWXU | S_IRWXG | S_IRWXO) == 0)
7080 if (!dirname || strlen(dirname) == 0)
7091 if (DeleteFile(dirname) != 0)
7097 if (DeleteFile(dirname) != 0)
7103 if (unlink(dirname) == 0)
7109 if (unlink(dirname) == 0)
7119 if (RemoveDirectory(dirname) != 0)
7125 if (RemoveDirectory(dirname) != 0)
7131 if (rmdir(dirname) == 0)
7137 if (rmdir(dirname) == 0)
7147 if (!dirname || strlen(dirname) == 0)
7156 for (uint32 n = 0; n<count; n++) {
7174 for (uint32 n=0; n<size; n++) {
7175 if (str[n] == find) {
7187 len2 = (int)strlen(str2);
7191 len1 = (int)strlen(str1);
7193 return (strcmp(str1, str2) == 0) ? str1 : 0;
7194 else if (len1 - len2 < 0)
7197 strp = (
char*)(str1 + len1 - len2);
7198 while(strp != str1) {
7199 if(*strp == *str2) {
7200 if(strncmp(strp,str2,len2)==0)
7212 len2 = (int)strlen(str2);
7216 len1 = (int)strlen(str1);
7218 return (
stricmp(str1, str2) == 0) ? str1 : 0;
7219 else if (len1 - len2 < 0)
7222 strp = (
char*)(str1 + len1 - len2);
7223 while(strp != str1) {
7224 if(*strp == *str2) {
7235 return (
laststristr(str, end) == str + strlen(str) - strlen(end));
7237 return (
laststrstr(str, end) == str + strlen(str) - strlen(end));
7242 return (
stristr(str, start) == str);
7244 return (strstr(str, start) == str);
7249 std::string name = filename;
7250 std::string::size_type p1 = name.find_last_of(
'/');
7251 std::string::size_type p2 = name.find_last_of(
'\\');
7252 if (p1 == std::string::npos) {
7253 if (p2 == std::string::npos)
7256 return name.substr(0, p2 + 1);
7258 else if (p2 == std::string::npos)
7259 return name.substr(0, p1 + 1);
7261 return name.substr(0, (p1 > p2) ? p1 + 1 : p2 + 1);
7265 std::string name = filename;
7266 std::string::size_type p1 = name.find_last_of(
'/');
7267 std::string::size_type p2 = name.find_last_of(
'\\');
7268 if (p1 == std::string::npos) {
7269 if (p2 == std::string::npos)
7272 return filename + p2 + 1;
7274 else if (p2 == std::string::npos)
7275 return filename + p1 + 1;
7277 return (p1 > p2) ? filename + p1 + 1 : filename + p2 + 1;
7282 char cCurrentPath[FILENAME_MAX];
7288 cCurrentPath[
sizeof(cCurrentPath) - 1] =
'\0';
7290 return cCurrentPath;
7293char*
GetFileList(
const char* dirname,
const char* ext, uint32& count,
bool fullpath, uint32 maxNameLen) {
7298 uint32 extlen = (ext == NULL) ? 0 : (uint32)strlen(ext);
7299 struct dirent* direntry = NULL;
7301 uint32 tempMaxCount = 50;
7302 uint32 len = (maxNameLen+1)*tempMaxCount;
7303 char* result =
new char[len];
7306 uint32 dirnamelen = (uint32)strlen(dirname);
7307 bool dirslash = (*(dirname + dirnamelen - 1) ==
'/') || (*(dirname + dirnamelen - 1) ==
'\\');
7315 if (direntry->
d_name[0] !=
'\0') {
7317 if ( !strcmp(direntry->
d_name,
".") || !strcmp(direntry->
d_name,
"..") ) {
7328 memset(dst+dirnamelen,
'/', 1);
7338 if (count >= tempMaxCount) {
7340 tmp =
new char[len*2];
7341 memcpy(tmp, result, len);
7365 struct stat statbuf;
7381 if ((fd = _open(filename, O_RDONLY)) == -1) {
7400 result = fstat(fd, &statbuf);
7411 info.
size = statbuf.st_size;
7412 info.
isDirectory = ((statbuf.st_mode & S_IFDIR) != 0);
7418 info.
isReadable = ((statbuf.st_mode & _S_IREAD) != 0);
7419 info.
isWritable = ((statbuf.st_mode & _S_IWRITE) != 0);
7420 info.
isExecutable = ((statbuf.st_mode & _S_IEXEC) != 0);
7422 info.
isReadable = ((statbuf.st_mode & S_IRUSR) != 0);
7423 info.
isWritable = ((statbuf.st_mode & S_IWUSR) != 0);
7424 info.
isExecutable = ((statbuf.st_mode & S_IXUSR) != 0);
7434 if (!ascii || (start >= end) || (!(len = (uint32)strlen(ascii))) ) {
7441 copy =
new char[end - start + 2];
7442 memcpy(copy, ascii + start,
7444 copy[end - start + 1] = 0;
7451 if (!ascii || (start > end))
return false;
7452 uint32 len = (uint32)strlen(ascii);
7453 uint32 stop = end ? end+1 : len;
7454 if (stop > len) stop = len;
7455 for (uint32 n=start; n<stop; n++) {
7456 if (( ascii[n] <
'0' || ascii[n] >
'9') && ascii[n] !=
'.')
7463 if (!ascii || (start > end))
return false;
7466 return _strtoi64(ascii + start, NULL, 10);
7468 return strtoll(ascii + start, NULL, 10);
7472 int64 val = _strtoi64(copy, NULL, 10);
7474 int64 val = strtoll(copy, NULL, 10);
7481 if (!ascii || (start > end))
return false;
7484 return _strtoui64(ascii + start, NULL, 10);
7486 return strtoull(ascii + start, NULL, 10);
7490 uint64 val = _strtoui64(copy, NULL, 10);
7492 uint64 val = strtoull(copy, NULL, 10);
7499 if (!ascii || (start > end))
return false;
7502 return _strtoui64(ascii + start, NULL, 16);
7504 return strtoull(ascii + start, NULL, 16);
7508 uint64 val = _strtoui64(copy, NULL, 16);
7510 uint64 val = strtoull(copy, NULL, 16);
7517 if (!ascii || (start > end))
return false;
7519 return (int32)strtol(ascii + start, NULL, 10);
7521 int32 val = (int32)strtol(copy, NULL, 10);
7527 if (!ascii || (start > end))
return false;
7529 return (uint32)strtoul(ascii + start, NULL, 10);
7531 uint32 val = (uint32)strtoul(copy, NULL, 10);
7537 if (!ascii || (start > end))
return false;
7539 return (uint32)strtoul(ascii + start, NULL, 16);
7541 uint32 val = (uint32)strtoul(copy, NULL, 16);
7547 if (!ascii || (start > end))
return false;
7549 return strtod(ascii + start, NULL);
7551 float64 val = strtod(copy, NULL);
7558 bool isEscaped =
false;
7559 char* tmp =
new char[5];
7561 std::ostringstream o;
7562 std::string::iterator c;
7563 for (c = str.begin(); c != str.end(); c++) {
7566 case '"': o <<
"\"";
break;
7567 case '\\': o <<
"\\";
break;
7568 case 'b': o <<
"\b";
break;
7569 case 'f': o <<
"\f";
break;
7570 case 'n': o <<
"\n";
break;
7571 case 'r': o <<
"\r";
break;
7572 case 't': o <<
"\t";
break;
7575 tmp[0] = (uint8)(*c++);
7576 tmp[1] = (uint8)(*c++);
7577 tmp[2] = (uint8)(*c++);
7578 tmp[3] = (uint8)(*c);
7579 o << (char) strtol(tmp, NULL, 16);
7587 case '\\': isEscaped =
true;
break;
7597 std::ostringstream o;
7598 std::string::iterator c;
7599 for (c = str.begin(); c != str.end(); c++) {
7601 case '"': o <<
"\\\"";
break;
7602 case '\\': o <<
"\\\\";
break;
7603 case '\b': o <<
"\\b";
break;
7604 case '\f': o <<
"\\f";
break;
7605 case '\n': o <<
"\\n";
break;
7606 case '\r': o <<
"\\r";
break;
7607 case '\t': o <<
"\\t";
break;
7609 if (
'\x00' <= *c && *c <=
'\x1f') {
7611 << std::hex << std::setw(4) << std::setfill(
'0') << (int)*c;
7673 srand( seedvalue ? seedvalue : (uint32)
GetTimeNow());
7680 double t = (1.0/((RAND_MAX + 1.0)*(RAND_MAX + 1.0)*(RAND_MAX + 1.0)));
7682 d = (rand () * ((RAND_MAX + 1.0) * (RAND_MAX + 1.0))
7683 + rand () * (RAND_MAX + 1.0)
7707 uint64 n = (uint64)(r/interval);
7708 double l = r - (n*interval);
7709 if (l >= (0.5*interval))
7710 return from + (n*interval);
7712 return from + ((n+1)*interval);
7716 return (int64)roundl(
RandomValue((
double)from, (
double)to));
7727 double mb = kb*1024;
7728 double gb = mb*1024;
7729 double tb = gb*1024;
7731 char *tmp =
new char[64];
7734 snprintf(tmp, 64,
"%.2f B", val);
7735 else if (val < 512*kb) {
7737 snprintf(tmp, 64,
"%.2f KB", val);
7739 else if (val < 512*mb) {
7741 snprintf(tmp, 64,
"%.2f MB", val);
7743 else if (val < 512*gb) {
7745 snprintf(tmp, 64,
"%.2f GB", val);
7749 snprintf(tmp, 64,
"%.2f TB", val);
7752 std::string result = tmp;
7764 double mb = kb*1024;
7765 double gb = mb*1024;
7766 double tb = gb*1024;
7768 char *tmp =
new char[64];
7769 char *end =
new char[64];
7772 double maximum = ((val1 > val2) ? val1 : val2);
7774 if (maximum < 512) {
7778 else if (maximum < 512*kb) {
7782 else if (maximum < 512*mb) {
7786 else if (maximum < 512*gb) {
7794 snprintf(tmp, 64,
"%.2f / %.2f %s", ((
double)val1)/val, ((
double)val2)/val, (
char*) end);
7796 std::string result = tmp;
7808 char *tmp =
new char[64];
7809 snprintf(tmp, 64,
"%s/sec", (
char*)
BytifySize(val).c_str());
7810 std::string result = tmp;
7820 char *tmp =
new char[64];
7821 snprintf(tmp, 64,
"%s/sec", (
char*)
BytifySizes(val1, val2).c_str());
7822 std::string result = tmp;
7836 HKEY hKeyRoot, hKey;
7837 std::string keySubName = GetRegistryKeyInfo(key, hKeyRoot);
7839 uint32 err = RegOpenKeyEx(hKeyRoot, keySubName.c_str(), 0, KEY_READ | KEY_WOW64_64KEY, &hKey);
7840 if (err != ERROR_SUCCESS)
7843 DWORD dwType = REG_DWORD;
7845 DWORD dwSize =
sizeof(numVal);
7847 err = RegQueryValueEx(hKey, entry, NULL, &dwType, (LPBYTE)&numVal, &dwSize);
7849 if (err != ERROR_SUCCESS)
7855 HKEY hKeyRoot, hKey;
7856 std::string keySubName = GetRegistryKeyInfo(key, hKeyRoot);
7858 uint32 err = RegOpenKeyEx(hKeyRoot, keySubName.c_str(), 0, KEY_READ | KEY_WOW64_64KEY, &hKey);
7859 if (err != ERROR_SUCCESS)
7862 DWORD dwType = REG_QWORD;
7864 DWORD dwSize =
sizeof(numVal);
7866 err = RegQueryValueEx(hKey, entry, NULL, &dwType, (LPBYTE)&numVal, &dwSize);
7868 if (err != ERROR_SUCCESS)
7874 HKEY hKeyRoot, hKey;
7875 std::string keySubName = GetRegistryKeyInfo(key, hKeyRoot);
7877 uint32 err = RegOpenKeyEx(hKeyRoot, keySubName.c_str(), 0, KEY_READ | KEY_WOW64_64KEY, &hKey);
7878 if (err != ERROR_SUCCESS) {
7882 DWORD dwType = REG_SZ;
7883 DWORD dwSize = 4096;
7884 char* lszValue =
new char[dwSize];
7886 err = RegQueryValueEx(hKey, entry, NULL, &dwType, (LPBYTE)lszValue, &dwSize);
7888 if (err != ERROR_SUCCESS) {
7893 std::string val = lszValue;
7899 DWORD dwDisposition;
7900 HKEY hKeyRoot, hKey;
7901 std::string keySubName = GetRegistryKeyInfo(key, hKeyRoot);
7903 uint32 err = RegOpenKeyEx(hKeyRoot, keySubName.c_str(), 0, KEY_WRITE | KEY_WOW64_64KEY, &hKey);
7904 if (err != ERROR_SUCCESS) {
7905 err = RegCreateKeyEx(hKeyRoot, keySubName.c_str(), 0, NULL, 0, KEY_WRITE | KEY_WOW64_64KEY, NULL, &hKey, &dwDisposition);
7906 if (err != ERROR_SUCCESS)
7910 DWORD dwType = REG_DWORD;
7911 err = RegSetValueEx(hKey, entry, 0, dwType, (
const BYTE*)&value,
sizeof(value));
7913 return (err == ERROR_SUCCESS);
7917 DWORD dwDisposition;
7918 HKEY hKeyRoot, hKey;
7919 std::string keySubName = GetRegistryKeyInfo(key, hKeyRoot);
7921 uint32 err = RegOpenKeyEx(hKeyRoot, keySubName.c_str(), 0, KEY_WRITE | KEY_WOW64_64KEY, &hKey);
7922 if (err != ERROR_SUCCESS) {
7923 err = RegCreateKeyEx(hKeyRoot, keySubName.c_str(), 0, NULL, 0, KEY_WRITE | KEY_WOW64_64KEY, NULL, &hKey, &dwDisposition);
7924 if (err != ERROR_SUCCESS)
7928 DWORD dwType = REG_QWORD;
7929 err = RegSetValueEx(hKey, entry, 0, dwType, (
const BYTE*)&value,
sizeof(value));
7931 return (err == ERROR_SUCCESS);
7935 DWORD dwDisposition;
7936 HKEY hKeyRoot, hKey;
7937 std::string keySubName = GetRegistryKeyInfo(key, hKeyRoot);
7939 uint32 err = RegOpenKeyEx(hKeyRoot, keySubName.c_str(), 0, KEY_WRITE | KEY_WOW64_64KEY, &hKey);
7940 if (err != ERROR_SUCCESS) {
7941 err = RegCreateKeyEx(hKeyRoot, keySubName.c_str(), 0, NULL, 0, KEY_WRITE | KEY_WOW64_64KEY, NULL, &hKey, &dwDisposition);
7942 if (err != ERROR_SUCCESS)
7946 DWORD dwType = REG_SZ;
7947 DWORD dwSize = 4096;
7949 err = RegSetValueEx(hKey, entry, 0, dwType, (LPBYTE)value, (DWORD)(strlen(value) + 1));
7951 return (err == ERROR_SUCCESS);
7955 HKEY hKeyRoot, hKey;
7956 std::string keySubName = GetRegistryKeyInfo(key, hKeyRoot);
7958 uint32 err = RegOpenKeyEx(hKeyRoot, keySubName.c_str(), 0, KEY_SET_VALUE | KEY_WOW64_64KEY, &hKey);
7959 if (err != ERROR_SUCCESS)
7963 err = RegDeleteValue(hKey, entry);
7964 return (err == ERROR_SUCCESS);
7971 std::string keySubName = GetRegistryKeyInfo(entry, hKeyRoot);
7972 uint32 err = RegDeleteKeyEx(hKeyRoot, keySubName.c_str(), KEY_WOW64_64KEY, 0);
7973 return (err == ERROR_SUCCESS);
7977 if (!key || !strlen(key))
7982 std::string keySubName = GetRegistryKeyInfo(root, hKeyRoot);
7983 uint32 err = RegOpenKeyEx(hKeyRoot, keySubName.c_str(), 0, DELETE | KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE | KEY_WOW64_64KEY, &hKey);
7984 if (err != ERROR_SUCCESS)
7987 err = RegDeleteTree(hKey, key);
7988 return (err == ERROR_SUCCESS);
8000 DWORD dwDisposition;
8007 std::string keySubName = GetRegistryKeyInfo(entry, hKeyRoot);
8008 std::string keySubNewName = GetRegistryKeyInfo(newName, hKeyNewRoot);
8010 err = RegOpenKeyEx(hKeyRoot, keySubName.c_str(), 0, KEY_READ | KEY_WOW64_64KEY, &hKey);
8011 if (err != ERROR_SUCCESS)
8014 err = RegCreateKeyEx(hKeyNewRoot, keySubNewName.c_str(), 0, NULL, 0, KEY_ALL_ACCESS | KEY_WOW64_64KEY, NULL, &hKeyNew, &dwDisposition);
8015 if (err != ERROR_SUCCESS) {
8020 err = RegCopyTree(hKey, NULL, hKeyNew);
8023 RegCloseKey(hKeyNew);
8025 if (err != ERROR_SUCCESS) {
8026 RegDeleteKeyEx(hKeyNewRoot, keySubNewName.c_str(), KEY_WOW64_64KEY, 0);
8052std::string GetRegistryKeyInfo(
const char* key, HKEY &hKeyRoot) {
8055 if (path.size() < 2)
return false;
8056 if (
stristr(path.at(0).c_str(),
"HKEY_CLASSES_ROOT"))
8057 hKeyRoot = HKEY_CLASSES_ROOT;
8058 else if (
stristr(path.at(0).c_str(),
"HKEY_CURRENT_USER"))
8059 hKeyRoot = HKEY_CURRENT_USER;
8060 else if (
stristr(path.at(0).c_str(),
"HKEY_LOCAL_MACHINE"))
8061 hKeyRoot = HKEY_LOCAL_MACHINE;
8062 else if (
stristr(path.at(0).c_str(),
"HKEY_USERS"))
8063 hKeyRoot = HKEY_USERS;
8067std::string GetRegistryParentKeyInfo(
const char* key, HKEY &hKeyRoot) {
8070 if (path.size() < 2)
return false;
8071 if (
stristr(path.at(0).c_str(),
"HKEY_CLASSES_ROOT"))
8072 hKeyRoot = HKEY_CLASSES_ROOT;
8073 else if (
stristr(path.at(0).c_str(),
"HKEY_CURRENT_USER"))
8074 hKeyRoot = HKEY_CURRENT_USER;
8075 else if (
stristr(path.at(0).c_str(),
"HKEY_LOCAL_MACHINE"))
8076 hKeyRoot = HKEY_LOCAL_MACHINE;
8077 else if (
stristr(path.at(0).c_str(),
"HKEY_USERS"))
8078 hKeyRoot = HKEY_USERS;
8108 "Bitfield slot allocation: SetBit/SetBitN, first-free and last-occupied searches",
"util");
8110 "Timer scheduling and trigger delivery via waitForTimer",
"util");
HTML/URL helper utilities: entity encoding/decoding, MIME type lookup and URL component parsing.
#define PROC_ERROR
Error state.
Object type ids used to tag and verify every binary structure in CMSDK memory.
#define DATAMESSAGEINFOID
Process-wide thread registry and lifecycle manager: the concurrency core of CMSDK.
Small, dependency-free unit test harness used by all CMSDK object tests.
Cross-platform utility toolbox for CMSDK: threading, synchronization, shared memory,...
#define THREAD_STATS_ADHOC
THREAD_RET(* THREAD_FUNCTION)(void *)
#define THREAD_STATS_AUTO
RAII guard whose single static instance triggers global utility cleanup at program exit.
CleanShutdown()
Default constructor; no side effects.
~CleanShutdown()
Destroys all lazily-created global utility maps via ClearUtilsMaps().
Callback interface for receiving log entries produced through LogSystem.
Process-wide singleton logging hub with per-topic verbosity/debug levels.
static bool SetLogFileOutput(const char *logfile, bool printOut=true)
Direct log output to a file.
static bool SetLogReceiver(LogReceiver *rec)
Register a receiver that gets every accepted LogEntry.
static bool LogSystemPrint(uint32 source, uint8 subject, uint8 level, const char *formatstring,...)
printf-style informational logging (usually invoked via the LogPrint macro).
static bool LogSystemDebug(uint32 source, uint8 subject, uint8 level, const char *formatstring,...)
printf-style debug logging (usually invoked via the LogDebug macro); same parameters as LogSystemPrin...
static LogSystem * LogSingleton
Lazily-created global instance used by all static functions.
static bool SetLogLevelDebug(uint8 level)
Set the debug level threshold for all topics.
static bool SetLogLevelVerbose(uint8 level)
Set the verbose (print) level threshold for all topics.
static bool Shutdown()
Terminate all managed threads, then destroy the singleton.
static UnitTestRunner & instance()
Access the singleton (created on first use).
void registerTest(const char *name, UnitTestFunc func, const char *description="", const char *category="", bool inDefaultRun=true)
Register a test with the runner.
Singleton snapshot of the parsed process command line (set via SetCommandLine()).
static CommandLineInfo * CommandLineInfoSingleton
Auto-reset notification event (condition variable style), optionally named for cross-process use.
bool waitNext()
Block until the next signal() occurs.
Event()
Create an anonymous, process-local event.
bool signal()
Wake all threads currently waiting on this event.
Thin RAII wrapper around a dynamically loaded library (LoadLibrary / dlopen).
LibraryFunction getFunction(const char *funcName)
Resolve an exported function.
static std::string patchLibraryFilename(const char *filename, const char *path=NULL)
Normalize a library name into a platform filename (adds lib prefix / .dll, .so, .dylib suffix and opt...
bool load(const char *filename)
Load a library.
Recursive mutual-exclusion lock, optionally named for cross-process use.
Mutex()
Create an anonymous, process-local mutex.
bool leave()
Release the mutex.
bool enter()
Block until the mutex is acquired.
Counting semaphore, optionally named for cross-process use.
Semaphore(uint32 maxCount=100)
Create an anonymous semaphore.
bool signal()
Increment (release) the semaphore, waking one waiter.
bool wait()
Block until the semaphore can be decremented.
Multiplexing timer: schedule many periodic timers and consume their expiries from one queue.
bool addTimer(uint32 id, uint32 interval, uint64 start=0, uint64 end=0)
Register a periodic timer.
static std::map< uint32, Timer * > * timers
Global registry mapping globalID to live Timer instances, used by the OS callbacks.
bool triggerTimer(uint32 id)
Manually inject an expiry for timer id, as if it had fired now.
bool waitForTimer(uint32 timeout, uint32 &id, uint64 &time)
Wait for the next expiry of any registered timer.
bool removeTimer(uint32 id)
Unregister a timer and cancel its OS timer.
uint64 FTime2PsyTime(uint64 t)
Convert an ftime-style value (ms since Unix epoch) to a PsyTime µs timestamp.
uint64 GetTimeNow()
Return the current absolute time (µs since year 0) according to the TMC.
std::string PrintTimeNowString(bool local=true, bool us=true, bool ms=true)
Format GetTimeNow().
int32 GetTimeAgeMS(uint64 t)
Age of a timestamp relative to now, in milliseconds.
bool UnitTest_Utils()
Aggregate self test for miscellaneous utils functionality.
int64 AtomicDecrement64(int64 volatile &v)
Atomically decrement a 64-bit value.
bool SeedRandomValues(uint32 seedvalue=0)
Seed the pseudo-random generator.
int GetLastOSErrorNumber()
Get the last OS error number (errno / GetLastError()).
std::string GetLastOSErrorMessage()
Get the last OS error as human-readable text.
uint32 NewProcess(const char *cmdline, const char *initdir=NULL, const char *title=NULL, int16 x=-1, int16 y=-1, int16 w=-1, int16 h=-1)
Launch a detached child process.
std::vector< std::string > TextListBreakLines(const char *text, uint32 maxLineLength=80)
Word-wrap text into lines no longer than maxLineLength.
bool SetSharedSystemInstance(uint32 inst)
Set the instance number used to namespace shared OS objects, allowing several independent CMSDK syste...
int8 CompareFloats(float64 a, float64 b)
Compare two doubles with epsilon tolerance.
uint32 * GetLocalIPAddresses(uint32 &count)
List all local IPv4 addresses.
uint32 GetThreadStatColAbility()
Report this platform's capability for per-thread CPU statistics collection.
std::string EncodeJSON(std::string str)
Escape text for embedding as a JSON string value.
unsigned char * Ascii2UTF16LE(const char *ascii, uint32 len, uint32 &size)
Convert 8-bit ASCII text to UTF-16LE (used for Windows wide APIs and some protocols).
uint64 GetProcessMemoryUsage()
Current resident memory usage of this process.
bool WaitForThreadToFinish(ThreadHandle hThread, uint32 timeoutMS=0)
Join a thread.
char ** SplitCommandline(const char *cmdline, int &argc)
Split a command line into a malloc'ed argv array.
uint64 ReadRegistryQWORD(const char *key, const char *entry)
Read a 64-bit registry value.
bool SignalSemaphore(const char *name)
Signal a named global semaphore.
std::string GetCommandLineArg(uint16 n)
Get the n-th positional command line item.
bool GetThreadPriority(ThreadHandle hThread, uint16 priority)
Query a thread's scheduling priority.
bool CreateADir(const char *dirname)
Create a directory (parents included where supported).
std::string BytifyRates(double val1, double val2)
Format two byte rates as "x / y" with matching units.
bool CopyAFile(const char *oldfilename, const char *newfilename, bool force=false)
Copy a file.
bool DeleteFilesInADir(const char *dirname, bool force)
Delete all files inside a directory, leaving the directory itself.
uint32 GetCommandLineArgCount()
Number of positional command line items (excluding the executable).
std::pair< std::string, Mutex * > SharedMemoryMutexMapPair
int FromOSPriority(int pri)
Map a native OS priority back to the CMSDK priority scale.
uint16 GetCPUArchitecture()
CPU architecture id.
bool EndProcess(uint32 proc)
Forcibly terminate a child process.
std::pair< std::string, Semaphore * > SharedMemorySemaphoreMapPair
std::string ReadAFileString(std::string filename)
Read an entire file into a std::string.
static Mutex * SharedMemorySemaphoreMapMutex
bool GetLastOccupiedBitLoc(const char *bitfield, uint32 bytesize, uint32 &loc)
Find the highest set (occupied) bit.
const char * laststrstr(const char *str1, const char *str2)
Find the last occurrence of str2 in str1.
char * StringFormatVA(uint32 &size, const char *format, va_list args)
va_list core used by the other StringFormat overloads.
std::pair< std::string, Event * > SharedMemoryEventMapPair
bool DestroyEvent(const char *name)
Destroy a named global event.
bool WaitForSemaphore(const char *name, uint32 ms, bool autocreate=true)
Wait on a named global semaphore.
static SharedMemoryFileHandleMapType * SharedMemoryFileHandleMap
bool TextStartsWith(const char *str, const char *start, bool caseSensitive=true)
Test whether str starts with start.
std::string TextUppercase(const char *text)
Convert to upper case (ASCII/current locale).
int CRC32(const char *addr, uint32 length, int32 crc=0)
Compute (or continue) a CRC-32 checksum.
bool Sleep(uint32 ms)
Suspend the calling thread.
bool WaitForSocketReadability(SOCKET s, int32 timeout)
Wait until a socket has data to read.
uint64 * GetLocalMACAddresses(uint32 &count)
List all local MAC addresses.
bool SetThreadPriority(ThreadHandle hThread, uint16 priority)
Set a thread's scheduling priority.
bool GetProcAndOSCPUUsage(double &procPercentUse, double &osPercentUse, uint64 &prevOSTicks, uint64 &prevOSIdleTicks, uint64 &prevProcTicks)
Sample CPU usage of this process and of the whole OS since the previous call.
bool PauseThread(ThreadHandle hThread)
Suspend a thread's execution.
static std::map< std::string, Event * > * SharedMemoryEventMap
bool MoveConsoleWindow(int32 x=-1, int32 y=-1, int32 w=-1, int32 h=-1)
Move/resize the console window.
const char * GetSystemArchitecture()
Architecture name string, e.g.
std::string TextTrim(const char *text)
Strip leading and trailing whitespace.
bool IsThreadRunning(ThreadHandle hThread)
Check whether a thread is still alive.
bool CreateThread(THREAD_FUNCTION func, void *args, ThreadHandle &thread, uint32 &osID)
Start a new OS thread.
int32 AtomicDecrement32(int32 volatile &v)
Atomically decrement a 32-bit value.
std::string GetCommandLinePath()
Get the directory portion of the executable path.
static std::map< uint32, DrumBeatInfo > * DrumBeatMap
bool HasCommandLineArg(const char *key, std::string &value)
Test for a 'key=value' argument without mutating the argument map.
bool SignalThread(ThreadHandle hThread, int32 signal)
Send a signal to a thread (POSIX pthread_kill; limited emulation on Windows).
bool SetSocketBlockingMode(SOCKET s)
Put a socket into blocking mode.
uint32 Ascii2Uint32(const char *ascii, uint32 start=0, uint32 end=0)
Parse an unsigned 32-bit decimal integer from a substring.
uint64 GetCPUSpeed()
Nominal CPU clock speed.
wchar_t ** SplitCommandlineW(const char *cmdline, int &argc)
Wide-character variant of SplitCommandline() (for Windows APIs).
std::string TextVectorConcat(std::vector< std::string >, const char *sep, bool allowEmpty=true)
Concatenate vector entries with sep.
bool AppendToAFile(const char *filename, const char *data, uint32 length, bool binary=false)
Append to a file, creating it if missing.
char * OpenSharedMemorySegment(const char *name, uint64 size)
Open and map an existing named shared memory segment.
std::string TextIndent(const char *text, const char *indent)
Prefix every line of text with indent.
int64 AtomicIncrement64(int64 volatile &v)
Atomically increment a 64-bit value.
uint32 GetSharedSystemInstance()
Get the current shared-system instance number.
unsigned char Dec2Char(const char *str)
Parse up to three decimal digits into a byte.
bool StopDrumBeat(uint32 id)
Stop a running drum beat without destroying it.
char * GetFileList(const char *dirname, const char *ext, uint32 &count, bool fullpath, uint32 maxNameLen=256)
List files in a directory matching an extension.
bool GetNextAvailableLocalPort(uint16 lastPort, uint16 &nextPort)
Find the next free TCP port above lastPort.
bool EnterMutex(const char *name, uint32 ms, bool autocreate=true)
Acquire a named global mutex, creating it on first use.
const char * laststristr(const char *str1, const char *str2)
Case-insensitive laststrstr().
bool MoveAFile(const char *oldfilename, const char *newfilename, bool force=false)
Move/rename a file.
static Mutex * SharedMemoryMutexMapMutex
#define SharedMemoryFileHandleMapType
bool CreateDrumBeat(uint32 id, uint32 interval, DrumBeatFunc func, bool autostart=false)
Create a periodic timer ("drum beat") that calls func every interval ms.
uint32 StringMultiReplace(std::string &text, std::map< std::string, std::string > &map, bool onlyFirst)
Apply many key→value replacements in one pass.
std::string PrintProgramTrace(uint32 startLine=0, uint32 endLine=0)
Format the current call stack as printable text.
uint8 GetProcessStatus(uint32 proc, int &returncode)
Poll a child started with NewProcess().
bool(* DrumBeatFunc)(uint32 id, uint32 count)
Callback invoked on every drum-beat tick.
std::vector< std::string > TextListSplit(const char *text, const char *split, bool keepEmpty=true, bool autoTrim=false)
Split text on a separator.
bool IsTextNumeric(const char *ascii, uint32 start=0, uint32 end=0)
Test whether a (sub)string is a valid number.
static Mutex * SharedMemoryEventMapMutex
uint16 GetCPUCount()
Number of logical CPU cores.
char * Uint2Ascii(uint64 value, char *result, uint16 size, uint8 base)
Render an unsigned integer as text in an arbitrary base.
std::map< std::string, std::string > TextMapSplit(const char *text, const char *outersplit, const char *innersplit)
Split "k=v<sep>k=v..." text into a map (later duplicates overwrite earlier ones).
uint64 GetPeakProcessMemoryUsage()
Peak resident memory usage of this process.
bool DeleteCommandline(char **argv, int argc)
Free an argv array produced by SplitCommandline().
Semaphore * GetSemaphore(const char *name, bool autocreate=true)
Look up (and optionally create) a named semaphore in the global registry.
uint32 AsciiHex2Uint32(const char *ascii, uint32 start=0, uint32 end=0)
Parse an unsigned 32-bit hexadecimal integer from a substring.
bool DeleteRegistryKey(const char *key)
Delete a (leaf) registry key.
bool GetLocalHostname(char *name, uint32 maxSize)
Local hostname into a caller buffer.
std::string TextUnindent(const char *text)
Remove one level of leading indentation from every line.
bool GetSystemOSVersion(uint16 &major, uint16 &minor, uint16 &build, char *text, uint16 textSize)
Detailed OS version.
uint32 StringScriptReplace(std::string &text, std::string name, std::list< std::map< std::string, std::string > > &list)
Expand a named repeating template block in text once per map in list, substituting each map's keys in...
std::string TextJoinXML(std::map< std::string, std::string > &map, const char *innernodeName, const char *outernodeName)
Serialize a map as XML, one innernodeName element per pair inside an outernodeName element.
bool SetCommandLine(int argc, char *argv[])
Parse and store the process command line for later retrieval by the Get/HasCommandLine* functions.
bool LeaveMutex(const char *name)
Release a named global mutex previously acquired with EnterMutex().
uint32 StringSingleReplace(std::string &text, std::string key, std::string value, bool onlyFirst)
Replace occurrences of key with value in text.
int RunOSCommand(const char *cmdline, const char *initdir, uint32 timeout, std::string &stdoutString, std::string &stderrString)
Run a command synchronously and capture its output.
uint64 GetSystemMemorySize()
Total physical RAM installed.
char * CreateSharedMemorySegment(const char *name, uint64 size, bool force=false)
Create a named shared memory segment and map it into this process.
uint32 ReadRegistryDWORD(const char *key, const char *entry)
Read a 32-bit registry value.
std::string PrintBitFieldString(const char *bitfield, uint32 bytesize, uint32 size, const char *title)
Like GetBitFieldAsString() but prefixed with title and formatted for printing.
bool GetLocalMACAddress(uint64 &address)
Get the primary local MAC address.
bool WaitForSocketWriteability(SOCKET s, int32 timeout)
Wait until a socket can be written without blocking.
FileDetails GetFileDetails(const char *filename)
Stat a file.
double RandomValue()
Uniform random double in [0,1).
bool GetSocketError(int wsaError, char *errorString, uint16 errorStringMaxSize, bool *isRecoverable)
Translate a socket error code into text and classify it.
std::string GetCommandLineExecutableOnly()
Get just the executable filename without path.
std::string GetBitFieldAsString(const char *bitfield, uint32 bytesize, uint32 size)
Render the first size bits as a '0'/'1' string, for debugging.
uint8 WaitForProcess(uint32 proc, uint32 timeout, int &returncode)
Wait for a child to exit.
std::multimap< std::string, std::string > TextMultiMapSplit(const char *text, const char *outersplit, const char *innersplit)
Split "k=v<sep>k=v..." text into a multimap (duplicate keys preserved).
uint32 GetLocalProcessID()
Get the OS process id of the current process.
bool EndDrumBeat(uint32 id)
Destroy a drum beat and release its OS timer.
bool GetLocalIPAddress(uint32 &address)
Get the primary local IPv4 address.
bool DestroySemaphore(const char *name)
Destroy a named global semaphore.
bool LookupHostname(uint32 address, char *name, uint32 maxSize)
Reverse-resolve an IPv4 address to a hostname.
char * TextSubstringCopy(const char *ascii, uint32 start, uint32 end)
Copy the substring [start,end) into a new NUL-terminated buffer.
bool CloseSharedMemorySegment(char *data, uint64 size)
Unmap a segment previously created/opened here.
bool TerminateThread(ThreadHandle hThread)
Forcibly kill a thread.
bool LookupIPAddress(const char *name, uint32 &address)
Resolve a hostname to an IPv4 address.
bool GetFirstFreeBitLocN(const char *bitfield, uint32 bytesize, uint32 num, uint32 &loc)
Find the first run of num consecutive 0 bits.
bool GetCurrentThreadUniqueID(uint32 &tid)
Get a process-unique id for the calling thread.
int32 AtomicIncrement32(int32 volatile &v)
Atomically increment a 32-bit value.
bool GetDesktopSize(uint32 &width, uint32 &height)
Get the primary desktop resolution.
char * Int2Ascii(int64 value, char *result, uint16 size, uint8 base)
Render a signed integer as text in an arbitrary base.
std::string GetLocalHostnameString()
Local hostname as std::string.
bool CheckForThreadFinished(ThreadHandle hThread)
Non-blocking check whether a thread has terminated.
bool DestroyMutex(const char *name)
Destroy a named global mutex and remove it from the registry.
int32 Ascii2Int32(const char *ascii, uint32 start=0, uint32 end=0)
Parse a signed 32-bit decimal integer from a substring.
bool DoesAFileExist(const char *filename)
Test whether a regular file exists.
NetworkInterfaces * GetLocalInterfaces(uint32 &count)
Enumerate local network interfaces with address, MAC and names.
bool ContinueThread(ThreadHandle hThread)
Resume a thread paused with PauseThread().
std::string TextTrimQuotes(const char *text)
Strip a single pair of surrounding quotes if present.
const char * stristr(const char *str, const char *substr, uint32 len=0)
Case-insensitive strstr.
std::list< std::string > GetProgramTrace()
Capture the current call stack.
unsigned char Hex2Char(const char *str)
Parse two hex digits into a byte.
uint64 hton64(const uint64_t *input)
Convert a 64-bit value from host to network byte order.
bool DeleteAFile(const char *filename, bool force)
Delete a file.
bool ChangeAFileAttr(const char *filename, bool read, bool write)
Change read/write permission attributes of a file.
static uint16 SharedSystemInstance
static void TimerCallback(int sig, siginfo_t *siginfo, void *context)
POSIX signal-based timer callback trampoline (SIGEV_SIGNAL); routes the expiry into the owning Timer'...
void PrintBinary(void *p, uint32 size, bool asInt, const char *title)
Hex/decimal dump a memory region to stdout for debugging.
static std::map< std::string, Mutex * > * SharedMemoryMutexMap
std::string BytifySize(double val)
Format a byte count with binary units, e.g.
bool GetFirstFreeBitLoc(const char *bitfield, uint32 bytesize, uint32 &loc)
Find the first 0 (free) bit.
std::string GetCommandLineExecutable()
Get the full executable path as invoked.
bool StringFormatInto(char *dst, uint32 maxsize, const char *format,...)
printf into a caller-supplied buffer with truncation.
std::vector< std::string > TextListSplitLines(const char *text, bool keepEmpty=true, bool autoTrim=false)
Split text into lines, handling both \n and \r\n.
bool WriteAFile(const char *filename, const char *data, uint32 length, bool binary=false)
Write (create/overwrite) a file.
std::string GetCurrentDir()
Current working directory.
bool SignalEvent(const char *name)
Signal a named global event.
std::string GetCommandLine()
Get the full original command line as one string.
bool GetCPUTicks(ThreadHandle hThread, uint64 &ticks)
Get accumulated CPU time of a specific thread.
bool GetNextLineEnd(const char *str, uint32 size, uint32 &len, uint32 &crSize)
Find the end of the current line.
std::string ReadRegistryString(const char *key, const char *entry)
Read a string registry value.
std::vector< std::string > TextCommandlineSplit(const char *cmdline)
Split a command line into arguments, honouring quoting rules.
bool GetBit(uint32 loc, const char *bitfield, uint32 bytesize, bit &val)
Read bit loc.
uint64 ntoh64(const uint64 *input)
Convert a 64-bit value from network to host byte order.
bool DoesADirExist(const char *dirname)
Test whether a directory exists.
bool GetProcessCPUTicks(uint64 &ticks)
Get accumulated CPU time of the current process.
bool DeleteRegistryEntry(const char *key, const char *entry)
Delete a single value from a key.
std::string StringFormat(const char *format,...)
printf into a std::string.
int ToOSPriority(int pri)
Map a CMSDK priority value to the platform's native priority scale.
static std::map< std::string, Semaphore * > * SharedMemorySemaphoreMap
bool SetSocketNonBlockingMode(SOCKET s)
Put a socket into non-blocking mode.
bool DeleteADir(const char *dirname, bool force)
Delete a directory (recursively when force).
bool SetBitN(uint32 loc, uint32 num, bit value, char *bitfield, uint32 bytesize)
Set num consecutive bits starting at loc to value.
bool WriteRegistryQWORD(const char *key, const char *entry, uint64 value)
Write a 64-bit registry value.
bool Reset32BitField(char *bitfield, uint32 bytesize)
Zero the whole bitfield, marking every bit as free.
char * ReadAFile(const char *filename, uint32 &length, bool binary=false)
Read an entire file into a new buffer.
bool StartDrumBeat(uint32 id)
Start (or resume) a previously created drum beat.
uint64 Ascii2Uint64(const char *ascii, uint32 start=0, uint32 end=0)
Parse an unsigned 64-bit decimal integer from a substring.
bool TextEndsWith(const char *str, const char *end, bool caseSensitive=true)
Test whether str ends with end.
uint64 AsciiHex2Uint64(const char *ascii, uint32 start=0, uint32 end=0)
Parse an unsigned 64-bit hexadecimal integer (with or without 0x) from a substring.
const char * GetFileBasename(const char *filename)
Filename portion of a path.
Library * OpenLibrary(const char *libName)
Load a library by name, applying platform filename conventions.
bool UnitTest_Timer()
Self test for the Timer class.
bool WriteRegistryString(const char *key, const char *entry, const char *value)
Write a string registry value.
bool GetSystemMemoryUsage(uint64 &totalRAM, uint64 &freeRAM)
Query total and free physical memory.
int64 Ascii2Int64(const char *ascii, uint32 start=0, uint32 end=0)
Parse a signed 64-bit decimal integer from a substring.
bool SetBit(uint32 loc, bit value, char *bitfield, uint32 bytesize)
Set bit loc to value.
bool GetCurrentThread(ThreadHandle &thread)
Get the handle of the calling thread.
bool WriteRegistryDWORD(const char *key, const char *entry, uint32 value)
Write a 32-bit registry value (creates the key when needed).
bool RenameConsoleWindow(const char *name, bool prepend=false)
Set the console window title.
std::string TextJoinJSON(std::map< std::string, std::string > &map)
Serialize a map as a JSON object (keys/values escaped).
bool UtilsTest()
Run the built-in self test of the utils module.
bool CopyRegistryTree(const char *entry, const char *newName)
Recursively copy a registry subtree.
uint32 Calc32BitFieldSize(uint32 bitsize)
Compute the byte size needed for a bitfield of bitsize bits, rounded up to a 32-bit boundary.
int(* LibraryFunction)()
Signature of a plain function exported from a dynamically loaded library.
bool DeleteRegistryTree(const char *root, const char *key)
Recursively delete a key and all subkeys.
std::string TextLowercase(const char *text)
Convert to lower case (ASCII/current locale).
uint32 TextReplaceCharsInPlace(char *str, uint32 size, char find, char replace)
Replace every occurrence of a character, in place.
uint32 strcpyavail(char *dst, const char *src, uint32 maxlen, bool copyAvailable)
Bounded strcpy that always NUL-terminates.
std::string DecodeJSON(std::string str)
Unescape a JSON string value (\" \\ \n \t \uXXXX etc.).
std::string TextCapitalise(const char *text)
Capitalise the first letter of text.
const char * GetComputerName()
Get this machine's hostname.
std::string GetFilePath(const char *filename)
Directory portion of a path.
bool GetOSCPUUsage(double &percentUse)
Get the instantaneous total OS CPU usage.
const char * GetSystemOSName()
OS name string, e.g.
std::string BytifySizes(double val1, double val2)
Format two byte counts as "x / y" with matching units.
bool IsLocalIPAddress(const char *addr)
Test whether a textual address refers to this machine (loopback or a local interface).
bool GetCurrentThreadOSID(uint32 &tid)
Get the OS-level id of the calling thread (gettid / GetCurrentThreadId).
float64 Ascii2Float64(const char *ascii, uint32 start=0, uint32 end=0)
Parse a 64-bit float from a substring (decimal point, not locale dependent).
std::string TextJoin(std::vector< std::string > &list, const char *split, uint32 start=0, uint32 count=0)
Join vector elements with split.
int64 RandomInt(int64 from=0, int64 to=100)
Uniform random integer in [from,to].
std::string BytifyRate(double val)
Format a byte rate, e.g.
std::string EncodeHTML(std::string str)
Encode a plain string for safe embedding in HTML (e.g.
void fail(const char *fmt,...)
Set an explanatory reason shown on the FAIL line.
void metric(const char *name, double value, const char *unit="", bool higherIsBetter=true)
Record a performance metric.
void detail(const char *fmt,...)
Verbose-only indented diagnostic line (shown only when verbose=1).
void progress(int percent, const char *action)
Report progress with a short description of the current action.
char OSLocalHostName[1024]
char OSArchitectureName[1024]
bool WaitForNextEvent(const char *name, uint32 ms, bool autocreate)
bool RenameRegistryTree(const char *entry, const char *newName)
bool CalcTimeout(struct timespec &timeout, uint32 ms)
static void DrumBeatCallback(union sigval p)
CleanShutdown CleanShutdownInstance
struct dirent * readdir(DIR *)
DIR * opendir(const char *)
bool ClearUtilsMaps()
Free all lazily-allocated global registries (mutex/semaphore/event/shared-memory maps).
uint32 CleanShutdownInstanceCount
void Register_Utils_Tests()
uint32 GetDataTypeID(const char *typeName)
Inverse of GetDataTypeName(): look up the numeric datatype id for a type name.
std::string GetDataTypeName(uint32 datatype)
Translate a CMSDK datatype id (e.g.
Wire/storage layout of one log record: fixed header immediately followed by the message text.
std::string toJSON()
Serialize the entry (header fields + text) as a JSON object string.
bool setText(char *text, uint32 len)
Copy len bytes of text into the payload area and update size.
const char * getText(uint32 &len)
Access the text payload stored after the header.
std::string toXML()
Serialize the entry as an XML fragment.
Bookkeeping record for one periodic "drum beat" timer.
Existence, type, permission and timestamp information for one file, as returned by GetFileDetails().
Description of one local network interface (IPv4 address, MAC and names).
char friendlyName[MAXKEYNAMELEN+1]
char name[MAXKEYNAMELEN+1]
One scheduled entry inside a Timer: id, active window and platform timer handle.
A single timer expiry: which timer fired and when.