aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llvfs
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llvfs')
-rw-r--r--linden/indra/llvfs/files.sunos5.lst1
-rw-r--r--linden/indra/llvfs/lldir.cpp3
-rw-r--r--linden/indra/llvfs/lldir_linux.cpp17
-rw-r--r--linden/indra/llvfs/lldir_solaris.cpp374
-rw-r--r--linden/indra/llvfs/lldir_solaris.h61
-rw-r--r--linden/indra/llvfs/llvfs.cpp90
6 files changed, 523 insertions, 23 deletions
diff --git a/linden/indra/llvfs/files.sunos5.lst b/linden/indra/llvfs/files.sunos5.lst
new file mode 100644
index 0000000..f1b74d8
--- /dev/null
+++ b/linden/indra/llvfs/files.sunos5.lst
@@ -0,0 +1 @@
llvfs/lldir_solaris.cpp
diff --git a/linden/indra/llvfs/lldir.cpp b/linden/indra/llvfs/lldir.cpp
index d71224a..5f0efbe 100644
--- a/linden/indra/llvfs/lldir.cpp
+++ b/linden/indra/llvfs/lldir.cpp
@@ -45,6 +45,9 @@ LLDir_Win32 gDirUtil;
45#elif LL_DARWIN 45#elif LL_DARWIN
46#include "lldir_mac.h" 46#include "lldir_mac.h"
47LLDir_Mac gDirUtil; 47LLDir_Mac gDirUtil;
48#elif LL_SOLARIS
49#include "lldir_solaris.h"
50LLDir_Solaris gDirUtil;
48#else 51#else
49#include "lldir_linux.h" 52#include "lldir_linux.h"
50LLDir_Linux gDirUtil; 53LLDir_Linux gDirUtil;
diff --git a/linden/indra/llvfs/lldir_linux.cpp b/linden/indra/llvfs/lldir_linux.cpp
index e3aada6..7cf1c2a 100644
--- a/linden/indra/llvfs/lldir_linux.cpp
+++ b/linden/indra/llvfs/lldir_linux.cpp
@@ -75,7 +75,16 @@ LLDir_Linux::LLDir_Linux()
75 mDirp = NULL; 75 mDirp = NULL;
76 76
77 char tmp_str[LL_MAX_PATH]; /* Flawfinder: ignore */ 77 char tmp_str[LL_MAX_PATH]; /* Flawfinder: ignore */
78 getcwd(tmp_str, LL_MAX_PATH); 78 if (getcwd(tmp_str, LL_MAX_PATH) == NULL)
79 {
80 strcpy(tmp_str, "/tmp");
81 llwarns << "Could not get current directory; changing to "
82 << tmp_str << llendl;
83 if (chdir(tmp_str) == -1)
84 {
85 llerrs << "Could not change directory to " << tmp_str << llendl;
86 }
87 }
79 88
80 mExecutableFilename = ""; 89 mExecutableFilename = "";
81 mExecutablePathAndName = ""; 90 mExecutablePathAndName = "";
@@ -328,7 +337,11 @@ void LLDir_Linux::getRandomFileInDir(const std::string &dirname, const std::stri
328std::string LLDir_Linux::getCurPath() 337std::string LLDir_Linux::getCurPath()
329{ 338{
330 char tmp_str[LL_MAX_PATH]; /* Flawfinder: ignore */ 339 char tmp_str[LL_MAX_PATH]; /* Flawfinder: ignore */
331 getcwd(tmp_str, LL_MAX_PATH); 340 if (getcwd(tmp_str, LL_MAX_PATH) == NULL)
341 {
342 llwarns << "Could not get current directory" << llendl;
343 tmp_str[0] = '\0';
344 }
332 return tmp_str; 345 return tmp_str;
333} 346}
334 347
diff --git a/linden/indra/llvfs/lldir_solaris.cpp b/linden/indra/llvfs/lldir_solaris.cpp
new file mode 100644
index 0000000..41262aa
--- /dev/null
+++ b/linden/indra/llvfs/lldir_solaris.cpp
@@ -0,0 +1,374 @@
1/**
2 * @file fmodwrapper.cpp
3 * @brief dummy source file for building a shared library to wrap libfmod.a
4 *
5 * Copyright (c) 2005-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
29#include "linden_common.h"
30
31#include "lldir_solaris.h"
32#include "llerror.h"
33#include "llrand.h"
34#include <sys/types.h>
35#include <sys/stat.h>
36#include <fcntl.h>
37#include <sys/param.h>
38#include <unistd.h>
39#include <glob.h>
40#include <pwd.h>
41#include <sys/utsname.h>
42#define _STRUCTURED_PROC 1
43#include <sys/procfs.h>
44
45static std::string getCurrentUserHome(char* fallback)
46{
47 const uid_t uid = getuid();
48 struct passwd *pw;
49 char *result_cstr = fallback;
50
51 pw = getpwuid(uid);
52 if ((pw != NULL) && (pw->pw_dir != NULL))
53 {
54 result_cstr = (char*) pw->pw_dir;
55 }
56 else
57 {
58 llinfos << "Couldn't detect home directory from passwd - trying $HOME" << llendl;
59 const char *const home_env = getenv("HOME"); /* Flawfinder: ignore */
60 if (home_env)
61 {
62 result_cstr = (char*) home_env;
63 }
64 else
65 {
66 llwarns << "Couldn't detect home directory! Falling back to " << fallback << llendl;
67 }
68 }
69
70 return std::string(result_cstr);
71}
72
73
74LLDir_Solaris::LLDir_Solaris()
75{
76 mDirDelimiter = "/";
77 mCurrentDirIndex = -1;
78 mCurrentDirCount = -1;
79 mDirp = NULL;
80
81 char tmp_str[LL_MAX_PATH]; /* Flawfinder: ignore */
82 getcwd(tmp_str, LL_MAX_PATH);
83
84 mExecutableFilename = "";
85 mExecutablePathAndName = "";
86 mExecutableDir = strdup(tmp_str);
87 mWorkingDir = strdup(tmp_str);
88 mAppRODataDir = strdup(tmp_str);
89 mOSUserDir = getCurrentUserHome(tmp_str);
90 mOSUserAppDir = "";
91 mLindenUserDir = tmp_str;
92
93 char path [LL_MAX_PATH]; /* Flawfinder: ignore */
94
95 sprintf(path, "/proc/%d/psinfo", (int)getpid());
96 int proc_fd = -1;
97 if((proc_fd = open(path, O_RDONLY)) == -1){
98 llwarns << "unable to open " << path << llendl;
99 return;
100 }
101 psinfo_t proc_psinfo;
102 if(read(proc_fd, &proc_psinfo, sizeof(psinfo_t)) != sizeof(psinfo_t)){
103 llwarns << "Unable to read " << path << llendl;
104 close(proc_fd);
105 return;
106 }
107
108 close(proc_fd);
109
110 mExecutableFilename = strdup(proc_psinfo.pr_fname);
111 llinfos << "mExecutableFilename = [" << mExecutableFilename << "]" << llendl;
112
113 sprintf(path, "/proc/%d/path/a.out", (int)getpid());
114
115 char execpath[LL_MAX_PATH];
116 if(readlink(path, execpath, LL_MAX_PATH) == -1){
117 llwarns << "Unable to read link from " << path << llendl;
118 return;
119 }
120
121 mExecutablePathAndName = strdup(execpath);
122 llinfos << "mExecutablePathAndName = [" << mExecutablePathAndName << "]" << llendl;
123
124 // plunk a null at last '/' to get exec dir
125 char *s = execpath + strlen(execpath) -1;
126 while(*s != '/' && s != execpath){
127 --s;
128 }
129
130 if(s != execpath){
131 *s = (char)NULL;
132
133 mExecutableDir = strdup(execpath);
134 llinfos << "mExecutableDir = [" << mExecutableDir << "]" << llendl;
135 }
136
137 // *TODO: don't use /tmp, use $HOME/.secondlife/tmp or something.
138 mTempDir = "/tmp";
139}
140
141LLDir_Solaris::~LLDir_Solaris()
142{
143}
144
145// Implementation
146
147
148void LLDir_Solaris::initAppDirs(const std::string &app_name)
149{
150 mAppName = app_name;
151
152 LLString upper_app_name(app_name);
153 LLString::toUpper(upper_app_name);
154
155 char* app_home_env = getenv((upper_app_name + "_USER_DIR").c_str()); /* Flawfinder: ignore */
156 if (app_home_env)
157 {
158 // user has specified own userappdir i.e. $SECONDLIFE_USER_DIR
159 mOSUserAppDir = app_home_env;
160 }
161 else
162 {
163 // traditionally on unixoids, MyApp gets ~/.myapp dir for data
164 mOSUserAppDir = mOSUserDir;
165 mOSUserAppDir += "/";
166 mOSUserAppDir += ".";
167 LLString lower_app_name(app_name);
168 LLString::toLower(lower_app_name);
169 mOSUserAppDir += lower_app_name;
170 }
171
172 // create any directories we expect to write to.
173
174 int res = LLFile::mkdir(mOSUserAppDir.c_str());
175 if (res == -1)
176 {
177 if (errno != EEXIST)
178 {
179 llwarns << "Couldn't create app user dir " << mOSUserAppDir << llendl;
180 llwarns << "Default to base dir" << mOSUserDir << llendl;
181 mOSUserAppDir = mOSUserDir;
182 }
183 }
184
185 res = LLFile::mkdir(getExpandedFilename(LL_PATH_LOGS,"").c_str());
186 if (res == -1)
187 {
188 if (errno != EEXIST)
189 {
190 llwarns << "Couldn't create LL_PATH_LOGS dir " << getExpandedFilename(LL_PATH_LOGS,"") << llendl;
191 }
192 }
193
194 res = LLFile::mkdir(getExpandedFilename(LL_PATH_USER_SETTINGS,"").c_str());
195 if (res == -1)
196 {
197 if (errno != EEXIST)
198 {
199 llwarns << "Couldn't create LL_PATH_USER_SETTINGS dir " << getExpandedFilename(LL_PATH_USER_SETTINGS,"") << llendl;
200 }
201 }
202
203 res = LLFile::mkdir(getExpandedFilename(LL_PATH_CACHE,"").c_str());
204 if (res == -1)
205 {
206 if (errno != EEXIST)
207 {
208 llwarns << "Couldn't create LL_PATH_CACHE dir " << getExpandedFilename(LL_PATH_CACHE,"") << llendl;
209 }
210 }
211
212 res = LLFile::mkdir(getExpandedFilename(LL_PATH_MOZILLA_PROFILE,"").c_str());
213 if (res == -1)
214 {
215 if (errno != EEXIST)
216 {
217 llwarns << "Couldn't create LL_PATH_MOZILLA_PROFILE dir " << getExpandedFilename(LL_PATH_MOZILLA_PROFILE,"") << llendl;
218 }
219 }
220
221 mCAFile = getExpandedFilename(LL_PATH_APP_SETTINGS, "CA.pem");
222}
223
224U32 LLDir_Solaris::countFilesInDir(const std::string &dirname, const std::string &mask)
225{
226 U32 file_count = 0;
227 glob_t g;
228
229 std::string tmp_str;
230 tmp_str = dirname;
231 tmp_str += mask;
232
233 if(glob(tmp_str.c_str(), GLOB_NOSORT, NULL, &g) == 0)
234 {
235 file_count = g.gl_pathc;
236
237 globfree(&g);
238 }
239
240 return (file_count);
241}
242
243// get the next file in the directory
244// automatically wrap if we've hit the end
245BOOL LLDir_Solaris::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname, BOOL wrap)
246{
247 glob_t g;
248 BOOL result = FALSE;
249 fname = "";
250
251 if(!(dirname == mCurrentDir))
252 {
253 // different dir specified, close old search
254 mCurrentDirIndex = -1;
255 mCurrentDirCount = -1;
256 mCurrentDir = dirname;
257 }
258
259 std::string tmp_str;
260 tmp_str = dirname;
261 tmp_str += mask;
262
263 if(glob(tmp_str.c_str(), GLOB_NOSORT, NULL, &g) == 0)
264 {
265 if(g.gl_pathc > 0)
266 {
267 if((int)g.gl_pathc != mCurrentDirCount)
268 {
269 // Number of matches has changed since the last search, meaning a file has been added or deleted.
270 // Reset the index.
271 mCurrentDirIndex = -1;
272 mCurrentDirCount = g.gl_pathc;
273 }
274
275 mCurrentDirIndex++;
276
277 if((mCurrentDirIndex >= (int)g.gl_pathc) && wrap)
278 {
279 mCurrentDirIndex = 0;
280 }
281
282 if(mCurrentDirIndex < (int)g.gl_pathc)
283 {
284// llinfos << "getNextFileInDir: returning number " << mCurrentDirIndex << ", path is " << g.gl_pathv[mCurrentDirIndex] << llendl;
285
286 // The API wants just the filename, not the full path.
287 //fname = g.gl_pathv[mCurrentDirIndex];
288
289 char *s = strrchr(g.gl_pathv[mCurrentDirIndex], '/');
290
291 if(s == NULL)
292 s = g.gl_pathv[mCurrentDirIndex];
293 else if(s[0] == '/')
294 s++;
295
296 fname = s;
297
298 result = TRUE;
299 }
300 }
301
302 globfree(&g);
303 }
304
305 return(result);
306}
307
308
309// get a random file in the directory
310// automatically wrap if we've hit the end
311void LLDir_Solaris::getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname)
312{
313 S32 num_files;
314 S32 which_file;
315 DIR *dirp;
316 dirent *entryp = NULL;
317
318 fname = "";
319
320 num_files = countFilesInDir(dirname,mask);
321 if (!num_files)
322 {
323 return;
324 }
325
326 which_file = ll_rand(num_files);
327
328// llinfos << "Random select file #" << which_file << llendl;
329
330 // which_file now indicates the (zero-based) index to which file to play
331
332 if (!((dirp = opendir(dirname.c_str()))))
333 {
334 while (which_file--)
335 {
336 if (!((entryp = readdir(dirp))))
337 {
338 return;
339 }
340 }
341
342 if ((!which_file) && entryp)
343 {
344 fname = entryp->d_name;
345 }
346
347 closedir(dirp);
348 }
349}
350
351std::string LLDir_Solaris::getCurPath()
352{
353 char tmp_str[LL_MAX_PATH]; /* Flawfinder: ignore */
354 getcwd(tmp_str, LL_MAX_PATH);
355 return tmp_str;
356}
357
358
359BOOL LLDir_Solaris::fileExists(const std::string &filename)
360{
361 struct stat stat_data;
362 // Check the age of the file
363 // Now, we see if the files we've gathered are recent...
364 int res = stat(filename.c_str(), &stat_data);
365 if (!res)
366 {
367 return TRUE;
368 }
369 else
370 {
371 return FALSE;
372 }
373}
374
diff --git a/linden/indra/llvfs/lldir_solaris.h b/linden/indra/llvfs/lldir_solaris.h
new file mode 100644
index 0000000..4a8feed
--- /dev/null
+++ b/linden/indra/llvfs/lldir_solaris.h
@@ -0,0 +1,61 @@
1/**
2 * @file fmodwrapper.cpp
3 * @brief dummy source file for building a shared library to wrap libfmod.a
4 *
5 * Copyright (c) 2005-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
29#ifndef LL_LLDIR_SOLARIS_H
30#define LL_LLDIR_SOLARIS_H
31
32#include "lldir.h"
33
34#include <stdio.h>
35#include <dirent.h>
36#include <errno.h>
37
38class LLDir_Solaris : public LLDir
39{
40public:
41 LLDir_Solaris();
42 virtual ~LLDir_Solaris();
43
44 virtual void initAppDirs(const std::string &app_name);
45public:
46 virtual std::string getCurPath();
47 virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask);
48 virtual BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname, BOOL wrap);
49 virtual void getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname);
50 /*virtual*/ BOOL fileExists(const std::string &filename);
51
52private:
53 DIR *mDirp;
54 int mCurrentDirIndex;
55 int mCurrentDirCount;
56 std::string mCurrentDir;
57};
58
59#endif // LL_LLDIR_SOLARIS_H
60
61
diff --git a/linden/indra/llvfs/llvfs.cpp b/linden/indra/llvfs/llvfs.cpp
index dd5854c..a05d1b9 100644
--- a/linden/indra/llvfs/llvfs.cpp
+++ b/linden/indra/llvfs/llvfs.cpp
@@ -35,6 +35,10 @@
35#include <map> 35#include <map>
36#if LL_WINDOWS 36#if LL_WINDOWS
37#include <share.h> 37#include <share.h>
38#elif LL_SOLARIS
39#include <sys/types.h>
40#include <unistd.h>
41#include <fcntl.h>
38#else 42#else
39#include <sys/file.h> 43#include <sys/file.h>
40#endif 44#endif
@@ -379,13 +383,13 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r
379 ) 383 )
380 { 384 {
381 U8 *buffer = new U8[fbuf.st_size]; 385 U8 *buffer = new U8[fbuf.st_size];
382 fread(buffer, fbuf.st_size, 1, mIndexFP); 386 size_t nread = fread(buffer, 1, fbuf.st_size, mIndexFP);
383 387
384 U8 *tmp_ptr = buffer; 388 U8 *tmp_ptr = buffer;
385 389
386 std::vector<LLVFSFileBlock*> files_by_loc; 390 std::vector<LLVFSFileBlock*> files_by_loc;
387 391
388 while (tmp_ptr < buffer + fbuf.st_size) 392 while (tmp_ptr < buffer + nread)
389 { 393 {
390 LLVFSFileBlock *block = new LLVFSFileBlock(); 394 LLVFSFileBlock *block = new LLVFSFileBlock();
391 395
@@ -881,12 +885,18 @@ BOOL LLVFS::setMaxSize(const LLUUID &file_id, const LLAssetType::EType file_type
881 // move the file into the new block 885 // move the file into the new block
882 U8 *buffer = new U8[block->mSize]; 886 U8 *buffer = new U8[block->mSize];
883 fseek(mDataFP, block->mLocation, SEEK_SET); 887 fseek(mDataFP, block->mLocation, SEEK_SET);
884 fread(buffer, block->mSize, 1, mDataFP); 888 if (fread(buffer, block->mSize, 1, mDataFP) == 1)
885 fseek(mDataFP, free_block->mLocation, SEEK_SET); 889 {
886 fwrite(buffer, block->mSize, 1, mDataFP); 890 fseek(mDataFP, free_block->mLocation, SEEK_SET);
887 // fflush(mDataFP); 891 if (fwrite(buffer, block->mSize, 1, mDataFP) != 1)
888 892 {
889 delete[] buffer; 893 llwarns << "Short write" << llendl;
894 }
895
896 delete[] buffer;
897 } else {
898 llwarns << "Short read" << llendl;
899 }
890 } 900 }
891 } 901 }
892 902
@@ -1486,7 +1496,7 @@ void LLVFS::sync(LLVFSFileBlock *block, BOOL remove)
1486 } 1496 }
1487 1497
1488 BOOL set_index_to_end = FALSE; 1498 BOOL set_index_to_end = FALSE;
1489 S32 seek_pos = block->mIndexLocation; 1499 long seek_pos = block->mIndexLocation;
1490 1500
1491 if (-1 == seek_pos) 1501 if (-1 == seek_pos)
1492 { 1502 {
@@ -1534,7 +1544,11 @@ void LLVFS::sync(LLVFSFileBlock *block, BOOL remove)
1534 fseek(mIndexFP, seek_pos, SEEK_SET); 1544 fseek(mIndexFP, seek_pos, SEEK_SET);
1535 } 1545 }
1536 1546
1537 fwrite(buffer, LLVFSFileBlock::SERIAL_SIZE, 1, mIndexFP); 1547 if (fwrite(buffer, LLVFSFileBlock::SERIAL_SIZE, 1, mIndexFP) != 1)
1548 {
1549 llwarns << "Short write" << llendl;
1550 }
1551
1538 // fflush(mIndexFP); 1552 // fflush(mIndexFP);
1539 1553
1540 lockData(); 1554 lockData();
@@ -1663,18 +1677,24 @@ void LLVFS::pokeFiles()
1663 // only write data if we actually read 4 bytes 1677 // only write data if we actually read 4 bytes
1664 // otherwise we're writing garbage and screwing up the file 1678 // otherwise we're writing garbage and screwing up the file
1665 fseek(mDataFP, 0, SEEK_SET); 1679 fseek(mDataFP, 0, SEEK_SET);
1666 if (fread(&word, 1, 4, mDataFP) == 4) 1680 if (fread(&word, sizeof(word), 1, mDataFP) == 1)
1667 { 1681 {
1668 fseek(mDataFP, 0, SEEK_SET); 1682 fseek(mDataFP, 0, SEEK_SET);
1669 fwrite(&word, 1, 4, mDataFP); 1683 if (fwrite(&word, sizeof(word), 1, mDataFP) != 1)
1684 {
1685 llwarns << "Could not write to data file" << llendl;
1686 }
1670 fflush(mDataFP); 1687 fflush(mDataFP);
1671 } 1688 }
1672 1689
1673 fseek(mIndexFP, 0, SEEK_SET); 1690 fseek(mIndexFP, 0, SEEK_SET);
1674 if (fread(&word, 1, 4, mIndexFP) == 4) 1691 if (fread(&word, sizeof(word), 1, mIndexFP) == 1)
1675 { 1692 {
1676 fseek(mIndexFP, 0, SEEK_SET); 1693 fseek(mIndexFP, 0, SEEK_SET);
1677 fwrite(&word, 1, 4, mIndexFP); 1694 if (fwrite(&word, sizeof(word), 1, mIndexFP) != 1)
1695 {
1696 llwarns << "Could not write to index file" << llendl;
1697 }
1678 fflush(mIndexFP); 1698 fflush(mIndexFP);
1679 } 1699 }
1680} 1700}
@@ -1709,21 +1729,26 @@ void LLVFS::audit()
1709 fflush(mIndexFP); 1729 fflush(mIndexFP);
1710 1730
1711 fseek(mIndexFP, 0, SEEK_END); 1731 fseek(mIndexFP, 0, SEEK_END);
1712 S32 index_size = ftell(mIndexFP); 1732 long index_size = ftell(mIndexFP);
1713 fseek(mIndexFP, 0, SEEK_SET); 1733 fseek(mIndexFP, 0, SEEK_SET);
1714 1734
1735 BOOL vfs_corrupt = FALSE;
1736
1715 U8 *buffer = new U8[index_size]; 1737 U8 *buffer = new U8[index_size];
1716 fread(buffer, index_size, 1, mIndexFP); 1738
1739 if (fread(buffer, 1, index_size, mIndexFP) != index_size)
1740 {
1741 llwarns << "Index truncated" << llendl;
1742 vfs_corrupt = TRUE;
1743 }
1717 1744
1718 U8 *tmp_ptr = buffer; 1745 U8 *tmp_ptr = buffer;
1719 1746
1720 std::map<LLVFSFileSpecifier, LLVFSFileBlock*> found_files; 1747 std::map<LLVFSFileSpecifier, LLVFSFileBlock*> found_files;
1721 U32 cur_time = (U32)time(NULL); 1748 U32 cur_time = (U32)time(NULL);
1722 1749
1723 BOOL vfs_corrupt = FALSE;
1724
1725 std::vector<LLVFSFileBlock*> audit_blocks; 1750 std::vector<LLVFSFileBlock*> audit_blocks;
1726 while (tmp_ptr < buffer + index_size) 1751 while (!vfs_corrupt && tmp_ptr < buffer + index_size)
1727 { 1752 {
1728 LLVFSFileBlock *block = new LLVFSFileBlock(); 1753 LLVFSFileBlock *block = new LLVFSFileBlock();
1729 audit_blocks.push_back(block); 1754 audit_blocks.push_back(block);
@@ -1803,7 +1828,11 @@ void LLVFS::audit()
1803 llwarns << "VFile " << block->mFileID << ":" << block->mFileType << " in memory, not on disk, loc " << block->mIndexLocation<< llendl; 1828 llwarns << "VFile " << block->mFileID << ":" << block->mFileType << " in memory, not on disk, loc " << block->mIndexLocation<< llendl;
1804 fseek(mIndexFP, block->mIndexLocation, SEEK_SET); 1829 fseek(mIndexFP, block->mIndexLocation, SEEK_SET);
1805 U8 buf[LLVFSFileBlock::SERIAL_SIZE]; 1830 U8 buf[LLVFSFileBlock::SERIAL_SIZE];
1806 fread(buf, LLVFSFileBlock::SERIAL_SIZE, 1, mIndexFP); 1831 if (fread(buf, LLVFSFileBlock::SERIAL_SIZE, 1, mIndexFP) != 1)
1832 {
1833 llwarns << "VFile " << block->mFileID
1834 << " gave short read" << llendl;
1835 }
1807 1836
1808 LLVFSFileBlock disk_block; 1837 LLVFSFileBlock disk_block;
1809 disk_block.deserialize(buf, block->mIndexLocation); 1838 disk_block.deserialize(buf, block->mIndexLocation);
@@ -2116,6 +2145,12 @@ FILE *LLVFS::openAndLock(const char *filename, const char *mode, BOOL read_lock)
2116 int fd; 2145 int fd;
2117 2146
2118 // first test the lock in a non-destructive way 2147 // first test the lock in a non-destructive way
2148#if LL_SOLARIS
2149 struct flock fl;
2150 fl.l_whence = SEEK_SET;
2151 fl.l_start = 0;
2152 fl.l_len = 1;
2153#else // !LL_SOLARIS
2119 if (strstr(mode, "w")) 2154 if (strstr(mode, "w"))
2120 { 2155 {
2121 fp = LLFile::fopen(filename, "rb"); /* Flawfinder: ignore */ 2156 fp = LLFile::fopen(filename, "rb"); /* Flawfinder: ignore */
@@ -2131,13 +2166,19 @@ FILE *LLVFS::openAndLock(const char *filename, const char *mode, BOOL read_lock)
2131 fclose(fp); 2166 fclose(fp);
2132 } 2167 }
2133 } 2168 }
2169#endif // !LL_SOLARIS
2134 2170
2135 // now actually open the file for use 2171 // now actually open the file for use
2136 fp = LLFile::fopen(filename, mode); /* Flawfinder: ignore */ 2172 fp = LLFile::fopen(filename, mode); /* Flawfinder: ignore */
2137 if (fp) 2173 if (fp)
2138 { 2174 {
2139 fd = fileno(fp); 2175 fd = fileno(fp);
2176#if LL_SOLARIS
2177 fl.l_type = read_lock ? F_RDLCK : F_WRLCK;
2178 if (fcntl(fd, F_SETLK, &fl) == -1)
2179#else
2140 if (flock(fd, (read_lock ? LOCK_SH : LOCK_EX) | LOCK_NB) == -1) 2180 if (flock(fd, (read_lock ? LOCK_SH : LOCK_EX) | LOCK_NB) == -1)
2181#endif
2141 { 2182 {
2142 fclose(fp); 2183 fclose(fp);
2143 fp = NULL; 2184 fp = NULL;
@@ -2165,7 +2206,14 @@ void LLVFS::unlockAndClose(FILE *fp)
2165 flock(fd, LOCK_UN); 2206 flock(fd, LOCK_UN);
2166 #endif 2207 #endif
2167 */ 2208 */
2168 2209#if LL_SOLARIS
2210 struct flock fl;
2211 fl.l_whence = SEEK_SET;
2212 fl.l_start = 0;
2213 fl.l_len = 1;
2214 fl.l_type = F_UNLCK;
2215 fcntl(fileno(fp), F_SETLK, &fl);
2216#endif
2169 fclose(fp); 2217 fclose(fp);
2170 } 2218 }
2171} 2219}