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.

git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@3722 ea778897-0a13-0410-b9d1-a72fbfd435f5
This commit is contained in:
Enrico Tröger 2009-04-21 20:54:04 +00:00
parent fae6486182
commit 8fcef38e82
6 changed files with 90 additions and 19 deletions

View File

@ -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>

View File

@ -4221,6 +4221,30 @@ if you have VTE termcap files other than
<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>&nbsp;</td>
<td>&nbsp;</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 @@ USE OR PERFORMANCE OF THIS SOFTWARE.</p>
<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>

View File

@ -3704,6 +3704,24 @@ allow_always_save Whether files can be saved always, even if f
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.
================================ =========================================== ==================

View File

@ -1680,18 +1680,25 @@ _("An error occurred while converting the file from UTF-8 in \"%s\". The file re
}
static gint write_data_to_disk(GeanyDocument *doc, const gchar *locale_filename,
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)));
/* 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 errno;
return g_strdup(g_strerror(errno));
bytes_written = fwrite(data, sizeof(gchar), len, fp);
@ -1700,14 +1707,28 @@ static gint write_data_to_disk(GeanyDocument *doc, const gchar *locale_filename,
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 @@ static gint write_data_to_disk(GeanyDocument *doc, const gchar *locale_filename,
**/
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 @@ gboolean document_save_file(GeanyDocument *doc, gboolean force)
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;
}

View File

@ -56,6 +56,7 @@ typedef struct GeanyFilePrefs
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;

View File

@ -172,6 +172,8 @@ static void init_pref_groups(void)
"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);
}