21 #if defined(__linux__)
22 # include <arpa/inet.h>
24 # include <linux/if.h>
25 # include <netinet/in.h>
27 # include <sys/ioctl.h>
28 # include <sys/socket.h>
29 # include <sys/statvfs.h>
30 # include <sys/types.h>
31 # include <sys/utsname.h>
34 extern char** environ;
36 #elif defined(__APPLE__)
37 # include <mach/mach.h>
40 # include <sys/mount.h>
41 # include <sys/param.h>
42 # include <sys/sysctl.h>
43 # include <sys/types.h>
62 # if (defined(WINVER)) && (WINVER >= 0x0502)
65 # pragma comment(lib, "pdh.lib")
66 # pragma comment(lib, "psapi.lib") // for get proocess name for pid
67 # pragma comment(lib, "wbemuuid.lib") // for get process arguments from pid
76 static void enableCpuLoadCollector();
77 static void disableCpuLoadCollector();
81 #if defined(__linux__)
86 size_t len = strlen(tag);
87 while (bufptr !=
nullptr) {
88 if (*bufptr ==
'\n') {
91 if (strncmp(tag, bufptr, len) == 0) {
92 retval = strtol(bufptr + len, &tail, 10);
93 if (tail == bufptr + len) {
98 bufptr = strchr(bufptr,
'\n');
104 bool getCpuEntry(
const char* tag,
const char* buff, std::string& value)
106 if (strlen(buff) <= strlen(tag)) {
110 if (strncmp(buff, tag, strlen(tag)) != 0) {
114 const char* pos1 = strchr(buff,
':');
115 if (pos1 ==
nullptr) {
119 while ((*pos1 !=
'\0') && ((*pos1 ==
' ') || (*pos1 ==
':') || (*pos1 ==
'\t'))) {
122 const char* pos2 = buff + strlen(buff) - 1;
123 while ((*pos2 !=
':') && ((*pos2 ==
' ') || (*pos2 ==
'\n'))) {
129 value = std::string(pos1, pos2 - pos1 + 1);
145 load.cpuLoad15 = 0.0;
146 load.cpuLoadInstant = (int)0;
156 load.cpuLoadInstant = (int)phdCpuLoad();
157 samples.push_back(load.cpuLoadInstant);
161 std::vector<int>::reverse_iterator rti;
169 load.cpuLoad1 = (double)(sum / n) / 100.0;
172 load.cpuLoad5 = (double)(sum / n) / 100.0;
174 load.cpuLoad15 = (double)(sum / n) / 100.0;
190 # if (defined(WINVER)) && (WINVER >= 0x0502)
195 phdStatus = PdhOpenQuery(
nullptr, 0, &hPhdQuery);
196 if (phdStatus != ERROR_SUCCESS)
199 PdhAddCounter(hPhdQuery, TEXT(
"\\Processor(_Total)\\% Processor Time"), 0, &phdCounter);
200 PdhCollectQueryData(hPhdQuery);
205 phdStatus = PdhCollectQueryData(hPhdQuery);
206 if (phdStatus != ERROR_SUCCESS)
208 phdStatus = PdhGetFormattedCounterValue(phdCounter,
209 PDH_FMT_DOUBLE | PDH_FMT_NOCAP100,
212 if (phdStatus != ERROR_SUCCESS)
214 return phdFmtValue.doubleValue;
224 # if (defined(WINVER)) && (WINVER >= 0x0502)
225 PDH_STATUS phdStatus;
227 PDH_FMT_COUNTERVALUE phdFmtValue;
236 static CpuLoadCollector* globalLoadCollector =
nullptr;
238 void enableCpuLoadCollector()
240 if (globalLoadCollector ==
nullptr) {
241 globalLoadCollector =
new CpuLoadCollector();
242 globalLoadCollector->start();
246 void disableCpuLoadCollector()
248 if (globalLoadCollector) {
249 globalLoadCollector->stop();
250 delete globalLoadCollector;
251 globalLoadCollector =
nullptr;
265 MEMORYSTATUSEX statex;
266 statex.dwLength =
sizeof(statex);
267 if (GlobalMemoryStatusEx(&statex)) {
273 #if defined(__linux__)
275 FILE* procmem = fopen(
"/proc/meminfo",
"r");
276 if (procmem !=
nullptr) {
277 while (fgets(
buffer, 128, procmem) !=
nullptr) {
279 if ((
ret = getMemEntry(
"MemTotal:",
buffer)) > 0) {
283 if ((
ret = getMemEntry(
"MemFree:",
buffer)) > 0) {
289 #elif defined(__APPLE__)
292 mach_port_t mach_port;
293 mach_msg_type_number_t count;
294 vm_statistics64_data_t vm_stats;
296 mach_port = mach_host_self();
297 count = HOST_VM_INFO64_COUNT;
298 if (KERN_SUCCESS == host_page_size(mach_port, &page_size) && KERN_SUCCESS == host_statistics64(mach_port, HOST_VM_INFO, (host_info64_t)&vm_stats, &count)) {
300 natural_t activePages = vm_stats.active_count + vm_stats.wire_count;
301 natural_t inactivePages = vm_stats.inactive_count + vm_stats.free_count;
302 natural_t totalPages = activePages + inactivePages;
304 int64_t total = totalPages * page_size;
305 int64_t freeSpace = inactivePages * page_size;
326 DWORD dwSectorsPerCluster = 0, dwBytesPerSector = 0;
327 DWORD dwFreeClusters = 0, dwTotalClusters = 0;
331 if (GetDiskFreeSpaceA(strHome.c_str(), &dwSectorsPerCluster, &dwBytesPerSector, &dwFreeClusters, &dwTotalClusters)) {
332 storage.
freeSpace = (
capacity_t)((dwFreeClusters / 1048576.0) * dwSectorsPerCluster * dwBytesPerSector);
333 storage.
totalSpace = (
capacity_t)((dwTotalClusters) / 1048576.0 * dwSectorsPerCluster * dwBytesPerSector);
337 #if defined(__linux__)
339 if (strHome.empty()) {
344 if (statvfs(strHome.c_str(), &vfs) == 0) {
345 storage.
totalSpace = (int)(vfs.f_blocks * vfs.f_bsize / (1048576));
346 storage.
freeSpace = (int)(vfs.f_bavail * vfs.f_bsize / (1048576));
351 #if defined(__APPLE__)
357 if (statfs(strHome.c_str(), &vfs) == 0) {
358 storage.
totalSpace = (int)(vfs.f_blocks * vfs.f_bsize / (1048576));
359 storage.
freeSpace = (int)(vfs.f_bavail * vfs.f_bsize / (1048576));
462 GetSystemInfo(&sysinf);
463 switch (sysinf.wProcessorArchitecture) {
464 case PROCESSOR_ARCHITECTURE_AMD64: {
468 case PROCESSOR_ARCHITECTURE_IA64: {
472 case PROCESSOR_ARCHITECTURE_INTEL: {
479 processor.
siblings = sysinf.dwNumberOfProcessors;
481 switch (sysinf.dwProcessorType) {
482 case PROCESSOR_INTEL_386: {
483 processor.
model =
"PROCESSOR_INTEL_386";
486 case PROCESSOR_INTEL_486: {
487 processor.
model =
"PROCESSOR_INTEL_486";
490 case PROCESSOR_INTEL_PENTIUM: {
491 processor.
model =
"PROCESSOR_INTEL_PENTIUM";
494 case PROCESSOR_INTEL_IA64: {
495 processor.
model =
"PROCESSOR_INTEL_IA64";
498 case PROCESSOR_AMD_X8664: {
499 processor.
model =
"PROCESSOR_AMD_X8664";
505 DWORD BufSize =
sizeof(DWORD);
507 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
508 "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",
513 RegQueryValueEx(hKey,
"~MHz",
nullptr,
nullptr, (LPBYTE)&dwMHz, &BufSize);
523 #if defined(__linux__)
525 FILE* proccpu = fopen(
"/proc/cpuinfo",
"r");
526 if (proccpu !=
nullptr) {
527 while (fgets(
buffer, 128, proccpu) !=
nullptr) {
529 if (getCpuEntry(
"model",
buffer, value) && !getCpuEntry(
"model name",
buffer, value)) {
532 if (getCpuEntry(
"model name",
buffer, value)) {
533 processor.
model = value;
535 if (getCpuEntry(
"vendor_id",
buffer, value)) {
538 if (getCpuEntry(
"cpu family",
buffer, value)) {
539 processor.
family = atoi(value.c_str());
541 if (getCpuEntry(
"cpu cores",
buffer, value)) {
542 processor.
cores = atoi(value.c_str());
544 if (getCpuEntry(
"siblings",
buffer, value)) {
545 processor.
siblings = atoi(value.c_str());
547 if (getCpuEntry(
"cpu MHz",
buffer, value)) {
548 processor.
frequency = atof(value.c_str());
555 if (uname(&uts) == 0) {
558 #elif defined(__APPLE__)
561 int mib[] = {CTL_HW, HW_CPU_FREQ};
563 size_t length =
sizeof(value);
565 if (!sysctl(mib, 2, &value, &length,
nullptr, 0)) {
569 if (!sysctlbyname(
"hw.logicalcpu", &value, &length,
nullptr, 0)) {
570 processor.
cores = value;
575 size_t buffLen = 512;
576 if (!sysctlbyname(
"machdep.cpu.vendor", buff, &buffLen,
nullptr, 0)) {
581 if (!sysctlbyname(
"machdep.cpu.brand_string", buff, &buffLen,
nullptr, 0)) {
582 processor.
model = buff;
585 if (!sysctlbyname(
"machdep.cpu.family", &value, &length,
nullptr, 0)) {
589 if (!sysctlbyname(
"machdep.cpu.model", &value, &length,
nullptr, 0)) {
605 platform.
name =
"Windows";
606 OSVERSIONINFOEX osver;
607 osver.dwOSVersionInfoSize =
sizeof(osver);
608 if (GetVersionEx((LPOSVERSIONINFO)&osver)) {
610 sprintf(buff,
"%d.%d", osver.dwMajorVersion, osver.dwMinorVersion);
613 if ((osver.dwMajorVersion == 10) && (osver.dwMinorVersion == 0) && (osver.wProductType == VER_NT_WORKSTATION)) {
615 }
else if ((osver.dwMajorVersion == 10) && (osver.dwMinorVersion == 0) && (osver.wProductType != VER_NT_WORKSTATION)) {
617 }
else if ((osver.dwMajorVersion == 6) && (osver.dwMinorVersion == 2) && (osver.wProductType == VER_NT_WORKSTATION)) {
619 }
else if ((osver.dwMajorVersion == 6) && (osver.dwMinorVersion == 3) && (osver.wProductType != VER_NT_WORKSTATION)) {
621 }
else if ((osver.dwMajorVersion == 6) && (osver.dwMinorVersion == 2) && (osver.wProductType == VER_NT_WORKSTATION)) {
623 }
else if ((osver.dwMajorVersion == 6) && (osver.dwMinorVersion == 2) && (osver.wProductType != VER_NT_WORKSTATION)) {
625 }
else if ((osver.dwMajorVersion == 6) && (osver.dwMinorVersion == 1) && (osver.wProductType == VER_NT_WORKSTATION)) {
627 }
else if ((osver.dwMajorVersion == 6) && (osver.dwMinorVersion == 1) && (osver.wProductType != VER_NT_WORKSTATION)) {
629 }
else if ((osver.dwMajorVersion == 6) && (osver.dwMinorVersion == 0) && (osver.wProductType == VER_NT_WORKSTATION)) {
631 }
else if ((osver.dwMajorVersion == 6) && (osver.dwMinorVersion == 0) && (osver.wProductType != VER_NT_WORKSTATION)) {
633 }
else if ((osver.dwMajorVersion == 5) && (osver.dwMinorVersion == 2)) {
639 }
else if ((osver.dwMajorVersion == 5) && (osver.dwMinorVersion == 2) && (osver.wProductType == VER_NT_WORKSTATION)) {
641 }
else if ((osver.dwMajorVersion == 5) && (osver.dwMinorVersion == 1)) {
643 }
else if ((osver.dwMajorVersion == 5) && (osver.dwMinorVersion == 0)) {
648 const char* a = GetEnvironmentStrings();
650 for (
size_t i = 0;; i++) {
652 std::string tmpVariable(a + prev, a + i);
653 size_t equalsSign = tmpVariable.find(
"=");
654 if (equalsSign != std::string::npos && equalsSign != 0)
656 platform.
environmentVars.
put(tmpVariable.substr(0, equalsSign), tmpVariable.substr(equalsSign + 1));
659 if (a[i + 1] ==
'\0') {
667 #if defined(__linux__)
669 if (uname(&uts) == 0) {
670 platform.
name = uts.sysname;
671 platform.
kernel = uts.release;
673 platform.
name =
"Linux";
677 FILE* release = popen(
"lsb_release -ric",
"r");
678 if (release !=
nullptr) {
679 while (fgets(
buffer, 128, release) !=
nullptr) {
681 if (getCpuEntry(
"Distributor ID",
buffer, value)) {
684 if (getCpuEntry(
"Release",
buffer, value)) {
687 if (getCpuEntry(
"Codename",
buffer, value)) {
694 char* varChar = *environ;
696 for (
int i = 0; varChar !=
nullptr; i++) {
697 std::string tmpVariable(varChar);
698 size_t equalsSign = tmpVariable.find(
'=');
699 if (equalsSign != std::string::npos) {
700 platform.
environmentVars.
put(tmpVariable.substr(0, equalsSign), tmpVariable.substr(equalsSign + 1));
702 varChar = *(environ + i);
706 #if defined(__APPLE__)
709 size_t buffLen = 512;
710 if (!sysctlbyname(
"kern.ostype", buff, &buffLen,
nullptr, 0)) {
711 platform.
name = buff;
714 if (!sysctlbyname(
"kern.osrelease", buff, &buffLen,
nullptr, 0)) {
729 char path[MAX_PATH + 1];
730 if (SHGetFolderPathA(
nullptr, CSIDL_PROFILE,
nullptr, 0, path) == S_OK)
733 char username[UNLEN + 1];
734 DWORD nsize = UNLEN + 1;
735 if (GetUserName(username, &nsize)) {
741 #if defined(__linux__) || defined(__APPLE__)
742 struct passwd* pwd = getpwuid(getuid());
744 if (pwd !=
nullptr) {
763 if (globalLoadCollector) {
764 load = globalLoadCollector->getCpuLoad();
774 #if defined(__linux__)
775 FILE* procload = fopen(
"/proc/loadavg",
"r");
776 if (procload !=
nullptr) {
780 char* tail = strchr(buff,
'/');
781 if ((tail !=
nullptr) && (tail != buff)) {
789 #if defined(__APPLE__)
791 mach_msg_type_number_t count = HOST_CPU_LOAD_INFO_COUNT;
792 host_cpu_load_info_data_t cpu_load;
794 if (KERN_SUCCESS == host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO, (host_info64_t)&cpu_load, &count)) {
797 for (
int i = 0; i < CPU_STATE_MAX; ++i) {
798 total += cpu_load.cpu_ticks[i];
801 load.
cpuLoad1 = 100.0 * cpu_load.cpu_ticks[CPU_STATE_USER] / total;
819 #if defined(__linux__)
821 char cmdline[256] = {0};
823 sprintf(filename,
"/proc/%d/cmdline", pid);
824 file = fopen(filename,
"r");
825 if (file !=
nullptr) {
826 char* p = fgets(cmdline,
sizeof(cmdline) /
sizeof(*cmdline), file);
839 size_t index = info.
name.find(
' ');
840 if (index != std::string::npos) {
841 info.
name = info.
name.substr(0, index);
849 struct sched_param param;
850 if (sched_getparam(pid, ¶m) == 0) {
855 #elif defined(_WIN32)
856 HANDLE hnd = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
858 TCHAR filename[MAX_PATH];
859 if (GetModuleBaseName(hnd, 0, filename, MAX_PATH)) {
860 info.
name = filename;
867 IWbemLocator* WbemLocator =
nullptr;
868 IWbemServices* WbemServices =
nullptr;
869 IEnumWbemClassObject* EnumWbem =
nullptr;
872 hr = CoInitializeEx(0, COINIT_MULTITHREADED);
873 hr = CoInitializeSecurity(
nullptr, -1,
nullptr,
nullptr, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE,
nullptr, EOAC_NONE,
nullptr);
874 hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&WbemLocator);
875 if (WbemLocator !=
nullptr) {
877 hr = WbemLocator->ConnectServer(L
"ROOT\\CIMV2",
nullptr,
nullptr, 0, 0, 0, 0, &WbemServices);
878 if (WbemServices !=
nullptr) {
880 hr = WbemServices->ExecQuery(L
"WQL", L
"SELECT ProcessId, CommandLine FROM Win32_Process", WBEM_FLAG_FORWARD_ONLY,
nullptr, &EnumWbem);
882 if (EnumWbem !=
nullptr) {
883 IWbemClassObject* result =
nullptr;
884 ULONG returnedCount = 0;
886 while ((hr = EnumWbem->Next(WBEM_INFINITE, 1, &result, &returnedCount)) == S_OK) {
891 hr = result->Get(L
"ProcessId", 0, &ProcessId, 0, 0);
892 hr = result->Get(L
"CommandLine", 0, &CommandLine, 0, 0);
893 if (!(CommandLine.vt == VT_NULL) && ProcessId.uintVal == (
unsigned int)pid) {
895 int res = WideCharToMultiByte(CP_UTF8, 0, CommandLine.bstrVal, -1,
nullptr, 0,
nullptr,
nullptr);
897 WideCharToMultiByte(CP_UTF8, 0, CommandLine.bstrVal, -1, &info.
arguments[0], res,
nullptr,
nullptr);
905 VariantClear(&ProcessId);
906 VariantClear(&CommandLine);
915 WbemServices->Release();
918 WbemLocator->Release();
922 #elif defined(__APPLE__)
924 size_t length =
sizeof(procInfo);
926 int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
928 if (!sysctl(mib, 4, &procInfo, &length,
nullptr, 0)) {
929 info.
name = procInfo.kp_proc.p_comm;
930 info.
pid = procInfo.kp_proc.p_pid;
933 mib[1] = KERN_PROCARGS;
938 int result = sysctl(mib, 3,
nullptr, &argv_len,
nullptr, 0);
940 yCError(SYSTEMINFO,
"sysctl: %d, %s", errno, strerror(errno));
945 proc_argv = (
char*)malloc(
sizeof(
char) * argv_len);
946 result = sysctl(mib, 3, proc_argv, &argv_len,
nullptr, 0);
948 yCError(SYSTEMINFO,
"sysctl: %d, %s", errno, strerror(errno));
956 while (index < argv_len && proc_argv[index] !=
'\0') {
965 std::stringstream arguments;
966 while (index < argv_len) {
967 if (proc_argv[index] ==
'\0' && index != argv_len - 1) {
970 arguments << proc_argv[index];