summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/app.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/src/app.c b/src/app.c
index 28e320fe..828f5097 100644
--- a/src/app.c
+++ b/src/app.c
@@ -105,6 +105,7 @@ static const char *defaultDataDir_App_ = "~/config/settings/lagrange";
105static const char *prefsFileName_App_ = "prefs.cfg"; 105static const char *prefsFileName_App_ = "prefs.cfg";
106static const char *oldStateFileName_App_ = "state.binary"; 106static const char *oldStateFileName_App_ = "state.binary";
107static const char *stateFileName_App_ = "state.lgr"; 107static const char *stateFileName_App_ = "state.lgr";
108static const char *tempStateFileName_App_ = "state.lgr.tmp";
108static const char *defaultDownloadDir_App_ = "~/Downloads"; 109static const char *defaultDownloadDir_App_ = "~/Downloads";
109 110
110static const int idleThreshold_App_ = 1000; /* ms */ 111static const int idleThreshold_App_ = 1000; /* ms */
@@ -554,7 +555,7 @@ static void saveState_App_(const iApp *d) {
554 navigation history, cached content) and depends closely on the widget 555 navigation history, cached content) and depends closely on the widget
555 tree. The data is largely not reorderable and should not be modified 556 tree. The data is largely not reorderable and should not be modified
556 by the user manually. */ 557 by the user manually. */
557 iFile *f = newCStr_File(concatPath_CStr(dataDir_App_(), stateFileName_App_)); 558 iFile *f = newCStr_File(concatPath_CStr(dataDir_App_(), tempStateFileName_App_));
558 if (open_File(f, writeOnly_FileMode)) { 559 if (open_File(f, writeOnly_FileMode)) {
559 writeData_File(f, magicState_App_, 4); 560 writeData_File(f, magicState_App_, 4);
560 writeU32_File(f, latest_FileVersion); /* version */ 561 writeU32_File(f, latest_FileVersion); /* version */
@@ -596,11 +597,19 @@ static void saveState_App_(const iApp *d) {
596 write8_File(f, flags); 597 write8_File(f, flags);
597 serializeState_DocumentWidget(i.object, stream_File(f)); 598 serializeState_DocumentWidget(i.object, stream_File(f));
598 } 599 }
600 iRelease(f);
599 } 601 }
600 else { 602 else {
603 iRelease(f);
601 fprintf(stderr, "[App] failed to save state: %s\n", strerror(errno)); 604 fprintf(stderr, "[App] failed to save state: %s\n", strerror(errno));
605 return;
602 } 606 }
603 iRelease(f); 607 /* Copy it over to the real file. This avoids truncation if the app for any reason crashes
608 before the state file is fully written. */
609 const char *tempName = concatPath_CStr(dataDir_App_(), tempStateFileName_App_);
610 const char *finalName = concatPath_CStr(dataDir_App_(), stateFileName_App_);
611 remove(finalName);
612 rename(tempName, finalName);
604} 613}
605 614
606#if defined (LAGRANGE_ENABLE_IDLE_SLEEP) 615#if defined (LAGRANGE_ENABLE_IDLE_SLEEP)