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:
parent
fae6486182
commit
8fcef38e82
@ -9,6 +9,11 @@
|
|||||||
document_get_basename_for_display() to the plugin API.
|
document_get_basename_for_display() to the plugin API.
|
||||||
* doc/geany.html, doc/geany.txt, src/toolbar.c:
|
* doc/geany.html, doc/geany.txt, src/toolbar.c:
|
||||||
Add new toolbar element: Print (patch by Roland Baudin, thanks).
|
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>
|
2009-04-20 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
|
||||||
|
@ -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>
|
<tt class="docutils literal"><span class="pre">vte/termcap/xterm</span></tt>.</td>
|
||||||
<td>xterm</td>
|
<td>xterm</td>
|
||||||
</tr>
|
</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>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@ -4792,7 +4816,7 @@ USE OR PERFORMANCE OF THIS SOFTWARE.</p>
|
|||||||
<div class="footer">
|
<div class="footer">
|
||||||
<hr class="footer" />
|
<hr class="footer" />
|
||||||
<a class="reference external" href="geany.txt">View document source</a>.
|
<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.
|
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>
|
</div>
|
||||||
|
@ -3704,6 +3704,24 @@ allow_always_save Whether files can be saved always, even if f
|
|||||||
emulation Terminal emulation mode. Only change this xterm
|
emulation Terminal emulation mode. Only change this xterm
|
||||||
if you have VTE termcap files other than
|
if you have VTE termcap files other than
|
||||||
``vte/termcap/xterm``.
|
``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.
|
||||||
================================ =========================================== ==================
|
================================ =========================================== ==================
|
||||||
|
|
||||||
|
|
||||||
|
@ -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)
|
const gchar *data, gint len)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
gint bytes_written;
|
gint bytes_written;
|
||||||
gint err = 0;
|
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");
|
fp = g_fopen(locale_filename, "wb");
|
||||||
if (G_UNLIKELY(fp == NULL))
|
if (G_UNLIKELY(fp == NULL))
|
||||||
return errno;
|
return g_strdup(g_strerror(errno));
|
||||||
|
|
||||||
bytes_written = fwrite(data, sizeof(gchar), len, fp);
|
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);
|
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 */
|
/* 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->real_path = tm_get_real_path(locale_filename);
|
||||||
doc->priv->is_remote = utils_is_remote_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)
|
gboolean document_save_file(GeanyDocument *doc, gboolean force)
|
||||||
{
|
{
|
||||||
|
gchar *errmsg;
|
||||||
gchar *data;
|
gchar *data;
|
||||||
gsize len;
|
gsize len;
|
||||||
gint err;
|
|
||||||
gchar *locale_filename;
|
gchar *locale_filename;
|
||||||
|
|
||||||
g_return_val_if_fail(doc != NULL, FALSE);
|
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;
|
doc->priv->file_disk_status = FILE_IGNORE;
|
||||||
|
|
||||||
/* actually write the content of data to the file on disk */
|
/* 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);
|
g_free(data);
|
||||||
|
|
||||||
if (G_UNLIKELY(err != 0))
|
if (errmsg != NULL)
|
||||||
{
|
{
|
||||||
ui_set_statusbar(TRUE, _("Error saving file (%s)."), g_strerror(err));
|
ui_set_statusbar(TRUE, _("Error saving file (%s)."), errmsg);
|
||||||
dialogs_show_msgbox_with_secondary(GTK_MESSAGE_ERROR,
|
dialogs_show_msgbox_with_secondary(GTK_MESSAGE_ERROR, _("Error saving file."), errmsg);
|
||||||
_("Error saving file."), g_strerror(err));
|
|
||||||
doc->priv->file_disk_status = FILE_OK;
|
doc->priv->file_disk_status = FILE_OK;
|
||||||
utils_beep();
|
utils_beep();
|
||||||
g_free(locale_filename);
|
g_free(locale_filename);
|
||||||
|
g_free(errmsg);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +56,7 @@ typedef struct GeanyFilePrefs
|
|||||||
gint default_eol_character;
|
gint default_eol_character;
|
||||||
gint disk_check_timeout;
|
gint disk_check_timeout;
|
||||||
gboolean cmdline_new_files; /* New file if command-line filename doesn't exist */
|
gboolean cmdline_new_files; /* New file if command-line filename doesn't exist */
|
||||||
|
gboolean use_safe_file_saving;
|
||||||
}
|
}
|
||||||
GeanyFilePrefs;
|
GeanyFilePrefs;
|
||||||
|
|
||||||
|
@ -172,6 +172,8 @@ static void init_pref_groups(void)
|
|||||||
"show_symbol_list_expanders", TRUE);
|
"show_symbol_list_expanders", TRUE);
|
||||||
stash_group_add_boolean(group, &ui_prefs.allow_always_save,
|
stash_group_add_boolean(group, &ui_prefs.allow_always_save,
|
||||||
"allow_always_save", FALSE);
|
"allow_always_save", FALSE);
|
||||||
|
stash_group_add_boolean(group, &file_prefs.use_safe_file_saving,
|
||||||
|
"use_safe_file_saving", FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user