diff options
author | Andrea Weikert <elubie@gmx.net> | 2011-06-02 16:44:59 +0400 |
---|---|---|
committer | Andrea Weikert <elubie@gmx.net> | 2011-06-02 16:44:59 +0400 |
commit | b4872b84c87ee5c7feade2fe684cd5823bf4c078 (patch) | |
tree | e90af136c9041ba46329ffd3e3d319c8e32348fb /source | |
parent | 1ba4550d2786bf5348d43a7285d37a66d53d461e (diff) |
fix for [#27410] Manual save kills actual .blend file if disk space is low
- moved do_history into WM_write_file after successful write of .blend@ temporary file
- Added new file flag, to avoid writing history on writing the startup.blend, autosave files and undo.
Thanks Campbell, Brecht for review!
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_global.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/blender.c | 5 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 104 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_files.c | 36 |
4 files changed, 83 insertions, 63 deletions
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h index 0360acbea32..d21b0428d76 100644 --- a/source/blender/blenkernel/BKE_global.h +++ b/source/blender/blenkernel/BKE_global.h @@ -145,6 +145,7 @@ typedef struct Global { #define G_FILE_IGNORE_DEPRECATION_WARNINGS (1 << 22) /* deprecated */ #define G_FILE_RECOVER (1 << 23) #define G_FILE_RELATIVE_REMAP (1 << 24) +#define G_FILE_HISTORY (1 << 25) /* G.windowstate */ #define G_WINDOWSTATE_USERDEF 0 diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 2fce1175fe1..b852629e49c 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -523,7 +523,8 @@ void BKE_write_undo(bContext *C, const char *name) static int counter= 0; char filepath[FILE_MAXDIR+FILE_MAXFILE]; char numstr[32]; - + int fileflags = G.fileflags & ~(G_FILE_HISTORY); /* don't do file history on undo */ + /* calculate current filepath */ counter++; counter= counter % U.undosteps; @@ -531,7 +532,7 @@ void BKE_write_undo(bContext *C, const char *name) BLI_snprintf(numstr, sizeof(numstr), "%d.blend", counter); BLI_make_file_string("/", filepath, btempdir, numstr); - success= BLO_write_file(CTX_data_main(C), filepath, G.fileflags, NULL, NULL); + success= BLO_write_file(CTX_data_main(C), filepath, fileflags, NULL, NULL); BLI_strncpy(curundo->str, filepath, sizeof(curundo->str)); } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 17f54141252..240e8d00ab8 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -2520,6 +2520,41 @@ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFil return endwrite(wd); } +/* do reverse file history: .blend1 -> .blend2, .blend -> .blend1 */ +/* return: success(0), failure(1) */ +static int do_history(const char *name, ReportList *reports) +{ + char tempname1[FILE_MAXDIR+FILE_MAXFILE], tempname2[FILE_MAXDIR+FILE_MAXFILE]; + int hisnr= U.versions; + + if(U.versions==0) return 0; + if(strlen(name)<2) { + BKE_report(reports, RPT_ERROR, "Unable to make version backup: filename too short"); + return 1; + } + + while(hisnr > 1) { + BLI_snprintf(tempname1, sizeof(tempname1), "%s%d", name, hisnr-1); + BLI_snprintf(tempname2, sizeof(tempname2), "%s%d", name, hisnr); + + if(BLI_rename(tempname1, tempname2)) { + BKE_report(reports, RPT_ERROR, "Unable to make version backup"); + return 1; + } + hisnr--; + } + + /* is needed when hisnr==1 */ + BLI_snprintf(tempname1, sizeof(tempname1), "%s%d", name, hisnr); + + if(BLI_rename(name, tempname1)) { + BKE_report(reports, RPT_ERROR, "Unable to make version backup"); + return 1; + } + + return 0; +} + /* return: success (1) */ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportList *reports, int *thumb) { @@ -2571,45 +2606,52 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL err= write_file_handle(mainvar, file, NULL,NULL, write_user_block, write_flags, thumb); close(file); - /* rename/compress */ - if(!err) { - if(write_flags & G_FILE_COMPRESS) { - /* compressed files have the same ending as regular files... only from 2.4!!! */ - char gzname[FILE_MAXDIR+FILE_MAXFILE+4]; - int ret; + if (err) { + BKE_report(reports, RPT_ERROR, strerror(errno)); + remove(tempname); - /* first write compressed to separate @.gz */ - BLI_snprintf(gzname, sizeof(gzname), "%s@.gz", filepath); - ret = BLI_gzip(tempname, gzname); - - if(0==ret) { - /* now rename to real file name, and delete temp @ file too */ - if(BLI_rename(gzname, filepath) != 0) { - BKE_report(reports, RPT_ERROR, "Can't change old file. File saved with @."); - return 0; - } + return 0; + } - BLI_delete(tempname, 0, 0); - } - else if(-1==ret) { - BKE_report(reports, RPT_ERROR, "Failed opening .gz file."); - return 0; - } - else if(-2==ret) { - BKE_report(reports, RPT_ERROR, "Failed opening .blend file for compression."); + /* file save to temporary file was successful */ + /* now do reverse file history (move .blend1 -> .blend2, .blend -> .blend1) */ + if (write_flags & G_FILE_HISTORY) { + int err_hist = do_history(filepath, reports); + if (err_hist) { + BKE_report(reports, RPT_ERROR, "Version backup failed. File saved with @"); + return 0; + } + } + + if(write_flags & G_FILE_COMPRESS) { + /* compressed files have the same ending as regular files... only from 2.4!!! */ + char gzname[FILE_MAXDIR+FILE_MAXFILE+4]; + int ret; + + /* first write compressed to separate @.gz */ + BLI_snprintf(gzname, sizeof(gzname), "%s@.gz", filepath); + ret = BLI_gzip(tempname, gzname); + + if(0==ret) { + /* now rename to real file name, and delete temp @ file too */ + if(BLI_rename(gzname, filepath) != 0) { + BKE_report(reports, RPT_ERROR, "Can't change old file. File saved with @."); return 0; } + + BLI_delete(tempname, 0, 0); } - else if(BLI_rename(tempname, filepath) != 0) { - BKE_report(reports, RPT_ERROR, "Can't change old file. File saved with @"); + else if(-1==ret) { + BKE_report(reports, RPT_ERROR, "Failed opening .gz file."); + return 0; + } + else if(-2==ret) { + BKE_report(reports, RPT_ERROR, "Failed opening .blend file for compression."); return 0; } - } - else { - BKE_report(reports, RPT_ERROR, strerror(errno)); - remove(tempname); - + else if(BLI_rename(tempname, filepath) != 0) { + BKE_report(reports, RPT_ERROR, "Can't change old file. File saved with @"); return 0; } diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 1f005ba6021..a5ee01de2f1 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -620,31 +620,6 @@ static void write_history(void) } } -static void do_history(char *name, ReportList *reports) -{ - char tempname1[FILE_MAXDIR+FILE_MAXFILE], tempname2[FILE_MAXDIR+FILE_MAXFILE]; - int hisnr= U.versions; - - if(U.versions==0) return; - if(strlen(name)<2) return; - - while(hisnr > 1) { - BLI_snprintf(tempname1, sizeof(tempname1), "%s%d", name, hisnr-1); - BLI_snprintf(tempname2, sizeof(tempname2), "%s%d", name, hisnr); - - if(BLI_rename(tempname1, tempname2)) - BKE_report(reports, RPT_ERROR, "Unable to make version backup"); - - hisnr--; - } - - /* is needed when hisnr==1 */ - BLI_snprintf(tempname1, sizeof(tempname1), "%s%d", name, hisnr); - - if(BLI_rename(name, tempname1)) - BKE_report(reports, RPT_ERROR, "Unable to make version backup"); -} - static ImBuf *blend_file_thumb(Scene *scene, int **thumb_pt) { /* will be scaled down, but gives some nice oversampling */ @@ -693,9 +668,11 @@ static ImBuf *blend_file_thumb(Scene *scene, int **thumb_pt) int write_crash_blend(void) { char path[FILE_MAX]; + int fileflags = G.fileflags & ~(G_FILE_HISTORY); /* don't do file history on crash file */ + BLI_strncpy(path, G.main->name, sizeof(path)); BLI_replace_extension(path, sizeof(path), "_crash.blend"); - if(BLO_write_file(G.main, path, G.fileflags, NULL, NULL)) { + if(BLO_write_file(G.main, path, fileflags, NULL, NULL)) { printf("written: %s\n", path); return 1; } @@ -753,8 +730,7 @@ int WM_write_file(bContext *C, const char *target, int fileflags, ReportList *re /* blend file thumbnail */ ibuf_thumb= blend_file_thumb(CTX_data_scene(C), &thumb); - /* rename to .blend1, do this as last before write */ - do_history(filepath, reports); + fileflags |= G_FILE_HISTORY; /* write file history */ if (BLO_write_file(CTX_data_main(C), filepath, fileflags, reports, thumb)) { if(!copy) { @@ -809,7 +785,7 @@ int WM_write_homefile(bContext *C, wmOperator *op) printf("trying to save homefile at %s ", filepath); /* force save as regular blend file */ - fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_LOCK | G_FILE_SIGN); + fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_LOCK | G_FILE_SIGN | G_FILE_HISTORY); if(BLO_write_file(CTX_data_main(C), filepath, fileflags, op->reports, NULL) == 0) { printf("fail\n"); @@ -883,7 +859,7 @@ void wm_autosave_timer(const bContext *C, wmWindowManager *wm, wmTimer *UNUSED(w wm_autosave_location(filepath); /* force save as regular blend file */ - fileflags = G.fileflags & ~(G_FILE_COMPRESS|G_FILE_AUTOPLAY |G_FILE_LOCK|G_FILE_SIGN); + fileflags = G.fileflags & ~(G_FILE_COMPRESS|G_FILE_AUTOPLAY |G_FILE_LOCK|G_FILE_SIGN|G_FILE_HISTORY); /* no error reporting to console */ BLO_write_file(CTX_data_main(C), filepath, fileflags, NULL, NULL); |