Revision: 3722 http://geany.svn.sourceforge.net/geany/?rev=3722&view=rev Author: eht16 Date: 2009-04-21 20:54:04 +0000 (Tue, 21 Apr 2009)
Log Message: ----------- Add a hidden preference 'use_safe_file_saving' to save files to disk by creating a temporary file first. This has serious side effects, please read the documentation before enabling this.
Modified Paths: -------------- trunk/ChangeLog trunk/doc/geany.html trunk/doc/geany.txt trunk/src/document.c trunk/src/document.h trunk/src/keyfile.c
Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-04-21 20:53:42 UTC (rev 3721) +++ trunk/ChangeLog 2009-04-21 20:54:04 UTC (rev 3722) @@ -9,6 +9,11 @@ document_get_basename_for_display() to the plugin API. * doc/geany.html, doc/geany.txt, src/toolbar.c: Add new toolbar element: Print (patch by Roland Baudin, thanks). + * doc/geany.html, doc/geany.txt, src/document.c, src/document.h, + src/keyfile.c: + Add a hidden preference 'use_safe_file_saving' to save files to disk + by creating a temporary file first. This has serious side effects, + please read the documentation before enabling this.
2009-04-20 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
Modified: trunk/doc/geany.html =================================================================== --- trunk/doc/geany.html 2009-04-21 20:53:42 UTC (rev 3721) +++ trunk/doc/geany.html 2009-04-21 20:54:04 UTC (rev 3722) @@ -4221,6 +4221,30 @@ <tt class="docutils literal"><span class="pre">vte/termcap/xterm</span></tt>.</td> <td>xterm</td> </tr> +<tr><td><strong>File related</strong></td> +<td> </td> +<td> </td> +</tr> +<tr><td>use_safe_file_saving</td> +<td>Defines the mode how Geany saves files to +disk. If disabled, Geany directly writes +the content of the document to disk. This +might cause in loss of data when there is +no more free space on disk to save the +file. When set to true, Geany first saves +the contents into a temporary file and if +this succeeded, the temporary file is +moved to the real file to save. +This gives better error checking in case of +no more free disk space. But it also +destroys hard links of the original file +and its permissions (e.g. executable flags +are reset). Use this with care as it can +break things seriously. +The better approach would be to ensure your +disk won't run out of free space.</td> +<td>false</td> +</tr> </tbody> </table> </div> @@ -4792,7 +4816,7 @@ <div class="footer"> <hr class="footer" /> <a class="reference external" href="geany.txt">View document source</a>. -Generated on: 2009-04-21 19:06 UTC. +Generated on: 2009-04-21 19:30 UTC. Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
Modified: trunk/doc/geany.txt =================================================================== --- trunk/doc/geany.txt 2009-04-21 20:53:42 UTC (rev 3721) +++ trunk/doc/geany.txt 2009-04-21 20:54:04 UTC (rev 3722) @@ -3704,6 +3704,24 @@ emulation Terminal emulation mode. Only change this xterm if you have VTE termcap files other than ``vte/termcap/xterm``. +**File related** +use_safe_file_saving Defines the mode how Geany saves files to false + disk. If disabled, Geany directly writes + the content of the document to disk. This + might cause in loss of data when there is + no more free space on disk to save the + file. When set to true, Geany first saves + the contents into a temporary file and if + this succeeded, the temporary file is + moved to the real file to save. + This gives better error checking in case of + no more free disk space. But it also + destroys hard links of the original file + and its permissions (e.g. executable flags + are reset). Use this with care as it can + break things seriously. + The better approach would be to ensure your + disk won't run out of free space. ================================ =========================================== ==================
Modified: trunk/src/document.c =================================================================== --- trunk/src/document.c 2009-04-21 20:53:42 UTC (rev 3721) +++ trunk/src/document.c 2009-04-21 20:54:04 UTC (rev 3722) @@ -1680,34 +1680,55 @@ }
-static gint write_data_to_disk(GeanyDocument *doc, const gchar *locale_filename, - const gchar *data, gint len) +static gchar *write_data_to_disk(GeanyDocument *doc, const gchar *locale_filename, + const gchar *data, gint len) { FILE *fp; gint bytes_written; gint err = 0; + GError *error = NULL;
- g_return_val_if_fail(data != NULL, EINVAL); + g_return_val_if_fail(doc != NULL, g_strdup(g_strerror(EINVAL))); + g_return_val_if_fail(data != NULL, g_strdup(g_strerror(EINVAL)));
- fp = g_fopen(locale_filename, "wb"); - if (G_UNLIKELY(fp == NULL)) - return errno; + /* we never use g_file_set_contents() for remote files as Geany only writes such files + * 'into' the Fuse mountpoint, the file itself is then written by GVfs on the target + * remote filesystem. */ + if (! file_prefs.use_safe_file_saving || doc->priv->is_remote) + { + fp = g_fopen(locale_filename, "wb"); + if (G_UNLIKELY(fp == NULL)) + return g_strdup(g_strerror(errno));
- bytes_written = fwrite(data, sizeof(gchar), len, fp); + bytes_written = fwrite(data, sizeof(gchar), len, fp);
- if (G_UNLIKELY(len != bytes_written)) - err = errno; + if (G_UNLIKELY(len != bytes_written)) + err = errno;
- fclose(fp); + fclose(fp);
+ if (err != 0) + return g_strdup(g_strerror(err)); + } + else + { + g_file_set_contents(locale_filename, data, len, &error); + if (error != NULL) + { + gchar *msg = g_strdup(error->message); + g_error_free(error); + return msg; + } + } + /* now the file is on disk, set real_path */ - if (err == 0 && doc->real_path == NULL) + if (doc->real_path == NULL) { doc->real_path = tm_get_real_path(locale_filename); doc->priv->is_remote = utils_is_remote_path(locale_filename); }
- return err; + return NULL; }
@@ -1726,9 +1747,9 @@ **/ gboolean document_save_file(GeanyDocument *doc, gboolean force) { + gchar *errmsg; gchar *data; gsize len; - gint err; gchar *locale_filename;
g_return_val_if_fail(doc != NULL, FALSE); @@ -1793,17 +1814,17 @@ doc->priv->file_disk_status = FILE_IGNORE;
/* actually write the content of data to the file on disk */ - err = write_data_to_disk(doc, locale_filename, data, len); + errmsg = write_data_to_disk(doc, locale_filename, data, len); g_free(data);
- if (G_UNLIKELY(err != 0)) + if (errmsg != NULL) { - ui_set_statusbar(TRUE, _("Error saving file (%s)."), g_strerror(err)); - dialogs_show_msgbox_with_secondary(GTK_MESSAGE_ERROR, - _("Error saving file."), g_strerror(err)); + ui_set_statusbar(TRUE, _("Error saving file (%s)."), errmsg); + dialogs_show_msgbox_with_secondary(GTK_MESSAGE_ERROR, _("Error saving file."), errmsg); doc->priv->file_disk_status = FILE_OK; utils_beep(); g_free(locale_filename); + g_free(errmsg); return FALSE; }
Modified: trunk/src/document.h =================================================================== --- trunk/src/document.h 2009-04-21 20:53:42 UTC (rev 3721) +++ trunk/src/document.h 2009-04-21 20:54:04 UTC (rev 3722) @@ -56,6 +56,7 @@ gint default_eol_character; gint disk_check_timeout; gboolean cmdline_new_files; /* New file if command-line filename doesn't exist */ + gboolean use_safe_file_saving; } GeanyFilePrefs;
Modified: trunk/src/keyfile.c =================================================================== --- trunk/src/keyfile.c 2009-04-21 20:53:42 UTC (rev 3721) +++ trunk/src/keyfile.c 2009-04-21 20:54:04 UTC (rev 3722) @@ -172,6 +172,8 @@ "show_symbol_list_expanders", TRUE); stash_group_add_boolean(group, &ui_prefs.allow_always_save, "allow_always_save", FALSE); + stash_group_add_boolean(group, &file_prefs.use_safe_file_saving, + "use_safe_file_saving", FALSE); }
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.