Jürgen Spitzmüller wrote: > There's one remaining critical bug > (#4534), but I have already uploaded a patch to bugzilla, which just needs > to be tested by one of the Windows people who can reproduce the problem.
Unfortunately, Uwe isn't able to reproduce the problem. So here is my proposed, untested fix: substitute some filesystem::exists calls that might throw exceptions by a new helper function doesFileExist that calls fs::exists itself, but catches exceptions. AFAICS, the fix cannot harm. Note, however, that there are still plain fs::exists calls in the source. So my questions are: (a) any objections to this patch? and (b) should I substitute the remaining fs::exists calls as well? Jürgen
Index: src/buffer_funcs.cpp =================================================================== --- src/buffer_funcs.cpp (Revision 22770) +++ src/buffer_funcs.cpp (Arbeitskopie) @@ -50,6 +50,7 @@ #include <boost/filesystem/operations.hpp> #include "support/textutils.h" +#include "support/filetools.h" using std::min; using std::string; @@ -60,6 +61,7 @@ using support::bformat; using support::FileName; +using support::doesFileExist; using support::libFileSearch; using support::makeAbsPath; using support::makeDisplayPath; @@ -77,7 +79,7 @@ BOOST_ASSERT(b); // File information about normal file - if (!fs::exists(s.toFilesystemEncoding())) { + if (!doesFileExist(s)) { docstring const file = makeDisplayPath(s.absFilename(), 50); docstring text = bformat(_("The specified document\n%1$s" "\ncould not be read."), file); @@ -88,8 +90,7 @@ // Check if emergency save file exists and is newer. FileName const e(s.absFilename() + ".emergency"); - if (fs::exists(e.toFilesystemEncoding()) && - fs::exists(s.toFilesystemEncoding()) && + if (doesFileExist(e) && doesFileExist(s) && fs::last_write_time(e.toFilesystemEncoding()) > fs::last_write_time(s.toFilesystemEncoding())) { docstring const file = makeDisplayPath(s.absFilename(), 20); @@ -115,8 +116,7 @@ // Now check if autosave file is newer. FileName const a(onlyPath(s.absFilename()) + '#' + onlyFilename(s.absFilename()) + '#'); - if (fs::exists(a.toFilesystemEncoding()) && - fs::exists(s.toFilesystemEncoding()) && + if (doesFileExist(a) && doesFileExist(s) && fs::last_write_time(a.toFilesystemEncoding()) > fs::last_write_time(s.toFilesystemEncoding())) { docstring const file = makeDisplayPath(s.absFilename(), 20); Index: src/support/filetools.cpp =================================================================== --- src/support/filetools.cpp (Revision 22770) +++ src/support/filetools.cpp (Arbeitskopie) @@ -175,7 +175,22 @@ lyxerr << fe.what() << endl; return false; } +} + +bool doesFileExist(FileName const & filename) +{ + std::string const path = filename.toFilesystemEncoding(); + try { + // fs::exists can throw an exception + // f.ex. if the drive was unmounted. + return fs::exists(path); + } catch (fs::filesystem_error const & fe){ + lyxerr << "doesFileExist() error with path: " + << path << endl; + lyxerr << fe.what() << endl; + return false; + } } @@ -240,7 +255,7 @@ vector<FileName> dirlist; string const encoded_dir = dir.toFilesystemEncoding(); - if (!(fs::exists(encoded_dir) && fs::is_directory(encoded_dir))) { + if (!(doesFileExist(dir) && fs::is_directory(encoded_dir))) { LYXERR(Debug::FILES) << "Directory \"" << dir << "\" does not exist to DirList." << endl; @@ -643,7 +658,7 @@ string const getFileContents(FileName const & fname) { string const encodedname = fname.toFilesystemEncoding(); - if (fs::exists(encodedname)) { + if (doesFileExist(fname)) { ifstream ifs(encodedname.c_str()); ostringstream ofs; if (ifs && ofs) { @@ -1135,7 +1150,7 @@ // If the file can be found directly, we just return a // absolute path version of it. FileName const absfile(makeAbsPath(fil)); - if (fs::exists(absfile.toFilesystemEncoding())) + if (doesFileExist(absfile)) return absfile; // No we try to find it using kpsewhich. @@ -1180,7 +1195,7 @@ a += onlyFilename(filename); a += '#'; FileName const autosave(a); - if (fs::exists(autosave.toFilesystemEncoding())) + if (doesFileExist(autosave)) unlink(autosave); } @@ -1249,15 +1264,15 @@ string const file1 = filename1.toFilesystemEncoding(); string const file2 = filename2.toFilesystemEncoding(); int cmp = 0; - if (fs::exists(file1) && fs::exists(file2)) { + if (doesFileExist(filename1) && doesFileExist(filename2)) { double const tmp = difftime(fs::last_write_time(file1), fs::last_write_time(file2)); if (tmp != 0) cmp = tmp > 0 ? 1 : -1; - } else if (fs::exists(file1)) { + } else if (doesFileExist(filename1)) { cmp = 1; - } else if (fs::exists(file2)) { + } else if (doesFileExist(filename2)) { cmp = -1; } Index: src/support/FileMonitor.cpp =================================================================== --- src/support/FileMonitor.cpp (Revision 22770) +++ src/support/FileMonitor.cpp (Arbeitskopie) @@ -11,6 +11,7 @@ #include <config.h> #include "support/FileMonitor.h" +#include "support/filetools.h" #include "support/FileName.h" #include "support/lyxlib.h" @@ -92,7 +93,7 @@ if (monitoring()) return; - if (!fs::exists(pimpl_->filename_.toFilesystemEncoding())) + if (!doesFileExist(pimpl_->filename_)) return; pimpl_->timestamp_ = fs::last_write_time(pimpl_->filename_.toFilesystemEncoding()); @@ -157,7 +158,7 @@ { bool changed = false; - if (!fs::exists(filename_.toFilesystemEncoding())) { + if (!doesFileExist(filename_)) { changed = timestamp_ || checksum_; timestamp_ = 0; checksum_ = 0; Index: src/support/filetools.h =================================================================== --- src/support/filetools.h (Revision 22770) +++ src/support/filetools.h (Arbeitskopie) @@ -88,6 +88,11 @@ */ bool isFileReadable(FileName const & path); +/** Does the file exist ? + Returns true if the file `path' exists. + */ +bool doesFileExist(FileName const & path); + /// bool isLyXFilename(std::string const & filename); Index: src/Buffer.cpp =================================================================== --- src/Buffer.cpp (Revision 22770) +++ src/Buffer.cpp (Arbeitskopie) @@ -114,6 +114,7 @@ using support::cmd_ret; using support::createBufferTmpDir; using support::destroyDir; +using support::doesFileExist; using support::FileName; using support::getFormatFromContents; using support::libFileSearch; @@ -372,8 +373,8 @@ // If no Latex log or Build log is newer, show Build log - if (fs::exists(bname.toFilesystemEncoding()) && - (!fs::exists(fname.toFilesystemEncoding()) || + if (doesFileExist(bname) && + (!doesFileExist(fname) || fs::last_write_time(fname.toFilesystemEncoding()) < fs::last_write_time(bname.toFilesystemEncoding()))) { LYXERR(Debug::FILES) << "Log name calculated as: " << bname << endl; return make_pair(Buffer::buildlog, bname.absFilename()); @@ -792,7 +793,7 @@ bool madeBackup = false; // make a backup if the file already exists - if (lyxrc.make_backup && fs::exists(encodedFilename)) { + if (lyxrc.make_backup && doesFileExist(pimpl_->filename)) { backupName = FileName(fileName() + '~'); if (!lyxrc.backupdir_path.empty()) { string const mangledName = @@ -814,7 +815,7 @@ } // ask if the disk file has been externally modified (use checksum method) - if (fs::exists(encodedFilename) && isExternallyModified(checksum_method)) { + if (doesFileExist(pimpl_->filename) && isExternallyModified(checksum_method)) { docstring const file = makeDisplayPath(fileName(), 20); docstring text = bformat(_("Document %1$s has been externally modified. Are you sure " "you want to overwrite this file?"), file); @@ -1579,7 +1580,7 @@ bool Buffer::isExternallyModified(CheckMethod method) const { - BOOST_ASSERT(fs::exists(pimpl_->filename.toFilesystemEncoding())); + BOOST_ASSERT(doesFileExist(pimpl_->filename)); // if method == timestamp, check timestamp before checksum return (method == checksum_method || pimpl_->timestamp_ != fs::last_write_time(pimpl_->filename.toFilesystemEncoding())) @@ -1589,7 +1590,7 @@ void Buffer::saveCheckSum(FileName const & file) const { - if (fs::exists(file.toFilesystemEncoding())) { + if (doesFileExist(file)) { pimpl_->timestamp_ = fs::last_write_time(file.toFilesystemEncoding()); pimpl_->checksum_ = sum(file);