diff options
author | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
commit | 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch) | |
tree | adca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llcommon/llsys.cpp | |
parent | README.txt (diff) | |
download | meta-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.cpp | 559 |
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> | ||
45 | const char MEMINFO_FILE[] = "/proc/meminfo"; | ||
46 | const char CPUINFO_FILE[] = "/proc/cpuinfo"; | ||
47 | #endif | ||
48 | |||
49 | |||
50 | static const S32 CPUINFO_BUFFER_SIZE = 16383; | ||
51 | LLCPUInfo gSysCPU; | ||
52 | |||
53 | LLOSInfo::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 | ||
203 | S32 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 | |||
234 | void LLOSInfo::stream(std::ostream& s) const | ||
235 | { | ||
236 | s << mOSString; | ||
237 | } | ||
238 | |||
239 | const std::string& LLOSInfo::getOSString() const | ||
240 | { | ||
241 | return mOSString; | ||
242 | } | ||
243 | |||
244 | const S32 STATUS_SIZE = 8192; | ||
245 | |||
246 | //static | ||
247 | U32 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 | ||
273 | U32 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 | |||
301 | LLCPUInfo::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 | |||
311 | std::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 | |||
330 | std::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 | |||
357 | void 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 | |||
392 | LLMemoryInfo::LLMemoryInfo() | ||
393 | { | ||
394 | } | ||
395 | |||
396 | #if LL_LINUX | ||
397 | #include <unistd.h> | ||
398 | #include <sys/sysinfo.h> | ||
399 | #endif | ||
400 | |||
401 | U32 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 | |||
429 | void 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 | |||
478 | std::ostream& operator<<(std::ostream& s, const LLOSInfo& info) | ||
479 | { | ||
480 | info.stream(s); | ||
481 | return s; | ||
482 | } | ||
483 | |||
484 | std::ostream& operator<<(std::ostream& s, const LLCPUInfo& info) | ||
485 | { | ||
486 | info.stream(s); | ||
487 | return s; | ||
488 | } | ||
489 | |||
490 | std::ostream& operator<<(std::ostream& s, const LLMemoryInfo& info) | ||
491 | { | ||
492 | info.stream(s); | ||
493 | return s; | ||
494 | } | ||
495 | |||
496 | BOOL 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; | ||
520 | err: | ||
521 | if (src != NULL) gzclose(src); | ||
522 | if (dst != NULL) fclose(dst); | ||
523 | return retval; | ||
524 | } | ||
525 | |||
526 | BOOL 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 | } | ||