diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/app.c | 13 |
1 files changed, 11 insertions, 2 deletions
@@ -105,6 +105,7 @@ static const char *defaultDataDir_App_ = "~/config/settings/lagrange"; | |||
105 | static const char *prefsFileName_App_ = "prefs.cfg"; | 105 | static const char *prefsFileName_App_ = "prefs.cfg"; |
106 | static const char *oldStateFileName_App_ = "state.binary"; | 106 | static const char *oldStateFileName_App_ = "state.binary"; |
107 | static const char *stateFileName_App_ = "state.lgr"; | 107 | static const char *stateFileName_App_ = "state.lgr"; |
108 | static const char *tempStateFileName_App_ = "state.lgr.tmp"; | ||
108 | static const char *defaultDownloadDir_App_ = "~/Downloads"; | 109 | static const char *defaultDownloadDir_App_ = "~/Downloads"; |
109 | 110 | ||
110 | static const int idleThreshold_App_ = 1000; /* ms */ | 111 | static 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) |