Re: Gnome config files update method?



Eric Sandeen <sandeen sgi com> writes: 
> Can someone point me to where/how the gnome config files are updated, so
> I can take a look at how this might interact with XFS?  Is there any
> chance that these files would be held open after the user has logged
> out?
> 

Look at gnome-libs/libgnome/gnome-config.c

Here's a patch to it that makes it more sane, btw.

Havoc

--- gnome-libs-1.2.13/libgnome/gnome-config.c.atomic-config-files	Sat Jun 17 12:53:33 2000
+++ gnome-libs-1.2.13/libgnome/gnome-config.c	Thu Apr 18 21:36:10 2002
@@ -47,6 +47,7 @@
 #include <ctype.h>	/* tolower() */
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <errno.h>
 #include <glib.h>
 #include "libgnomeP.h"
 
@@ -534,7 +535,7 @@
 	static char *cache_global_filename = NULL;
 	gboolean cache_valid;
 	time_t now;
-
+        
 	switch (mode) {
 	case SET:
 		/* fall through to normal behaviour */
@@ -622,29 +623,56 @@
 	return def;
 }
 
-static void 
+static gboolean
 dump_keys (FILE *profile, TKeys *p)
 {
 	if (!p)
-		return;
-	dump_keys (profile, p->link);
+		return TRUE;
+	if (!dump_keys (profile, p->link))
+                return FALSE;
 	if (*p->key_name) {
+                gboolean retval = FALSE;
 		char *t = escape_string_and_dup (p->value);
-		fprintf (profile, "%s=%s\n", p->key_name, t);
+                if (fputs (p->key_name, profile) < 0)
+                        goto out;
+                if (fputs ("=", profile) < 0)
+                        goto out;
+                if (fputs (t, profile) < 0)
+                        goto out;
+                if (fputs ("\n", profile) < 0)
+                        goto out;
+                retval = TRUE;
+        out:
 		g_free (t);
+                return retval;
 	}
+
+        return TRUE;
 }
 
-static void 
+static gboolean 
 dump_sections (FILE *profile, TSecHeader *p)
 {
 	if (!p)
-		return;
-	dump_sections (profile, p->link);
+		return TRUE;
+	if (!dump_sections (profile, p->link))
+                return FALSE;
+
 	if (p->section_name && p->section_name [0]){
-		fprintf (profile, "\n[%s]\n", p->section_name);
-		dump_keys (profile, p->keys);
+                if (fputs ("\n[", profile) < 0)
+                        return FALSE;
+
+                if (fputs (p->section_name, profile) < 0)
+                        return FALSE;
+                
+                if (fputs ("]\n", profile) < 0)
+                        return FALSE;
+
+		if (!dump_keys (profile, p->keys))
+                        return FALSE;
 	}
+
+        return TRUE;
 }
 
 /*check the path and if we need to create directories create them with
@@ -762,10 +790,53 @@
 			p->to_be_deleted = FALSE;
 			if(p==Current)
 				Current = NULL;
-		} else if (check_path(p->filename,0755) &&
-		    (profile = fopen (p->filename, "w")) != NULL){
-			dump_sections (profile, p->section);
-			fclose (profile);
+		} else if (check_path(p->filename,0755)) {
+                        int fd;
+                        char *template;
+                        gboolean ok;
+
+                        ok = FALSE;
+
+                        profile = NULL;
+                        template = g_strdup_printf ("%s-XXXXXX", p->filename);
+                        fd = mkstemp (template);
+
+                        if (fd < 0)
+                                goto out;
+                        fchmod (fd, 0644);
+                        profile = fdopen (fd, "w");
+
+                        if (profile == NULL)
+                                goto out;
+
+			if (!dump_sections (profile, p->section))
+                                goto out;
+
+                        /* have to close before rename or the fd may
+                         * not be flushed
+                         */
+                        if (profile) {                                
+                                if (fclose (profile) != 0) {
+                                        profile = NULL;
+                                        goto out;
+                                }
+                                profile = NULL;
+                        }
+                        
+                        if (rename (template, p->filename) < 0)
+                                goto out;
+
+                        ok = TRUE;
+                out:
+                        if (!ok)
+                          g_printerr ("failure writing %s: %s\n",
+                                      p->filename, strerror (errno));
+
+                        if (profile)
+                                fclose (profile);
+                        
+                        unlink (template);
+                        g_free (template);
 		}
 	}
 	



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]