If we successfully save a file but fail to move it to its proper location,

then, if we made a backup and the original file was not a symlink, we moved
that file, so it will look to the user as if it was deleted. This is bug
This commit is contained in:
Richard Heck 2014-08-08 12:02:20 -04:00
parent 8b57600a1c
commit 8ec3e3283a

View File

@ -1301,17 +1301,20 @@ bool Buffer::save() const
// proper location once that has been done successfully. that // proper location once that has been done successfully. that
// way we preserve the original file if something goes wrong. // way we preserve the original file if something goes wrong.
TempFile tempfile(fileName().onlyPath(), "tmpXXXXXX.lyx"); TempFile tempfile(fileName().onlyPath(), "tmpXXXXXX.lyx");
FileName savefile(tempfile.name()); bool const symlink = fileName().isSymLink();
if (!symlink)
tempfile.setAutoRemove(false);
FileName savefile(tempfile.name());
LYXERR(Debug::FILES, "Saving to " << savefile.absFileName()); LYXERR(Debug::FILES, "Saving to " << savefile.absFileName());
if (!writeFile(savefile)) if (!writeFile(savefile))
return false; return false;
// we will set this to false if we fail // we will set this to false if we fail
bool made_backup = true; bool made_backup = true;
bool const symlink = fileName().isSymLink();
if (lyxrc.make_backup) {
FileName backupName(absFileName() + '~'); FileName backupName(absFileName() + '~');
if (lyxrc.make_backup) {
if (!lyxrc.backupdir_path.empty()) { if (!lyxrc.backupdir_path.empty()) {
string const mangledName = string const mangledName =
subst(subst(backupName.absFileName(), '/', '!'), ':', '!'); subst(subst(backupName.absFileName(), '/', '!'), ':', '!');
@ -1338,22 +1341,39 @@ bool Buffer::save() const
// If we have no symlink, we can simply rename the temp file. // If we have no symlink, we can simply rename the temp file.
// Otherwise, we need to copy it so the symlink stays intact. // Otherwise, we need to copy it so the symlink stays intact.
if (!symlink) if (made_backup && symlink ? savefile.copyTo(fileName(), true) :
tempfile.setAutoRemove(false); savefile.moveTo(fileName()))
if (made_backup && {
(symlink ? savefile.copyTo(fileName(), true) : savefile.moveTo(fileName()))) {
// saveCheckSum() was already called by writeFile(), but the // saveCheckSum() was already called by writeFile(), but the
// time stamp is invalidated by copying/moving // time stamp is invalidated by copying/moving
saveCheckSum(); saveCheckSum();
markClean(); markClean();
return true; return true;
} }
// else // else we saved the file, but failed to move it to the right location.
if (lyxrc.make_backup && made_backup && !symlink) {
// the original file was moved to filename.lyx~, so it will look
// to the user as if it was deleted. (see bug #9234.) we could try
// to restore it, but that would basically mean trying to do again
// what we just failed to do. better to leave things as they are.
Alert::error(_("Write failure"),
bformat(_("The file has successfully been saved as:\n %1$s.\n"
"But LyX could not move it to:\n %2$s.\n"
"Your original file has been backed up to:\n %3$s"),
from_utf8(savefile.absFileName()),
from_utf8(fileName().absFileName()),
from_utf8(backupName.absFileName())));
} else {
// either we did not try to make a backup, or else we tried and failed,
// or else the original file was a symlink, in which case it was copied,
// not moved. so the original file is intact.
Alert::error(_("Write failure"), Alert::error(_("Write failure"),
bformat(_("Cannot move saved file to:\n %1$s.\n" bformat(_("Cannot move saved file to:\n %1$s.\n"
"But the file has successfully been saved as:\n %2$s."), "But the file has successfully been saved as:\n %2$s."),
from_utf8(fileName().absFileName()), from_utf8(fileName().absFileName()),
from_utf8(savefile.absFileName()))); from_utf8(savefile.absFileName())));
}
return false; return false;
} }