xref: /haiku/src/apps/activitymonitor/SystemInfo.cpp (revision b671e9bbdbd10268a042b4f4cc4317ccd03d105e)
1 /*
2  * Copyright 2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include "SystemInfo.h"
8 #include "SystemInfoHandler.h"
9 
10 #include <net/if.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <sys/socket.h>
14 #include <sys/sockio.h>
15 #include <unistd.h>
16 
17 
18 SystemInfo::SystemInfo(SystemInfoHandler* handler)
19 	:
20 	fTime(system_time()),
21 	fRetrievedNetwork(false),
22 	fRunningApps(0),
23 	fClipboardSize(0),
24 	fClipboardTextSize(0),
25 	fMediaNodes(0),
26 	fMediaConnections(0),
27 	fMediaBuffers(0)
28 {
29 	get_system_info(&fSystemInfo);
30 	get_system_info_etc(B_MEMORY_INFO, &fMemoryInfo,
31 		sizeof(system_memory_info));
32 
33 	if (handler != NULL) {
34 		fRunningApps = handler->RunningApps();
35 		fClipboardSize = handler->ClipboardSize();
36 		fClipboardTextSize = handler->ClipboardTextSize();
37 		fMediaNodes = handler->MediaNodes();
38 		fMediaConnections = handler->MediaConnections();
39 		fMediaBuffers = handler->MediaBuffers();
40 	}
41 }
42 
43 
44 SystemInfo::~SystemInfo()
45 {
46 }
47 
48 
49 uint64
50 SystemInfo::CachedMemory() const
51 {
52 #ifdef __HAIKU__
53 	return (uint64)fSystemInfo.cached_pages * B_PAGE_SIZE;
54 #else
55 	return 0LL;
56 #endif
57 }
58 
59 
60 uint64
61 SystemInfo::UsedMemory() const
62 {
63 	return (uint64)fSystemInfo.used_pages * B_PAGE_SIZE;
64 }
65 
66 
67 uint64
68 SystemInfo::MaxMemory() const
69 {
70 	return (uint64)fSystemInfo.max_pages * B_PAGE_SIZE;
71 }
72 
73 
74 uint32
75 SystemInfo::PageFaults() const
76 {
77 	return fMemoryInfo.page_faults;
78 }
79 
80 
81 uint64
82 SystemInfo::UsedSwapSpace() const
83 {
84 	return fMemoryInfo.max_swap_space - fMemoryInfo.free_swap_space;
85 }
86 
87 
88 uint64
89 SystemInfo::MaxSwapSpace() const
90 {
91 	return fMemoryInfo.max_swap_space;
92 }
93 
94 
95 uint32
96 SystemInfo::UsedSemaphores() const
97 {
98 	return fSystemInfo.used_sems;
99 }
100 
101 
102 uint32
103 SystemInfo::MaxSemaphores() const
104 {
105 	return fSystemInfo.max_sems;
106 }
107 
108 
109 uint32
110 SystemInfo::UsedPorts() const
111 {
112 	return fSystemInfo.used_ports;
113 }
114 
115 
116 uint32
117 SystemInfo::MaxPorts() const
118 {
119 	return fSystemInfo.max_ports;
120 }
121 
122 
123 uint32
124 SystemInfo::UsedThreads() const
125 {
126 	return fSystemInfo.used_threads;
127 }
128 
129 
130 uint32
131 SystemInfo::MaxThreads() const
132 {
133 	return fSystemInfo.max_threads;
134 }
135 
136 
137 uint32
138 SystemInfo::UsedTeams() const
139 {
140 	return fSystemInfo.used_teams;
141 }
142 
143 
144 uint32
145 SystemInfo::MaxTeams() const
146 {
147 	return fSystemInfo.max_teams;
148 }
149 
150 
151 void
152 SystemInfo::_RetrieveNetwork()
153 {
154 	if (fRetrievedNetwork)
155 		return;
156 
157 	fBytesReceived = 0;
158 	fBytesSent = 0;
159 	fRetrievedNetwork = true;
160 
161 	// we need a socket to talk to the networking stack
162 	int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
163 	if (socket < 0)
164 		return;
165 
166 	// get a list of all interfaces
167 
168 	ifconf config;
169 	config.ifc_len = sizeof(config.ifc_value);
170 	if (ioctl(socket, SIOCGIFCOUNT, &config, sizeof(struct ifconf)) < 0
171 		|| config.ifc_value == 0) {
172 		close(socket);
173 		return;
174 	}
175 
176 	uint32 count = (uint32)config.ifc_value;
177 
178 	void *buffer = malloc(count * sizeof(struct ifreq));
179 	if (buffer == NULL) {
180 		close(socket);
181 		return;
182 	}
183 
184 	config.ifc_len = count * sizeof(struct ifreq);
185 	config.ifc_buf = buffer;
186 	if (ioctl(socket, SIOCGIFCONF, &config, sizeof(struct ifconf)) < 0) {
187 		close(socket);
188 		return;
189 	}
190 
191 	ifreq *interface = (ifreq *)buffer;
192 
193 	for (uint32 i = 0; i < count; i++) {
194 		ifreq request;
195 		strlcpy(request.ifr_name, interface->ifr_name, IF_NAMESIZE);
196 
197 #ifdef __HAIKU__
198 		if (ioctl(socket, SIOCGIFSTATS, &request, sizeof(struct ifreq)) == 0) {
199 			fBytesReceived += request.ifr_stats.receive.bytes;
200 			fBytesSent += request.ifr_stats.send.bytes;
201 		}
202 #endif
203 
204 		interface = (ifreq *)((addr_t)interface + IF_NAMESIZE
205 			+ interface->ifr_addr.sa_len);
206 	}
207 
208 	free(buffer);
209 	close(socket);
210 }
211 
212 
213 uint64
214 SystemInfo::NetworkReceived()
215 {
216 	_RetrieveNetwork();
217 	return fBytesReceived;
218 }
219 
220 
221 uint64
222 SystemInfo::NetworkSent()
223 {
224 	_RetrieveNetwork();
225 	return fBytesSent;
226 }
227 
228 
229 uint32
230 SystemInfo::UsedRunningApps() const
231 {
232 	return fRunningApps;
233 }
234 
235 
236 uint32
237 SystemInfo::MaxRunningApps() const
238 {
239 	return fSystemInfo.max_teams;
240 }
241 
242 
243 uint32
244 SystemInfo::ClipboardSize() const
245 {
246 	return fClipboardSize;
247 }
248 
249 
250 uint32
251 SystemInfo::ClipboardTextSize() const
252 {
253 	return fClipboardTextSize;
254 }
255 
256 
257 uint32
258 SystemInfo::MediaNodes() const
259 {
260 	return fMediaNodes;
261 }
262 
263 
264 uint32
265 SystemInfo::MediaConnections() const
266 {
267 	return fMediaConnections;
268 }
269 
270 
271 uint32
272 SystemInfo::MediaBuffers() const
273 {
274 	return fMediaBuffers;
275 }
276 
277 
278