Move temp save files to temporary directory

Avoid excess writes to the project directory to dodge issues with remote
file systems not fully writing data.

wxRename works across disk boundaries (in theory) and falls back to
wxCopy/wxRemove when it fails

Fixes https://gitlab.com/kicad/code/kicad/issues/10747
This commit is contained in:
Seth Hillbrand 2022-03-07 20:08:54 -08:00
parent 768dd0c6c9
commit 6934bc124c
3 changed files with 27 additions and 27 deletions

View File

@ -62,6 +62,7 @@
#include <wx/ffile.h>
#include <wx/filedlg.h>
#include <wx/log.h>
#include <wx/stdpaths.h>
#include <tools/ee_inspection_tool.h>
#include <paths.h>
#include <wx_filename.h> // For ::ResolvePossibleSymlinks
@ -693,9 +694,9 @@ bool SCH_EDIT_FRAME::saveSchematicFile( SCH_SHEET* aSheet, const wxString& aSave
if( !IsWritable( schematicFileName ) )
return false;
wxFileName tempFile( schematicFileName );
tempFile.SetName( wxT( "." ) + tempFile.GetName() );
tempFile.SetExt( tempFile.GetExt() + wxT( "$" ) );
wxStandardPaths& paths = wxStandardPaths::Get();
wxString tempFile = wxFileName::CreateTempFileName(
paths.GetTempDir() + wxFileName::GetPathSeparator() + wxT( "eeschema" ) );
// Save
wxLogTrace( traceAutoSave, "Saving file " + schematicFileName.GetFullPath() );
@ -706,7 +707,7 @@ bool SCH_EDIT_FRAME::saveSchematicFile( SCH_SHEET* aSheet, const wxString& aSave
try
{
pi->Save( tempFile.GetFullPath(), aSheet, &Schematic() );
pi->Save( tempFile, aSheet, &Schematic() );
success = true;
}
catch( const IO_ERROR& ioe )
@ -717,11 +718,11 @@ bool SCH_EDIT_FRAME::saveSchematicFile( SCH_SHEET* aSheet, const wxString& aSave
DisplayError( this, msg );
msg.Printf( _( "Failed to create temporary file '%s'." ),
tempFile.GetFullPath() );
tempFile );
SetMsgPanel( wxEmptyString, msg );
// In case we started a file but didn't fully write it, clean up
wxRemoveFile( tempFile.GetFullPath() );
wxRemoveFile( tempFile );
success = false;
}
@ -729,18 +730,18 @@ bool SCH_EDIT_FRAME::saveSchematicFile( SCH_SHEET* aSheet, const wxString& aSave
if( success )
{
// Replace the original with the temporary file we just wrote
success = wxRenameFile( tempFile.GetFullPath(), schematicFileName.GetFullPath() );
success = wxRenameFile( tempFile, schematicFileName.GetFullPath() );
if( !success )
{
msg.Printf( _( "Error saving schematic file '%s'.\n"
"Failed to rename temporary file '%s'." ),
schematicFileName.GetFullPath(),
tempFile.GetFullPath() );
tempFile );
DisplayError( this, msg );
msg.Printf( _( "Failed to rename temporary file '%s'." ),
tempFile.GetFullPath() );
tempFile );
SetMsgPanel( wxEmptyString, msg );
}
}

View File

@ -37,6 +37,8 @@
#include "properties_frame.h"
#include <wx/filedlg.h>
#include <wx/filename.h>
#include <wx/stdpaths.h>
bool PL_EDITOR_FRAME::saveCurrentPageLayout()
{
@ -288,23 +290,23 @@ bool PL_EDITOR_FRAME::SaveDrawingSheetFile( const wxString& aFullFileName )
{
if( !aFullFileName.IsEmpty() )
{
wxFileName tempFile( aFullFileName );
tempFile.SetName( wxT( "." ) + tempFile.GetName() );
tempFile.SetExt( tempFile.GetExt() + wxT( "$" ) );
wxStandardPaths& paths = wxStandardPaths::Get();
wxString tempFile = wxFileName::CreateTempFileName(
paths.GetTempDir() + wxFileName::GetPathSeparator() + wxT( "pledit" ) );
try
{
DS_DATA_MODEL::GetTheInstance().Save( tempFile.GetFullPath() );
DS_DATA_MODEL::GetTheInstance().Save( tempFile );
}
catch( const IO_ERROR& )
{
// In case we started a file but didn't fully write it, clean up
wxRemoveFile( tempFile.GetFullPath() );
wxRemoveFile( tempFile);
return false;
}
if( !wxRenameFile( tempFile.GetFullPath(), aFullFileName ) )
if( !wxRenameFile( tempFile, aFullFileName ) )
return false;
GetScreen()->SetContentModified( false );

View File

@ -1046,20 +1046,17 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool addToHistory,
GetBoard()->SynchronizeNetsAndNetClasses();
}
wxFileName tempFile( aFileName );
wxStandardPaths& paths = wxStandardPaths::Get();
wxString tempFile = wxFileName::CreateTempFileName(
paths.GetTempDir() + wxFileName::GetPathSeparator() + wxT( "pcbnew" ) );
wxString upperTxt;
wxString lowerTxt;
tempFile.SetName( wxT( "." ) + tempFile.GetName() );
tempFile.SetExt( tempFile.GetExt() + wxT( "$" ) );
try
{
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::KICAD_SEXP ) );
wxASSERT( tempFile.IsAbsolute() );
pi->Save( tempFile.GetFullPath(), GetBoard(), nullptr );
pi->Save( tempFile, GetBoard(), nullptr );
}
catch( const IO_ERROR& ioe )
{
@ -1067,26 +1064,26 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool addToHistory,
pcbFileName.GetFullPath(),
ioe.What() ) );
lowerTxt.Printf( _( "Failed to create temporary file '%s'." ), tempFile.GetFullPath() );
lowerTxt.Printf( _( "Failed to create temporary file '%s'." ), tempFile );
SetMsgPanel( upperTxt, lowerTxt );
// In case we started a file but didn't fully write it, clean up
wxRemoveFile( tempFile.GetFullPath() );
wxRemoveFile( tempFile );
return false;
}
// If save succeeded, replace the original with what we just wrote
if( !wxRenameFile( tempFile.GetFullPath(), pcbFileName.GetFullPath() ) )
if( !wxRenameFile( tempFile, pcbFileName.GetFullPath() ) )
{
DisplayError( this, wxString::Format( _( "Error saving board file '%s'.\n"
"Failed to rename temporary file '%s." ),
pcbFileName.GetFullPath(),
tempFile.GetFullPath() ) );
tempFile ) );
lowerTxt.Printf( _( "Failed to rename temporary file '%s'." ),
tempFile.GetFullPath() );
tempFile );
SetMsgPanel( upperTxt, lowerTxt );