diff options
Diffstat (limited to 'linden/indra/llvfs')
-rw-r--r-- | linden/indra/llvfs/files.sunos5.lst | 1 | ||||
-rw-r--r-- | linden/indra/llvfs/lldir.cpp | 3 | ||||
-rw-r--r-- | linden/indra/llvfs/lldir_linux.cpp | 17 | ||||
-rw-r--r-- | linden/indra/llvfs/lldir_solaris.cpp | 374 | ||||
-rw-r--r-- | linden/indra/llvfs/lldir_solaris.h | 61 | ||||
-rw-r--r-- | linden/indra/llvfs/llvfs.cpp | 90 |
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" |
47 | LLDir_Mac gDirUtil; | 47 | LLDir_Mac gDirUtil; |
48 | #elif LL_SOLARIS | ||
49 | #include "lldir_solaris.h" | ||
50 | LLDir_Solaris gDirUtil; | ||
48 | #else | 51 | #else |
49 | #include "lldir_linux.h" | 52 | #include "lldir_linux.h" |
50 | LLDir_Linux gDirUtil; | 53 | LLDir_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 | |||
328 | std::string LLDir_Linux::getCurPath() | 337 | std::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 | |||
45 | static 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 | |||
74 | LLDir_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 | |||
141 | LLDir_Solaris::~LLDir_Solaris() | ||
142 | { | ||
143 | } | ||
144 | |||
145 | // Implementation | ||
146 | |||
147 | |||
148 | void 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 | |||
224 | U32 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 | ||
245 | BOOL 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 | ||
311 | void 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 | |||
351 | std::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 | |||
359 | BOOL 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 | |||
38 | class LLDir_Solaris : public LLDir | ||
39 | { | ||
40 | public: | ||
41 | LLDir_Solaris(); | ||
42 | virtual ~LLDir_Solaris(); | ||
43 | |||
44 | virtual void initAppDirs(const std::string &app_name); | ||
45 | public: | ||
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 | |||
52 | private: | ||
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 | } |