aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcommon/llsys.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llcommon/llsys.cpp
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/llcommon/llsys.cpp')
-rw-r--r--linden/indra/llcommon/llsys.cpp559
1 files changed, 559 insertions, 0 deletions
diff --git a/linden/indra/llcommon/llsys.cpp b/linden/indra/llcommon/llsys.cpp
new file mode 100644
index 0000000..148e4de
--- /dev/null
+++ b/linden/indra/llcommon/llsys.cpp
@@ -0,0 +1,559 @@
1/**
2 * @file llsys.cpp
3 * @brief Impelementation of the basic system query functions.
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "linden_common.h"
29
30#include "llsys.h"
31
32#include <iostream>
33#include <zlib/zlib.h>
34#include "processor.h"
35
36#if LL_WINDOWS
37# define WIN32_LEAN_AND_MEAN
38# include <winsock2.h>
39# include <windows.h>
40#elif LL_DARWIN
41# include <sys/sysctl.h>
42# include <sys/utsname.h>
43#elif LL_LINUX
44# include <sys/utsname.h>
45const char MEMINFO_FILE[] = "/proc/meminfo";
46const char CPUINFO_FILE[] = "/proc/cpuinfo";
47#endif
48
49
50static const S32 CPUINFO_BUFFER_SIZE = 16383;
51LLCPUInfo gSysCPU;
52
53LLOSInfo::LLOSInfo() :
54 mMajorVer(0), mMinorVer(0), mBuild(0),
55 mOSString("")
56{
57
58#if LL_WINDOWS
59 OSVERSIONINFOEX osvi;
60 BOOL bOsVersionInfoEx;
61
62 // Try calling GetVersionEx using the OSVERSIONINFOEX structure.
63 ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
64 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
65 if(!(bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO *) &osvi)))
66 {
67 // If OSVERSIONINFOEX doesn't work, try OSVERSIONINFO.
68 osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
69 if(!GetVersionEx( (OSVERSIONINFO *) &osvi))
70 return;
71 }
72 mMajorVer = osvi.dwMajorVersion;
73 mMinorVer = osvi.dwMinorVersion;
74 mBuild = osvi.dwBuildNumber;
75
76 switch(osvi.dwPlatformId)
77 {
78 case VER_PLATFORM_WIN32_NT:
79 {
80 // Test for the product.
81 if(osvi.dwMajorVersion <= 4)
82 {
83 mOSString = "Microsoft Windows NT ";
84 }
85 else if(osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
86 {
87 mOSString = "Microsoft Windows 2000 ";
88 }
89 else if(osvi.dwMajorVersion ==5 && osvi.dwMinorVersion == 1)
90 {
91 mOSString = "Microsoft Windows XP ";
92 }
93 else if(osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
94 {
95 if(osvi.wProductType == VER_NT_WORKSTATION)
96 mOSString = "Microsoft Windows XP x64 Edition ";
97 else mOSString = "Microsoft Windows Server 2003 ";
98 }
99 else if(osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0)
100 {
101 if(osvi.wProductType == VER_NT_WORKSTATION)
102 mOSString = "Microsoft Windows Vista ";
103 else mOSString = "Microsoft Windows Vista Server ";
104 }
105 else // Use the registry on early versions of Windows NT.
106 {
107 HKEY hKey;
108 WCHAR szProductType[80];
109 DWORD dwBufLen;
110 RegOpenKeyEx( HKEY_LOCAL_MACHINE,
111 L"SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
112 0, KEY_QUERY_VALUE, &hKey );
113 RegQueryValueEx( hKey, L"ProductType", NULL, NULL,
114 (LPBYTE) szProductType, &dwBufLen);
115 RegCloseKey( hKey );
116 if ( lstrcmpi( L"WINNT", szProductType) == 0 )
117 {
118 mOSString += "Professional ";
119 }
120 else if ( lstrcmpi( L"LANMANNT", szProductType) == 0 )
121 {
122 mOSString += "Server ";
123 }
124 else if ( lstrcmpi( L"SERVERNT", szProductType) == 0 )
125 {
126 mOSString += "Advanced Server ";
127 }
128 }
129
130 std::string csdversion = utf16str_to_utf8str(osvi.szCSDVersion);
131 // Display version, service pack (if any), and build number.
132 char tmp[MAX_STRING]; /* Flawfinder: ignore */
133 if(osvi.dwMajorVersion <= 4)
134 {
135 snprintf(
136 tmp,
137 sizeof(tmp),
138 "version %d.%d %s (Build %d)",
139 osvi.dwMajorVersion,
140 osvi.dwMinorVersion,
141 csdversion.c_str(),
142 (osvi.dwBuildNumber & 0xffff)); /* Flawfinder: ignore */
143 }
144 else
145 {
146 snprintf(
147 tmp,
148 sizeof(tmp),
149 "%s (Build %d)",
150 csdversion.c_str(),
151 (osvi.dwBuildNumber & 0xffff)); /*Flawfinder: ignore*/
152 }
153 mOSString += tmp;
154 }
155 break;
156
157 case VER_PLATFORM_WIN32_WINDOWS:
158 // Test for the Windows 95 product family.
159 if(osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
160 {
161 mOSString = "Microsoft Windows 95 ";
162 if ( osvi.szCSDVersion[1] == 'C' || osvi.szCSDVersion[1] == 'B' )
163 {
164 mOSString += "OSR2 ";
165 }
166 }
167 if(osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10)
168 {
169 mOSString = "Microsoft Windows 98 ";
170 if ( osvi.szCSDVersion[1] == 'A' )
171 {
172 mOSString += "SE ";
173 }
174 }
175 if(osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90)
176 {
177 mOSString = "Microsoft Windows Millennium Edition ";
178 }
179 break;
180 }
181#else
182 struct utsname un;
183 if(0==uname(&un))
184 {
185 mOSString.append(un.sysname);
186 mOSString.append(" ");
187 mOSString.append(un.release);
188 mOSString.append(" ");
189 mOSString.append(un.version);
190 mOSString.append(" ");
191 mOSString.append(un.machine);
192 }
193 else
194 {
195 mOSString.append("Unable to collect OS info");
196 }
197#endif
198
199}
200
201#ifndef LL_WINDOWS
202// static
203S32 LLOSInfo::getMaxOpenFiles()
204{
205 const S32 OPEN_MAX_GUESS = 256;
206
207#ifdef OPEN_MAX
208 static S32 open_max = OPEN_MAX;
209#else
210 static S32 open_max = 0;
211#endif
212
213 if (0 == open_max)
214 {
215 // First time through.
216 errno = 0;
217 if ( (open_max = sysconf(_SC_OPEN_MAX)) < 0)
218 {
219 if (0 == errno)
220 {
221 // Indeterminate.
222 open_max = OPEN_MAX_GUESS;
223 }
224 else
225 {
226 llerrs << "LLOSInfo::getMaxOpenFiles: sysconf error for _SC_OPEN_MAX" << llendl;
227 }
228 }
229 }
230 return open_max;
231}
232#endif
233
234void LLOSInfo::stream(std::ostream& s) const
235{
236 s << mOSString;
237}
238
239const std::string& LLOSInfo::getOSString() const
240{
241 return mOSString;
242}
243
244const S32 STATUS_SIZE = 8192;
245
246//static
247U32 LLOSInfo::getProcessVirtualSizeKB()
248{
249 U32 virtual_size = 0;
250#if LL_WINDOWS
251#endif
252#if LL_LINUX
253 FILE *status_filep = LLFile::fopen("/proc/self/status", "r");
254 S32 numRead = 0;
255 char buff[STATUS_SIZE]; /* Flawfinder: ignore */
256 bzero(buff, STATUS_SIZE);
257
258 rewind(status_filep);
259 fread(buff, 1, STATUS_SIZE-2, status_filep);
260
261 // All these guys return numbers in KB
262 char *memp = strstr(buff, "VmSize:");
263 if (memp)
264 {
265 numRead += sscanf(memp, "%*s %u", &virtual_size);
266 }
267 fclose(status_filep);
268#endif
269 return virtual_size;
270}
271
272//static
273U32 LLOSInfo::getProcessResidentSizeKB()
274{
275 U32 resident_size = 0;
276#if LL_WINDOWS
277#endif
278#if LL_LINUX
279 FILE *status_filep = LLFile::fopen("/proc/self/status", "r");
280 if (status_filep != NULL)
281 {
282 S32 numRead = 0;
283 char buff[STATUS_SIZE]; /* Flawfinder: ignore */
284 bzero(buff, STATUS_SIZE);
285
286 rewind(status_filep);
287 fread(buff, 1, STATUS_SIZE-2, status_filep);
288
289 // All these guys return numbers in KB
290 char *memp = strstr(buff, "VmRSS:");
291 if (memp)
292 {
293 numRead += sscanf(memp, "%*s %u", &resident_size);
294 }
295 fclose(status_filep);
296 }
297#endif
298 return resident_size;
299}
300
301LLCPUInfo::LLCPUInfo()
302{
303 CProcessor proc;
304 const ProcessorInfo* info = proc.GetCPUInfo();
305 mHasSSE = (info->_Ext.SSE_StreamingSIMD_Extensions != 0);
306 mHasSSE2 = (info->_Ext.SSE2_StreamingSIMD2_Extensions != 0);
307 mCPUMhz = (S32)(proc.GetCPUFrequency(50)/1000000.0);
308 mFamily.assign( info->strFamily );
309}
310
311std::string LLCPUInfo::getCPUString() const
312{
313 std::string cpu_string;
314
315#if LL_WINDOWS || LL_DARWIN
316 // gather machine information.
317 char proc_buf[CPUINFO_BUFFER_SIZE]; /* Flawfinder: ignore */
318 CProcessor proc;
319 if(proc.CPUInfoToText(proc_buf, CPUINFO_BUFFER_SIZE))
320 {
321 cpu_string.append(proc_buf);
322 }
323#else
324 cpu_string.append("Can't get CPU information");
325#endif
326
327 return cpu_string;
328}
329
330std::string LLCPUInfo::getCPUStringTerse() const
331{
332 std::string cpu_string;
333
334#if LL_WINDOWS || LL_DARWIN
335 CProcessor proc;
336 const ProcessorInfo *info = proc.GetCPUInfo();
337
338 cpu_string.append(info->strBrandID);
339
340 F64 freq = (F64)(S64)proc.GetCPUFrequency(50) / 1000000.f;
341
342 // cpu speed is often way wrong, do a sanity check
343 if (freq < 10000.f && freq > 200.f )
344 {
345 char tmp[MAX_STRING]; /* Flawfinder: ignore */
346 snprintf(tmp, sizeof(tmp), " (%.0f Mhz)", freq); /* Flawfinder: ignore */
347
348 cpu_string.append(tmp);
349 }
350#else
351 cpu_string.append("Can't get terse CPU information");
352#endif
353
354 return cpu_string;
355}
356
357void LLCPUInfo::stream(std::ostream& s) const
358{
359#if LL_WINDOWS || LL_DARWIN
360 // gather machine information.
361 char proc_buf[CPUINFO_BUFFER_SIZE]; /* Flawfinder: ignore */
362 CProcessor proc;
363 if(proc.CPUInfoToText(proc_buf, CPUINFO_BUFFER_SIZE))
364 {
365 s << proc_buf;
366 }
367 else
368 {
369 s << "Unable to collect processor info";
370 }
371#else
372 // *NOTE: This works on linux. What will it do on other systems?
373 FILE* cpuinfo = LLFile::fopen(CPUINFO_FILE, "r"); /* Flawfinder: ignore */
374 if(cpuinfo)
375 {
376 char line[MAX_STRING]; /* Flawfinder: ignore */
377 memset(line, 0, MAX_STRING);
378 while(fgets(line, MAX_STRING, cpuinfo))
379 {
380 line[strlen(line)-1] = ' '; /*Flawfinder: ignore*/
381 s << line;
382 }
383 fclose(cpuinfo);
384 }
385 else
386 {
387 s << "Unable to collect memory information";
388 }
389#endif
390}
391
392LLMemoryInfo::LLMemoryInfo()
393{
394}
395
396#if LL_LINUX
397#include <unistd.h>
398#include <sys/sysinfo.h>
399#endif
400
401U32 LLMemoryInfo::getPhysicalMemory() const
402{
403#if LL_WINDOWS
404 MEMORYSTATUS state;
405 state.dwLength = sizeof(state);
406 GlobalMemoryStatus(&state);
407
408 return (U32)state.dwTotalPhys;
409
410#elif LL_DARWIN
411 // This might work on Linux as well. Someone check...
412 unsigned int phys = 0;
413 int mib[2] = { CTL_HW, HW_PHYSMEM };
414
415 size_t len = sizeof(phys);
416 sysctl(mib, 2, &phys, &len, NULL, 0);
417
418 return phys;
419#elif LL_LINUX
420
421 return getpagesize() * get_phys_pages();
422
423#else
424 return 0;
425
426#endif
427}
428
429void LLMemoryInfo::stream(std::ostream& s) const
430{
431#if LL_WINDOWS
432 MEMORYSTATUS state;
433 state.dwLength = sizeof(state);
434 GlobalMemoryStatus(&state);
435
436 s << "Percent Memory use: " << (U32)state.dwMemoryLoad << '%' << std::endl;
437 s << "Total Physical Kb: " << (U32)state.dwTotalPhys/1024 << std::endl;
438 s << "Avail Physical Kb: " << (U32)state.dwAvailPhys/1024 << std::endl;
439 s << "Total page Kb: " << (U32)state.dwTotalPageFile/1024 << std::endl;
440 s << "Avail page Kb: " << (U32)state.dwAvailPageFile/1024 << std::endl;
441 s << "Total Virtual Kb: " << (U32)state.dwTotalVirtual/1024 << std::endl;
442 s << "Avail Virtual Kb: " << (U32)state.dwAvailVirtual/1024 << std::endl;
443#elif LL_DARWIN
444 U64 phys = 0;
445
446 size_t len = sizeof(phys);
447
448 if(sysctlbyname("hw.memsize", &phys, &len, NULL, 0) == 0)
449 {
450 s << "Total Physical Kb: " << phys/1024 << std::endl;
451 }
452 else
453 {
454 s << "Unable to collect memory information";
455 }
456
457#else
458 // *NOTE: This works on linux. What will it do on other systems?
459 FILE* meminfo = LLFile::fopen(MEMINFO_FILE,"r"); /* Flawfinder: ignore */
460 if(meminfo)
461 {
462 char line[MAX_STRING]; /* Flawfinder: ignore */
463 memset(line, 0, MAX_STRING);
464 while(fgets(line, MAX_STRING, meminfo))
465 {
466 line[strlen(line)-1] = ' '; /*Flawfinder: ignore*/
467 s << line;
468 }
469 fclose(meminfo);
470 }
471 else
472 {
473 s << "Unable to collect memory information";
474 }
475#endif
476}
477
478std::ostream& operator<<(std::ostream& s, const LLOSInfo& info)
479{
480 info.stream(s);
481 return s;
482}
483
484std::ostream& operator<<(std::ostream& s, const LLCPUInfo& info)
485{
486 info.stream(s);
487 return s;
488}
489
490std::ostream& operator<<(std::ostream& s, const LLMemoryInfo& info)
491{
492 info.stream(s);
493 return s;
494}
495
496BOOL gunzip_file(const char *srcfile, const char *dstfile)
497{
498 char tmpfile[LL_MAX_PATH]; /* Flawfinder: ignore */
499 const S32 UNCOMPRESS_BUFFER_SIZE = 32768;
500 BOOL retval = FALSE;
501 gzFile src = NULL;
502 U8 buffer[UNCOMPRESS_BUFFER_SIZE];
503 FILE *dst = NULL;
504 S32 bytes = 0;
505 (void *) strcpy(tmpfile, dstfile); /* Flawfinder: ignore */
506 (void *) strncat(tmpfile, ".t", sizeof(tmpfile) - strlen(tmpfile) -1); /* Flawfinder: ignore */
507 src = gzopen(srcfile, "rb");
508 if (! src) goto err;
509 dst = LLFile::fopen(tmpfile, "wb"); /* Flawfinder: ignore */
510 if (! dst) goto err;
511 do
512 {
513 bytes = gzread(src, buffer, UNCOMPRESS_BUFFER_SIZE);
514 fwrite(buffer, sizeof(U8), bytes, dst);
515 } while(gzeof(src) == 0);
516 fclose(dst);
517 dst = NULL;
518 if (LLFile::rename(tmpfile, dstfile) == -1) goto err; /* Flawfinder: ignore */
519 retval = TRUE;
520err:
521 if (src != NULL) gzclose(src);
522 if (dst != NULL) fclose(dst);
523 return retval;
524}
525
526BOOL gzip_file(const char *srcfile, const char *dstfile)
527{
528 const S32 COMPRESS_BUFFER_SIZE = 32768;
529 char tmpfile[LL_MAX_PATH]; /* Flawfinder: ignore */
530 BOOL retval = FALSE;
531 U8 buffer[COMPRESS_BUFFER_SIZE];
532 gzFile dst = NULL;
533 FILE *src = NULL;
534 S32 bytes = 0;
535 (void *) strcpy(tmpfile, dstfile); /* Flawfinder: ignore */
536 (void *) strncat(tmpfile, ".t", sizeof(tmpfile) - strlen(tmpfile) -1); /* Flawfinder: ignore */
537 dst = gzopen(tmpfile, "wb"); /* Flawfinder: ignore */
538 if (! dst) goto err;
539 src = LLFile::fopen(srcfile, "rb"); /* Flawfinder: ignore */
540 if (! src) goto err;
541
542 do
543 {
544 bytes = (S32)fread(buffer, sizeof(U8), COMPRESS_BUFFER_SIZE,src);
545 gzwrite(dst, buffer, bytes);
546 } while(feof(src) == 0);
547 gzclose(dst);
548 dst = NULL;
549#if LL_WINDOWS
550 // Rename in windows needs the dstfile to not exist.
551 LLFile::remove(dstfile);
552#endif
553 if (LLFile::rename(tmpfile, dstfile) == -1) goto err; /* Flawfinder: ignore */
554 retval = TRUE;
555 err:
556 if (src != NULL) fclose(src);
557 if (dst != NULL) gzclose(dst);
558 return retval;
559}