Merge lp:~widelands-dev/widelands/filesystem-errors into lp:widelands
- filesystem-errors
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 8921 |
Proposed branch: | lp:~widelands-dev/widelands/filesystem-errors |
Merge into: | lp:widelands |
Diff against target: |
361 lines (+85/-88) 4 files modified
src/io/filesystem/disk_filesystem.cc (+69/-66) src/io/filesystem/filesystem.cc (+3/-3) src/io/filesystem/filesystem_exceptions.h (+0/-12) src/io/filesystem/zip_filesystem.cc (+13/-7) |
To merge this branch: | bzr merge lp:~widelands-dev/widelands/filesystem-errors |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
GunChleoc | Approve | ||
Review via email: mp+358219@code.launchpad.net |
Commit message
Improved error checking in filesystem functions
- some filesystem error checking added
- more specific filesystem exceptions thrown
Description of the change
bunnybot (widelandsofficial) wrote : | # |
bunnybot (widelandsofficial) wrote : | # |
Continuous integration builds have changed state:
Travis build 4199. State: passed. Details: https:/
Appveyor build 3995. State: failed. Details: https:/
GunChleoc (gunchleoc) wrote : | # |
I have done a code review with my last commit - please have a look at the diff.
Not tested yet.
Arty (artydent) wrote : | # |
regarding code review:
There're plenty more long lines and if-blocks without curly braces in there. I'll fix this tonight.
Do we generally follow a strict rule of curly braces even for short single line blocks?
GunChleoc (gunchleoc) wrote : | # |
Our policy is to always use curly braces, as the lack of them can cause bugs. We still have tons of them missing though, so we only fix them if the code is being changed anyway. Too many merge conflicts otherwise.
Arty (artydent) wrote : | # |
Oh okay, then I'll leave it.
I am still somewhat fuzzy about some specifics with bazaar, specifically merge conflicts.
Let's say for examply I'd fix all those little things in disk_filesystem.cc, then merge the result into my two child branches (which itself should be fine because those don't make any changes to the file themselve). Then - if I got this right - the only conflicts would arise if someone else is doing other changes to a version of the branches from before the merge (which of course is easily possible during the review) or if someone is changing the file in some other branch. Right?
kaputtnik (franku) wrote : | # |
No, then you will have 'diverged' branches. I had those a lot in the past... Mostly i deleted the branch and pulled it again to get a clean copy.
Merge conflicts arise if the logic of the merge command wasn't able to merge branch A into branch B. This can happen if the changes made in branch A are too complicated for the merge logic.
Try in terminal:
bzr help conflicts
bzr help conflict-types
bzr help diverged-branches
Arty (artydent) wrote : | # |
Good to know, thanks. So I guess I shouldn't even make any child branches at all before the parent branch is fully revised and scheduled for merging into trunk. Or maybe just not push them online or at least not bother anyone else with them via merge requests; and then later resolve merge conflicts on my own (possibly just copying it over into a new branch) before making everything available. I feel that this kinda destroys what I thought to be a big advantage of this whole branching concept.
GunChleoc (gunchleoc) wrote : | # |
You get diverged branches if somebody else pushed to the online version of the branch. You can rescue your changes with:
bzr uncommit
bzr shelve
Then pull the changes:
bzr pull lp:~widelands-dev/widelands/filesystem-errors
Then retrieve the shelved changes:
bzr unshelve
If you getting merge conflicts during the unshelve or then merging trunk, you'll have to manually edit the files to get them in a good state again, then call
bzr resolve
If it doesn't autoresolve:
bzr resolve <filename>
Compile again to make sure that you haven't made any mistakes with the merge, then commit.
GunChleoc (gunchleoc) wrote : | # |
Tested.
@bunnybot merge
Preview Diff
1 | === modified file 'src/io/filesystem/disk_filesystem.cc' | |||
2 | --- src/io/filesystem/disk_filesystem.cc 2018-04-07 16:59:00 +0000 | |||
3 | +++ src/io/filesystem/disk_filesystem.cc 2018-11-12 08:55:49 +0000 | |||
4 | @@ -167,15 +167,13 @@ | |||
5 | 167 | } | 167 | } |
6 | 168 | 168 | ||
7 | 169 | /** | 169 | /** |
9 | 170 | * Create a sub filesystem out of this filesystem | 170 | * Make a sub filesystem out of this filesystem |
10 | 171 | */ | 171 | */ |
11 | 172 | FileSystem* RealFSImpl::make_sub_file_system(const std::string& path) { | 172 | FileSystem* RealFSImpl::make_sub_file_system(const std::string& path) { |
12 | 173 | FileSystemPath fspath(canonicalize_name(path)); | 173 | FileSystemPath fspath(canonicalize_name(path)); |
13 | 174 | 174 | ||
14 | 175 | if (!fspath.exists_) { | 175 | if (!fspath.exists_) { |
18 | 176 | throw wexception("RealFSImpl: unable to create sub filesystem, path does not exist for '%s'" | 176 | throw FileNotFoundError("RealFSImpl::make_sub_file_system", fspath); |
16 | 177 | " in directory '%s'", | ||
17 | 178 | fspath.c_str(), directory_.c_str()); | ||
19 | 179 | } | 177 | } |
20 | 180 | 178 | ||
21 | 181 | if (fspath.is_directory_) | 179 | if (fspath.is_directory_) |
22 | @@ -190,10 +188,7 @@ | |||
23 | 190 | FileSystem* RealFSImpl::create_sub_file_system(const std::string& path, Type const fs) { | 188 | FileSystem* RealFSImpl::create_sub_file_system(const std::string& path, Type const fs) { |
24 | 191 | FileSystemPath fspath(canonicalize_name(path)); | 189 | FileSystemPath fspath(canonicalize_name(path)); |
25 | 192 | if (fspath.exists_) | 190 | if (fspath.exists_) |
30 | 193 | throw wexception( | 191 | throw FileError("RealFSImpl::create_sub_file_system", fspath, "path already exists, cannot create new filesystem from it"); |
27 | 194 | "path '%s'' already exists in directory '%s', can not create a filesystem from it", | ||
28 | 195 | path.c_str(), directory_.c_str()); | ||
29 | 196 | |||
31 | 197 | if (fs == FileSystem::DIR) { | 192 | if (fs == FileSystem::DIR) { |
32 | 198 | ensure_directory_exists(path); | 193 | ensure_directory_exists(path); |
33 | 199 | return new RealFSImpl(fspath); | 194 | return new RealFSImpl(fspath); |
34 | @@ -221,20 +216,22 @@ | |||
35 | 221 | void RealFSImpl::unlink_file(const std::string& file) { | 216 | void RealFSImpl::unlink_file(const std::string& file) { |
36 | 222 | FileSystemPath fspath(canonicalize_name(file)); | 217 | FileSystemPath fspath(canonicalize_name(file)); |
37 | 223 | if (!fspath.exists_) { | 218 | if (!fspath.exists_) { |
41 | 224 | throw wexception( | 219 | throw FileNotFoundError("RealFSImpl::unlink_file", fspath); |
39 | 225 | "RealFSImpl: unable to unlink file, path does not exist for '%s' in directory '%s'", | ||
40 | 226 | fspath.c_str(), directory_.c_str()); | ||
42 | 227 | } | 220 | } |
43 | 228 | if (fspath.is_directory_) { | 221 | if (fspath.is_directory_) { |
47 | 229 | throw wexception( | 222 | throw FileTypeError("RealFSImpl::unlink_file", fspath, "path is a directory"); |
45 | 230 | "RealFSImpl: unable to unlink file, path '%s' in directory '%s' is a directory", | ||
46 | 231 | fspath.c_str(), directory_.c_str()); | ||
48 | 232 | } | 223 | } |
49 | 233 | |||
50 | 234 | #ifndef _WIN32 | 224 | #ifndef _WIN32 |
52 | 235 | unlink(fspath.c_str()); | 225 | if (unlink(fspath.c_str()) == -1) |
53 | 226 | throw FileError("RealFSImpl::unlink_file", fspath, strerror(errno)); | ||
54 | 236 | #else | 227 | #else |
56 | 237 | DeleteFile(fspath.c_str()); | 228 | // Note: We could possibly replace this with _unlink() |
57 | 229 | // which would then also work with errno instead of GetLastError(), | ||
58 | 230 | // but I am not sure if this is available (and works properly) | ||
59 | 231 | // on all windows platforms or only with Visual Studio. | ||
60 | 232 | if (!DeleteFile(fspath.c_str())) | ||
61 | 233 | throw FileError("RealFSImpl::unlink_file", fspath, std::string("file error (Windows error code ")+std::to_string(GetLastError())+")"); | ||
62 | 234 | // TODO(Arty): generate proper system message from GetLastError() via FormatMessage | ||
63 | 238 | #endif | 235 | #endif |
64 | 239 | } | 236 | } |
65 | 240 | 237 | ||
66 | @@ -244,14 +241,10 @@ | |||
67 | 244 | void RealFSImpl::unlink_directory(const std::string& file) { | 241 | void RealFSImpl::unlink_directory(const std::string& file) { |
68 | 245 | FileSystemPath fspath(canonicalize_name(file)); | 242 | FileSystemPath fspath(canonicalize_name(file)); |
69 | 246 | if (!fspath.exists_) { | 243 | if (!fspath.exists_) { |
73 | 247 | throw wexception("RealFSImpl: unable to unlink directory, path does not exist for '%s'" | 244 | throw FileNotFoundError("RealFSImpl::unlink_directory", fspath); |
71 | 248 | " in directory '%s'", | ||
72 | 249 | fspath.c_str(), directory_.c_str()); | ||
74 | 250 | } | 245 | } |
75 | 251 | if (!fspath.is_directory_) { | 246 | if (!fspath.is_directory_) { |
79 | 252 | throw wexception("RealFSImpl: unable to unlink directory, path '%s' in directory '%s'" | 247 | throw FileTypeError("RealFSImpl::unlink_directory", fspath, "path is not a directory"); |
77 | 253 | " is not a directory", | ||
78 | 254 | fspath.c_str(), directory_.c_str()); | ||
80 | 255 | } | 248 | } |
81 | 256 | 249 | ||
82 | 257 | FilenameSet files = list_directory(file); | 250 | FilenameSet files = list_directory(file); |
83 | @@ -268,14 +261,18 @@ | |||
84 | 268 | unlink_file(*pname); | 261 | unlink_file(*pname); |
85 | 269 | } | 262 | } |
86 | 270 | 263 | ||
89 | 271 | // NOTE: this might fail if this directory contains CVS dir, | 264 | // NOTE: this might fail if this directory contains CVS dir |
88 | 272 | // so no error checking here | ||
90 | 273 | #ifndef _WIN32 | 265 | #ifndef _WIN32 |
92 | 274 | rmdir(fspath.c_str()); | 266 | if (rmdir(fspath.c_str()) == -1) |
93 | 267 | throw FileError("RealFSImpl::unlink_directory", fspath, strerror(errno)); | ||
94 | 275 | #else | 268 | #else |
95 | 269 | // Note: We could possibly replace this with _rmdir() | ||
96 | 270 | // which would then also work with errno instead of GetLastError(), | ||
97 | 271 | // but I am not sure if this is available (and works properly) | ||
98 | 272 | // on all windows platforms or only with Visual Studio. | ||
99 | 276 | if (!RemoveDirectory(fspath.c_str())) | 273 | if (!RemoveDirectory(fspath.c_str())) |
102 | 277 | throw wexception( | 274 | throw FileError("RealFSImpl::unlink_directory", fspath, std::string("file error (Windows error code ")+std::to_string(GetLastError())+")"); |
103 | 278 | "'%s' could not be deleted in directory '%s'.", fspath.c_str(), directory_.c_str()); | 275 | // TODO(Arty): generate proper system message from GetLastError() via FormatMessage |
104 | 279 | #endif | 276 | #endif |
105 | 280 | } | 277 | } |
106 | 281 | 278 | ||
107 | @@ -292,25 +289,23 @@ | |||
108 | 292 | boost::replace_all(clean_dirname, "\\", "/"); | 289 | boost::replace_all(clean_dirname, "\\", "/"); |
109 | 293 | #endif | 290 | #endif |
110 | 294 | 291 | ||
130 | 295 | try { | 292 | std::string::size_type it = 0; |
131 | 296 | std::string::size_type it = 0; | 293 | while (it < clean_dirname.size()) { |
132 | 297 | while (it < clean_dirname.size()) { | 294 | it = clean_dirname.find('/', it); |
133 | 298 | it = clean_dirname.find('/', it); | 295 | |
134 | 299 | 296 | FileSystemPath fspath(canonicalize_name(clean_dirname.substr(0, it))); | |
135 | 300 | FileSystemPath fspath(canonicalize_name(clean_dirname.substr(0, it))); | 297 | if (fspath.exists_ && !fspath.is_directory_) { |
136 | 301 | if (fspath.exists_ && !fspath.is_directory_) | 298 | throw FileTypeError("RealFSImpl::ensure_directory_exists", |
137 | 302 | throw wexception("'%s' in directory '%s' exists and is not a directory", | 299 | fspath, "path is not a directory"); |
138 | 303 | clean_dirname.substr(0, it).c_str(), directory_.c_str()); | 300 | } |
139 | 304 | if (!fspath.exists_) | 301 | if (!fspath.exists_) { |
140 | 305 | make_directory(clean_dirname.substr(0, it)); | 302 | make_directory(clean_dirname.substr(0, it)); |
141 | 306 | 303 | } | |
142 | 307 | if (it == std::string::npos) | 304 | |
143 | 308 | break; | 305 | if (it == std::string::npos) { |
144 | 309 | ++it; | 306 | break; |
145 | 310 | } | 307 | } |
146 | 311 | } catch (const std::exception& e) { | 308 | ++it; |
128 | 312 | throw wexception("RealFSImpl::ensure_directory_exists(%s) in directory '%s': %s", | ||
129 | 313 | clean_dirname.c_str(), directory_.c_str(), e.what()); | ||
147 | 314 | } | 309 | } |
148 | 315 | } | 310 | } |
149 | 316 | 311 | ||
150 | @@ -318,33 +313,37 @@ | |||
151 | 318 | * Create this directory, throw an error if it already exists or | 313 | * Create this directory, throw an error if it already exists or |
152 | 319 | * if a file is in the way or if the creation fails. | 314 | * if a file is in the way or if the creation fails. |
153 | 320 | * | 315 | * |
155 | 321 | * Pleas note, this function does not honor parents, | 316 | * Please note, this function does not honor parents, |
156 | 322 | * make_directory("onedir/otherdir/onemoredir") will fail | 317 | * make_directory("onedir/otherdir/onemoredir") will fail |
157 | 323 | * if either onedir or otherdir is missing | 318 | * if either onedir or otherdir is missing |
158 | 324 | */ | 319 | */ |
159 | 325 | void RealFSImpl::make_directory(const std::string& dirname) { | 320 | void RealFSImpl::make_directory(const std::string& dirname) { |
160 | 326 | FileSystemPath fspath(canonicalize_name(dirname)); | 321 | FileSystemPath fspath(canonicalize_name(dirname)); |
161 | 327 | if (fspath.exists_) | 322 | if (fspath.exists_) |
164 | 328 | throw wexception("a file/directory with the name '%s' already exists in directory '%s'", | 323 | throw FileError("RealFSImpl::make_directory", fspath, "a file or directory with that name already exists"); |
163 | 329 | dirname.c_str(), directory_.c_str()); | ||
165 | 330 | 324 | ||
169 | 331 | if | 325 | #ifndef _WIN32 |
170 | 332 | #ifdef _WIN32 | 326 | if (mkdir(fspath.c_str(), 0x1FF) == -1) |
171 | 333 | (!CreateDirectory(fspath.c_str(), NULL)) | 327 | throw FileError("RealFSImpl::make_directory", fspath, strerror(errno)); |
172 | 334 | #else | 328 | #else |
174 | 335 | (mkdir(fspath.c_str(), 0x1FF) == -1) | 329 | // Note: We could possibly replace this with _mkdir() |
175 | 330 | // which would then also work with errno instead of GetLastError(), | ||
176 | 331 | // but I am not sure if this is available (and works properly) | ||
177 | 332 | // on all windows platforms or only with Visual Studio. | ||
178 | 333 | if (!CreateDirectory(fspath.c_str(), NULL)) | ||
179 | 334 | throw FileError("RealFSImpl::make_directory", fspath, std::string("file error (Windows error code ")+std::to_string(GetLastError())+")"); | ||
180 | 335 | // TODO(Arty): generate proper system message from GetLastError() via FormatMessage | ||
181 | 336 | #endif | 336 | #endif |
182 | 337 | throw DirectoryCannotCreateError("RealFSImpl::make_directory", dirname, strerror(errno)); | ||
183 | 338 | } | 337 | } |
184 | 339 | 338 | ||
185 | 340 | /** | 339 | /** |
187 | 341 | * Read the given file into alloced memory; called by FileRead::open. | 340 | * Read the given file into allocated memory; called by FileRead::open. |
188 | 342 | * Throws an exception if the file couldn't be opened. | 341 | * Throws an exception if the file couldn't be opened. |
189 | 343 | */ | 342 | */ |
190 | 344 | void* RealFSImpl::load(const std::string& fname, size_t& length) { | 343 | void* RealFSImpl::load(const std::string& fname, size_t& length) { |
191 | 345 | const std::string fullname = canonicalize_name(fname); | 344 | const std::string fullname = canonicalize_name(fname); |
192 | 346 | if (is_directory(fullname)) { | 345 | if (is_directory(fullname)) { |
194 | 347 | throw FileError("RealFSImpl::load", fullname); | 346 | throw FileTypeError("RealFSImpl::load", fullname, "path is a directory"); |
195 | 348 | } | 347 | } |
196 | 349 | 348 | ||
197 | 350 | FILE* file = nullptr; | 349 | FILE* file = nullptr; |
198 | @@ -353,7 +352,7 @@ | |||
199 | 353 | try { | 352 | try { |
200 | 354 | file = fopen(fullname.c_str(), "rb"); | 353 | file = fopen(fullname.c_str(), "rb"); |
201 | 355 | if (!file) | 354 | if (!file) |
203 | 356 | throw FileError("RealFSImpl::load", fullname); | 355 | throw FileError("RealFSImpl::load", fullname, "could not open file for reading"); |
204 | 357 | 356 | ||
205 | 358 | // determine the size of the file (rather quirky, but it doesn't require | 357 | // determine the size of the file (rather quirky, but it doesn't require |
206 | 359 | // potentially unportable functions) | 358 | // potentially unportable functions) |
207 | @@ -371,6 +370,9 @@ | |||
208 | 371 | 370 | ||
209 | 372 | // allocate a buffer and read the entire file into it | 371 | // allocate a buffer and read the entire file into it |
210 | 373 | data = malloc(size + 1); // TODO(unknown): memory leak! | 372 | data = malloc(size + 1); // TODO(unknown): memory leak! |
211 | 373 | if (!data) | ||
212 | 374 | throw wexception("RealFSImpl::load: memory allocation failed for reading file %s (%s) with size %" PRIuS "", | ||
213 | 375 | fname.c_str(), fullname.c_str(), size); | ||
214 | 374 | int result = fread(data, size, 1, file); | 376 | int result = fread(data, size, 1, file); |
215 | 375 | if (size && (result != 1)) { | 377 | if (size && (result != 1)) { |
216 | 376 | throw wexception("RealFSImpl::load: read failed for %s (%s) with size %" PRIuS "", | 378 | throw wexception("RealFSImpl::load: read failed for %s (%s) with size %" PRIuS "", |
217 | @@ -383,10 +385,12 @@ | |||
218 | 383 | 385 | ||
219 | 384 | length = size; | 386 | length = size; |
220 | 385 | } catch (...) { | 387 | } catch (...) { |
222 | 386 | if (file) { | 388 | if (file) { |
223 | 387 | fclose(file); | 389 | fclose(file); |
226 | 388 | } | 390 | } |
227 | 389 | free(data); | 391 | if (data) { |
228 | 392 | free(data); | ||
229 | 393 | } | ||
230 | 390 | throw; | 394 | throw; |
231 | 391 | } | 395 | } |
232 | 392 | 396 | ||
233 | @@ -410,7 +414,7 @@ | |||
234 | 410 | 414 | ||
235 | 411 | FILE* const f = fopen(fullname.c_str(), append ? "a" : "wb"); | 415 | FILE* const f = fopen(fullname.c_str(), append ? "a" : "wb"); |
236 | 412 | if (!f) | 416 | if (!f) |
238 | 413 | throw wexception("could not open %s (%s) for writing", fname.c_str(), fullname.c_str()); | 417 | throw FileError("RealFSImpl::write", fullname, "could not open file for writing"); |
239 | 414 | 418 | ||
240 | 415 | size_t const c = fwrite(data, length, 1, f); | 419 | size_t const c = fwrite(data, length, 1, f); |
241 | 416 | fclose(f); | 420 | fclose(f); |
242 | @@ -424,8 +428,7 @@ | |||
243 | 424 | const std::string fullname1 = canonicalize_name(old_name); | 428 | const std::string fullname1 = canonicalize_name(old_name); |
244 | 425 | const std::string fullname2 = canonicalize_name(new_name); | 429 | const std::string fullname2 = canonicalize_name(new_name); |
245 | 426 | if (rename(fullname1.c_str(), fullname2.c_str()) != 0) | 430 | if (rename(fullname1.c_str(), fullname2.c_str()) != 0) |
248 | 427 | throw wexception("DiskFileSystem: unable to rename %s to %s: %s", fullname1.c_str(), | 431 | throw FileError("RealFSImpl::fs_rename", fullname1, std::string("unable to rename file to ") + fullname2 + ", " + strerror(errno)); |
247 | 428 | fullname2.c_str(), strerror(errno)); | ||
249 | 429 | } | 432 | } |
250 | 430 | 433 | ||
251 | 431 | /***************************************************************************** | 434 | /***************************************************************************** |
252 | @@ -439,7 +442,7 @@ | |||
253 | 439 | struct RealFSStreamRead : public StreamRead { | 442 | struct RealFSStreamRead : public StreamRead { |
254 | 440 | explicit RealFSStreamRead(const std::string& fname) : file_(fopen(fname.c_str(), "rb")) { | 443 | explicit RealFSStreamRead(const std::string& fname) : file_(fopen(fname.c_str(), "rb")) { |
255 | 441 | if (!file_) | 444 | if (!file_) |
257 | 442 | throw wexception("could not open %s for reading", fname.c_str()); | 445 | throw FileError("RealFSStreamRead::RealFSStreamRead", fname, "could not open file for reading"); |
258 | 443 | } | 446 | } |
259 | 444 | 447 | ||
260 | 445 | ~RealFSStreamRead() override { | 448 | ~RealFSStreamRead() override { |
261 | @@ -477,7 +480,7 @@ | |||
262 | 477 | explicit RealFSStreamWrite(const std::string& fname) : filename_(fname) { | 480 | explicit RealFSStreamWrite(const std::string& fname) : filename_(fname) { |
263 | 478 | file_ = fopen(fname.c_str(), "wb"); | 481 | file_ = fopen(fname.c_str(), "wb"); |
264 | 479 | if (!file_) | 482 | if (!file_) |
266 | 480 | throw wexception("could not open %s for writing", fname.c_str()); | 483 | throw FileError("RealFSStreamWrite::RealFSStreamWrite", fname, "could not open file for writing"); |
267 | 481 | } | 484 | } |
268 | 482 | 485 | ||
269 | 483 | ~RealFSStreamWrite() override { | 486 | ~RealFSStreamWrite() override { |
270 | 484 | 487 | ||
271 | === modified file 'src/io/filesystem/filesystem.cc' | |||
272 | --- src/io/filesystem/filesystem.cc 2018-07-12 04:41:20 +0000 | |||
273 | +++ src/io/filesystem/filesystem.cc 2018-11-12 08:55:49 +0000 | |||
274 | @@ -306,7 +306,7 @@ | |||
275 | 306 | std::list<std::string>::iterator i; | 306 | std::list<std::string>::iterator i; |
276 | 307 | 307 | ||
277 | 308 | #ifdef _WIN32 | 308 | #ifdef _WIN32 |
279 | 309 | // remove all slashes with backslashes so following can work. | 309 | // replace all slashes with backslashes so following can work. |
280 | 310 | for (uint32_t j = 0; j < path.size(); ++j) { | 310 | for (uint32_t j = 0; j < path.size(); ++j) { |
281 | 311 | if (path[j] == '/') | 311 | if (path[j] == '/') |
282 | 312 | path[j] = '\\'; | 312 | path[j] = '\\'; |
283 | @@ -463,8 +463,8 @@ | |||
284 | 463 | fs.ensure_directory_exists(".widelands"); | 463 | fs.ensure_directory_exists(".widelands"); |
285 | 464 | fs.fs_unlink(".widelands"); | 464 | fs.fs_unlink(".widelands"); |
286 | 465 | return true; | 465 | return true; |
289 | 466 | } catch (...) { | 466 | } catch (const FileError& e) { |
290 | 467 | log("Directory %s is not writeable - next try\n", path); | 467 | log("Directory %s is not writeable - next try: %s\n", path, e.what()); |
291 | 468 | } | 468 | } |
292 | 469 | 469 | ||
293 | 470 | return false; | 470 | return false; |
294 | 471 | 471 | ||
295 | === modified file 'src/io/filesystem/filesystem_exceptions.h' | |||
296 | --- src/io/filesystem/filesystem_exceptions.h 2018-04-07 16:59:00 +0000 | |||
297 | +++ src/io/filesystem/filesystem_exceptions.h 2018-11-12 08:55:49 +0000 | |||
298 | @@ -76,16 +76,4 @@ | |||
299 | 76 | } | 76 | } |
300 | 77 | }; | 77 | }; |
301 | 78 | 78 | ||
302 | 79 | /** | ||
303 | 80 | * The directory cannot be created | ||
304 | 81 | */ | ||
305 | 82 | class DirectoryCannotCreateError : public FileError { | ||
306 | 83 | public: | ||
307 | 84 | explicit DirectoryCannotCreateError(const std::string& thrower, | ||
308 | 85 | const std::string& dirname, | ||
309 | 86 | const std::string& message = "cannot create directory") | ||
310 | 87 | |||
311 | 88 | : FileError(thrower, dirname, message) { | ||
312 | 89 | } | ||
313 | 90 | }; | ||
314 | 91 | #endif // end of include guard: WL_IO_FILESYSTEM_FILESYSTEM_EXCEPTIONS_H | 79 | #endif // end of include guard: WL_IO_FILESYSTEM_FILESYSTEM_EXCEPTIONS_H |
315 | 92 | 80 | ||
316 | === modified file 'src/io/filesystem/zip_filesystem.cc' | |||
317 | --- src/io/filesystem/zip_filesystem.cc 2018-10-21 22:21:34 +0000 | |||
318 | +++ src/io/filesystem/zip_filesystem.cc 2018-11-12 08:55:49 +0000 | |||
319 | @@ -268,12 +268,14 @@ | |||
320 | 268 | if (!file_exists(path)) { | 268 | if (!file_exists(path)) { |
321 | 269 | throw wexception( | 269 | throw wexception( |
322 | 270 | "ZipFilesystem::make_sub_file_system: The path '%s' does not exist in zip file '%s'.", | 270 | "ZipFilesystem::make_sub_file_system: The path '%s' does not exist in zip file '%s'.", |
324 | 271 | path.c_str(), zip_file_->path().c_str()); | 271 | (basedir_in_zip_file_.empty() ? path : basedir_in_zip_file_ + "/" + path).c_str(), |
325 | 272 | zip_file_->path().c_str()); | ||
326 | 272 | } | 273 | } |
327 | 273 | if (!is_directory(path)) { | 274 | if (!is_directory(path)) { |
331 | 274 | throw wexception("ZipFilesystem::make_sub_file_system: " | 275 | throw wexception( |
332 | 275 | "The path '%s' needs to be a directory in zip file '%s'.", | 276 | "ZipFilesystem::make_sub_file_system: The path '%s' needs to be a directory in zip file '%s'.", |
333 | 276 | path.c_str(), zip_file_->path().c_str()); | 277 | (basedir_in_zip_file_.empty() ? path : basedir_in_zip_file_ + "/" + path).c_str(), |
334 | 278 | zip_file_->path().c_str()); | ||
335 | 277 | } | 279 | } |
336 | 278 | 280 | ||
337 | 279 | std::string localpath = path; | 281 | std::string localpath = path; |
338 | @@ -291,7 +293,10 @@ | |||
339 | 291 | // see Filesystem::create | 293 | // see Filesystem::create |
340 | 292 | FileSystem* ZipFilesystem::create_sub_file_system(const std::string& path, Type const type) { | 294 | FileSystem* ZipFilesystem::create_sub_file_system(const std::string& path, Type const type) { |
341 | 293 | if (file_exists(path)) { | 295 | if (file_exists(path)) { |
343 | 294 | throw wexception("ZipFilesystem::create_sub_file_system: Sub file system already exists."); | 296 | throw wexception( |
344 | 297 | "ZipFilesystem::create_sub_file_system: Path '%s' already exists in zip file %s.", | ||
345 | 298 | (basedir_in_zip_file_.empty() ? path : basedir_in_zip_file_ + "/" + path).c_str(), | ||
346 | 299 | zip_file_->path().c_str()); | ||
347 | 295 | } | 300 | } |
348 | 296 | 301 | ||
349 | 297 | if (type != FileSystem::DIR) | 302 | if (type != FileSystem::DIR) |
350 | @@ -438,8 +443,9 @@ | |||
351 | 438 | "ZipFilesystem::write", complete_filename, | 443 | "ZipFilesystem::write", complete_filename, |
352 | 439 | (boost::format("in path '%s'', Error") % zip_file_->path() % strerror(errno)).str()); | 444 | (boost::format("in path '%s'', Error") % zip_file_->path() % strerror(errno)).str()); |
353 | 440 | default: | 445 | default: |
356 | 441 | throw FileError("ZipFilesystem::write", complete_filename, | 446 | throw FileError( |
357 | 442 | (boost::format("in path '%s'") % zip_file_->path()).str()); | 447 | "ZipFilesystem::write", complete_filename, |
358 | 448 | (boost::format("in path '%s'") % zip_file_->path()).str()); | ||
359 | 443 | } | 449 | } |
360 | 444 | 450 | ||
361 | 445 | zipCloseFileInZip(zip_file_->write_handle()); | 451 | zipCloseFileInZip(zip_file_->write_handle()); |
Continuous integration builds have changed state:
Travis build 4186. State: failed. Details: https:/ /travis- ci.org/ widelands/ widelands/ builds/ 449820523. /ci.appveyor. com/project/ widelands- dev/widelands/ build/_ widelands_ dev_widelands_ filesystem_ errors- 3983.
Appveyor build 3983. State: success. Details: https:/