44
55#include " GAState.h"
66
7+ #include < errno.h>
8+ #include < linux/unistd.h>
9+ #include < linux/kernel.h>
710#include < execinfo.h>
811#include < sys/utsname.h>
912#include < sys/stat.h>
1013#include < unistd.h>
1114#include < sys/sysinfo.h>
15+ #include < sys/ioctl.h>
16+ #include < sys/socket.h>
17+ #include < linux/wireless.h>
18+ #include < ifaddrs.h>
19+
20+ struct sigaction gameanalytics::GAPlatformLinux::prevSigAction;
21+
22+ struct ProcessStat
23+ {
24+ int pid;
25+ std::string comm;
26+ char state;
27+ long ppid;
28+ long pgrp;
29+ long session;
30+ long tty_nr;
31+ long tpgid;
32+ unsigned long flags;
33+ unsigned long minflt;
34+ unsigned long cminflt;
35+ unsigned long majflt;
36+ unsigned long cmajflt;
37+ unsigned long utime;
38+ unsigned long stime;
39+ long cutime;
40+ long cstime;
41+ long priority;
42+ long nice;
43+ long num_threads;
44+ long itrealvalue;
45+ long starttime;
46+ long vsize;
47+ long rss;
48+ };
49+
50+ ProcessStat readProcessStat ()
51+ {
52+ ProcessStat stat{};
53+ std::ifstream statFile (" /proc/self/stat" );
54+
55+ if (!statFile.is_open ())
56+ {
57+ return {};
58+ }
59+
60+ std::string line;
61+ std::getline (statFile, line);
62+ std::istringstream iss (line);
63+
64+ iss >> stat.pid >> stat.comm >> stat.state >> stat.ppid >> stat.pgrp >> stat.session
65+ >> stat.tty_nr >> stat.tpgid >> stat.flags >> stat.minflt >> stat.cminflt
66+ >> stat.majflt >> stat.cmajflt >> stat.utime >> stat.stime
67+ >> stat.cutime >> stat.cstime >> stat.priority >> stat.nice
68+ >> stat.num_threads >> stat.itrealvalue >> stat.starttime >> stat.vsize >> stat.rss ;
69+
70+ return stat;
71+ }
1272
1373std::string gameanalytics::GAPlatformLinux::getOSVersion ()
1474{
@@ -156,7 +216,7 @@ void gameanalytics::GAPlatformLinux::signalHandler(int sig, siginfo_t* info, voi
156216 if (errorCount <= MAX_ERROR_TYPE_COUNT)
157217 {
158218 errorCount++;
159- events::GAEvents::addErrorEvent (EGAErrorSeverity::Critical, stackTrace, {}, false , false );
219+ events::GAEvents::addErrorEvent (EGAErrorSeverity::Critical, stackTrace, " " , - 1 , {}, false , false );
160220 events::GAEvents::processEvents (" error" , false );
161221 }
162222
@@ -180,6 +240,51 @@ std::string gameanalytics::GAPlatformLinux::getCpuModel() const
180240 return systemInfo.machine ;
181241}
182242
243+ std::string gameanalytics::GAPlatformLinux::getConnectionType ()
244+ {
245+ struct ifaddrs * list = nullptr ;
246+ struct ifaddrs * current = nullptr ;
247+
248+ std::string connection = CONNECTION_OFFLINE;
249+
250+ if (getifaddrs (&list) == -1 )
251+ {
252+ return connection;
253+ }
254+
255+ current = list;
256+ while (current)
257+ {
258+ int sock = -1 ;
259+ if (!current->ifa_addr || current->ifa_addr ->sa_family != AF_PACKET)
260+ {
261+ struct iwreq req = {};
262+ strncpy (req.ifr_name , current->ifa_name , IFNAMSIZ);
263+
264+ int sock = socket (AF_INET, SOCK_STREAM, 0 );
265+ if (sock == -1 )
266+ {
267+ connection = CONNECTION_LAN;
268+ }
269+ else
270+ {
271+ if (ioctl (sock, SIOCGIWNAME, &req) != -1 )
272+ {
273+ connection = CONNECTION_WIFI;
274+ }
275+ }
276+ }
277+
278+ if (sock != -1 )
279+ close (sock);
280+
281+ current = current->ifa_next ;
282+ }
283+
284+ freeifaddrs (list);
285+ return connection;
286+ }
287+
183288std::string gameanalytics::GAPlatformLinux::getGpuModel () const
184289{
185290 return UNKNOWN_VALUE;
@@ -203,59 +308,42 @@ int64_t gameanalytics::GAPlatformLinux::getTotalDeviceMemory() const
203308
204309int64_t gameanalytics::GAPlatformLinux::getAppMemoryUsage () const
205310{
206- struct task_basic_info info;
207-
208- mach_msg_type_number_t infoSize = TASK_BASIC_INFO_COUNT;
209- kern_return_t result = task_info (mach_task_self (), TASK_BASIC_INFO, (task_info_t )&info, &infoSize);
210-
211- if (result == KERN_SUCCESS)
212- {
213- return utilities::convertBytesToMB (info.resident_size );
214- }
311+ constexpr int k_pageSize = 1024 ;
312+ ProcessStat proc = readProcessStat ();
215313
216- return 0 ;
314+ int64_t vmUsage = proc.vsize / k_pageSize;
315+ int64_t resident = proc.rss * (sysconf (_SC_PAGE_SIZE) / k_pageSize);
316+
317+ int64_t inBytes = (vmUsage + resident) * 1024 ;
318+
319+ return utilities::convertBytesToMB (inBytes);
217320}
218321
219322int64_t gameanalytics::GAPlatformLinux::getSysMemoryUsage () const
220323{
221- mach_port_t port = mach_host_self ();
222- mach_msg_type_number_t hostSize = sizeof (vm_statistics_data_t ) / sizeof (integer_t );
223-
224- vm_size_t pageSize;
225- host_page_size (port, &pageSize);
226-
227- vm_statistics_data_t stats;
228-
229- if (host_statistics (port, HOST_VM_INFO, (host_info_t )&stats, &hostSize) == KERN_SUCCESS)
324+ struct sysinfo info = {};
325+ if (sysinfo (&info) == 0 )
230326 {
231- const int64_t freeMemory = (stats.free_count + stats.inactive_count ) * pageSize;
232- return getTotalDeviceMemory () - utilities::convertBytesToMB (freeMemory);
327+ return utilities::convertBytesToMB (info.totalram - info.freeram );
233328 }
234329
235330 return 0 ;
236331}
237332
238333int64_t gameanalytics::GAPlatformLinux::getBootTime () const
239334{
240- const size_t len = 4 ;
241- int mib[len] = {0 ,0 ,0 ,0 };
242- struct kinfo_proc kp = {};
335+ ProcessStat procStat = readProcessStat ();
243336
244- const size_t pidId = 3 ;
245-
246- size_t num = len;
247- sysctlnametomib (" kern.proc.pid" , mib, &num);
248- mib[pidId] = getpid ();
249-
250- num = sizeof (kp);
251- sysctl (mib, len, &kp, &num, NULL , 0 );
337+ struct sysinfo info = {};
338+ if (sysinfo (&info) != 0 )
339+ {
340+ return 0 ;
341+ }
252342
253- struct timeval startTime = kp.kp_proc .p_un .__p_starttime ;
254- struct timeval currentTime = {};
255-
256- gettimeofday (¤tTime, NULL );
257-
258- return currentTime.tv_sec - startTime.tv_sec ;
343+ int64_t startTime = procStat.starttime / sysconf (_SC_CLK_TCK);
344+ int64_t bootTime = info.uptime - startTime;
345+
346+ return bootTime;
259347}
260348
261349#endif
0 commit comments