SF.net SVN: geany:[3722] trunk

eht16 at users.sourceforge.net eht16 at xxxxx
Tue Apr 21 20:54:04 UTC 2009


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.



More information about the Commits mailing list