Use GMappedFile instead g_file_get_contents(). (build_instructions): Pass
authorSoren Sandmann <sandmann@daimi.au.dk>
Thu, 23 Nov 2006 03:32:04 +0000 (03:32 +0000)
committerSøren Sandmann Pedersen <ssp@src.gnome.org>
Thu, 23 Nov 2006 03:32:04 +0000 (03:32 +0000)
2006-11-22  Soren Sandmann <sandmann@daimi.au.dk>

        * sfile.c (sfile_load): Use GMappedFile instead
        g_file_get_contents().
        (build_instructions): Pass length instead of -1.
        (sfile_output_save): Use g_file_set_contents() instead of
        cut-and-pasted copy.

ChangeLog
sfile.c

index 7ee6a80..01db7f7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2006-11-22  Soren Sandmann <sandmann@daimi.au.dk>
 
+       * sfile.c (sfile_load): Use GMappedFile instead
+       g_file_get_contents().
+       (build_instructions): Pass length instead of -1.
+       (sfile_output_save): Use g_file_set_contents() instead of
+       cut-and-pasted copy.
+
+2006-11-22  Soren Sandmann <sandmann@daimi.au.dk>
+
        * profile.c (add_trace_to_tree): Move match to front
        (add_trace_to_tree): Break as soon as a recursive call is found.
 
diff --git a/sfile.c b/sfile.c
index ac23aef..8321714 100644 (file)
--- a/sfile.c
+++ b/sfile.c
@@ -28,6 +28,7 @@
 #endif
 #include "sfile.h"
 #include "sformat.h"
+#include <sys/mman.h>
 
 typedef struct BuildContext BuildContext;
 typedef struct Instruction Instruction;
@@ -607,6 +608,7 @@ post_process_read_instructions (Instruction  *instructions,
 
 static Instruction *
 build_instructions (const char *contents,
+                    gsize       length,
                    SFormat    *format,
                    int        *n_instructions,
                    GError    **err)
@@ -627,7 +629,7 @@ build_instructions (const char *contents,
     
     parse_context = g_markup_parse_context_new (&parser, 0, &build, NULL);
     
-    if (!g_markup_parse_context_parse (parse_context, contents, -1, err))
+    if (!g_markup_parse_context_parse (parse_context, contents, length, err))
     {
         free_instructions ((Instruction *)build.instructions->data, build.instructions->len);
        return NULL;
@@ -661,22 +663,29 @@ sfile_load (const char  *filename,
     gchar *contents;
     gsize length;
     SFileInput *input;
-    
-    if (!g_file_get_contents (filename, &contents, &length, err))
-       return NULL;
+    GMappedFile *file;
+
+    file = g_mapped_file_new (filename, FALSE, err);
+    if (!file)
+        return NULL;
+
+    contents = g_mapped_file_get_contents (file);
+    length = g_mapped_file_get_length (file);
+
+    madvise (contents, length, MADV_SEQUENTIAL);
     
     input = g_new (SFileInput, 1);
     
-    input->instructions = build_instructions (contents, format, &input->n_instructions, err);
+    input->instructions = build_instructions (contents, length, format, &input->n_instructions, err);
     
     if (!input->instructions)
     {
         g_free (input);
-        g_free (contents);
+        g_mapped_file_free (file);
         return NULL;
     }
-    
-    g_free (contents);
+
+    g_mapped_file_free (file);
     
     input->current_instruction = input->instructions;
     input->instructions_by_location = g_hash_table_new (g_direct_hash, g_direct_equal);
@@ -976,12 +985,6 @@ add_nl (GString *output)
     g_string_append_c (output, '\n');
 }
 
-static gboolean
-file_replace (const gchar  *filename,
-              const gchar  *contents,
-              gssize       length,
-              GError     **error);
-
 #if 0
 static void
 disaster (int status)
@@ -1129,7 +1132,7 @@ sfile_output_save (SFileOutput  *sfile,
     g_free (compressed);
 #endif
     
-    retval = file_replace (filename, output->str, - 1, err);
+    retval = g_file_set_contents (filename, output->str, output->len, err);
     
     g_string_free (output, TRUE);
     
@@ -1161,337 +1164,3 @@ sfile_output_free (SFileOutput *sfile)
     g_hash_table_destroy (sfile->objects);
     g_free (sfile);
 }
-
-
-
-
-
-
-
-
-
-
-
-
-
-/* A copy of g_file_replace() because I don't want to depend on
- * GLib HEAD
- */
-#include <errno.h>
-#include <sys/wait.h>
-#include <glib/gstdio.h>
-#include <unistd.h>
-
-static gboolean
-rename_file (const char *old_name,
-            const char *new_name,
-            GError **err)
-{
-    errno = 0;
-    if (g_rename (old_name, new_name) == -1)
-    {
-       int save_errno = errno;
-       gchar *display_old_name = g_filename_display_name (old_name);
-       gchar *display_new_name = g_filename_display_name (new_name);
-       
-       g_set_error (err,
-                    G_FILE_ERROR,
-                    g_file_error_from_errno (save_errno),
-                    "Failed to rename file '%s' to '%s': g_rename() failed: %s",
-                    display_old_name,
-                    display_new_name,
-                    g_strerror (save_errno));
-       
-       g_free (display_old_name);
-       g_free (display_new_name);
-       
-       return FALSE;
-    }
-    
-    return TRUE;
-}
-
-static gboolean
-set_umask_permissions (int          fd,
-                      GError      **err)
-{
-#ifdef G_OS_WIN32
-    
-    return TRUE;
-    
-#else
-    
-    /* All of this function is just to work around the fact that
-     * there is no way to get the umask without changing it.
-     *
-     * We can't just change-and-reset the umask because that would
-     * lead to a race condition if another thread tried to change
-     * the umask in between the getting and the setting of the umask.
-     * So we have to do the whole thing in a child process.
-     */
-    
-    pid_t pid = fork ();
-    
-    if (pid == -1)
-    {
-       g_set_error (err,
-                    G_FILE_ERROR,
-                    g_file_error_from_errno (errno),
-                    "Could not change file mode: fork() failed: %s",
-                    g_strerror (errno));
-       
-       return FALSE;
-    }
-    else if (pid == 0)
-    {
-       /* child */
-       mode_t mask = umask (0666);
-       
-       errno = 0;
-       if (fchmod (fd, 0666 & ~mask) == -1)
-           _exit (errno);
-       else
-           _exit (0);
-       
-       return TRUE; /* To quiet gcc */
-    }
-    else
-    { 
-       /* parent */
-       int status;
-       
-       waitpid (pid, &status, 0);
-       
-       if (WIFEXITED (status))
-       {
-           int chmod_errno = WEXITSTATUS (status);
-           
-           if (chmod_errno == 0)
-           {
-               return TRUE;
-           }
-           else
-           {
-               g_set_error (err,
-                            G_FILE_ERROR,
-                            g_file_error_from_errno (chmod_errno),
-                            "Could not change file mode: chmod() failed: %s",
-                            g_strerror (chmod_errno));
-               
-               return FALSE;
-           }
-       }
-       else if (WIFSIGNALED (status))
-       {
-           g_set_error (err,
-                        G_FILE_ERROR,
-                        G_FILE_ERROR_FAILED,
-                        "Could not change file mode: Child terminated by signal: %s",
-                        g_strsignal (WTERMSIG (status)));
-           
-           return FALSE;
-       }
-       else
-       {
-           /* This shouldn't happen */
-           g_set_error (err,
-                        G_FILE_ERROR,
-                        G_FILE_ERROR_FAILED,
-                        "Could not change file mode: Child terminated abnormally");
-           return FALSE;
-       }
-    }
-#endif
-}
-
-static gchar *
-write_to_temp_file (const gchar *contents,
-                   gssize length,
-                   const gchar *template,
-                   GError **err)
-{
-    gchar *tmp_name;
-    gchar *display_name;
-    gchar *retval;
-    FILE *file;
-    gint fd;
-    int save_errno;
-    
-    retval = NULL;
-    
-    tmp_name = g_strdup_printf ("%s.XXXXXX", template);
-    
-    errno = 0;
-    fd = g_mkstemp (tmp_name);
-    save_errno = errno;
-    display_name = g_filename_display_name (tmp_name);
-    
-    if (fd == -1)
-    {
-       g_set_error (err,
-                    G_FILE_ERROR,
-                    g_file_error_from_errno (save_errno),
-                    "Failed to create file '%s': %s",
-                    display_name, g_strerror (save_errno));
-       
-       goto out;
-    }
-    
-    if (!set_umask_permissions (fd, err))
-    {
-       close (fd);
-       g_unlink (tmp_name);
-       
-       goto out;
-    }
-    
-    errno = 0;
-    file = fdopen (fd, "wb");
-    if (!file)
-    {
-       g_set_error (err,
-                    G_FILE_ERROR,
-                    g_file_error_from_errno (errno),
-                    "Failed to open file '%s' for writing: fdopen() failed: %s",
-                    display_name,
-                    g_strerror (errno));
-       
-       close (fd);
-       g_unlink (tmp_name);
-       
-       goto out;
-    }
-    
-    if (length > 0)
-    {
-       size_t n_written;
-       
-       errno = 0;
-       
-       n_written = fwrite (contents, 1, length, file);
-       
-       if (n_written < length)
-       {
-           g_set_error (err,
-                        G_FILE_ERROR,
-                        g_file_error_from_errno (errno),
-                        "Failed to write file '%s': fwrite() failed: %s",
-                        display_name,
-                        g_strerror (errno));
-           
-           fclose (file);
-           g_unlink (tmp_name);
-           
-           goto out;
-       }
-    }
-    
-    errno = 0;
-    if (fclose (file) == EOF)
-    {
-       g_set_error (err,
-                    G_FILE_ERROR,
-                    g_file_error_from_errno (errno),
-                    "Failed to close file '%s': fclose() failed: %s",
-                    display_name, 
-                    g_strerror (errno));
-       
-       g_unlink (tmp_name);
-       
-       goto out;
-    }
-    
-    retval = g_strdup (tmp_name);
-    
-out:
-    g_free (tmp_name);
-    g_free (display_name);
-    
-    return retval;
-}
-
-static gboolean
-file_replace (const gchar *filename,
-              const gchar *contents,
-              gssize        length,
-              GError      **error)
-{
-    gchar *tmp_filename;
-    gboolean retval;
-    GError *rename_error = NULL;
-    
-    g_return_val_if_fail (filename != NULL, FALSE);
-    g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-    g_return_val_if_fail (contents != NULL || length == 0, FALSE);
-    g_return_val_if_fail (length >= -1, FALSE);
-    
-    if (length == -1)
-       length = strlen (contents);
-    
-    tmp_filename = write_to_temp_file (contents, length, filename, error);
-    
-    if (!tmp_filename)
-    {
-       retval = FALSE;
-       goto out;
-    }
-    
-    if (!rename_file (tmp_filename, filename, &rename_error))
-    {
-#ifndef G_OS_WIN32
-       
-       g_unlink (tmp_filename);
-       g_propagate_error (error, rename_error);
-       retval = FALSE;
-       goto out;
-       
-#else /* G_OS_WIN32 */
-       
-      /* Renaming failed, but on Windows this may just mean
-       * the file already exists. So if the target file
-       * exists, try deleting it and do the rename again.
-       */
-       if (!g_file_test (filename, G_FILE_TEST_EXISTS))
-       {
-           g_unlink (tmp_filename);
-           g_propagate_error (error, rename_error);
-           retval = FALSE;
-           goto out;
-       }
-       
-       g_error_free (rename_error);
-       
-       if (g_unlink (filename) == -1)
-       {
-           gchar *display_filename = g_filename_display_name (filename);
-           
-           g_set_error (error,
-                        G_FILE_ERROR,
-                        g_file_error_from_errno (errno),
-                        "Existing file '%s' could not be removed: g_unlink() failed: %s",
-                        display_filename,
-                        g_strerror (errno));
-           
-           g_free (display_filename);
-           g_unlink (tmp_filename);
-           retval = FALSE;
-           goto out;
-       }
-       
-       if (!rename_file (tmp_filename, filename, error))
-       {
-           g_unlink (tmp_filename);
-           retval = FALSE;
-           goto out;
-       }
-       
-#endif
-    }
-    
-    retval = TRUE;
-    
-out:
-    g_free (tmp_filename);
-    return retval;
-}
-