Merge remote-tracking branch 'gvdb/master'
[platform/upstream/glib.git] / glib / gfileutils.c
index fbd124d..da6cacd 100644 (file)
@@ -19,8 +19,7 @@
  */
 
 #include "config.h"
-
-#include "glib.h"
+#include "glibconfig.h"
 
 #include <sys/stat.h>
 #ifdef HAVE_UNISTD_H
 #define O_BINARY 0
 #endif
 
+#include "gfileutils.h"
+
 #include "gstdio.h"
 #include "glibintl.h"
 
-#include "galias.h"
+#ifdef HAVE_LINUX_MAGIC_H /* for btrfs check */
+#include <linux/magic.h>
+#include <sys/vfs.h>
+#endif
 
 /**
  * g_mkdir_with_parents:
@@ -204,19 +208,26 @@ g_file_test (const gchar *filename,
     return TRUE;
       
   if (test & G_FILE_TEST_IS_REGULAR)
-    return (attributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE)) == 0;
+    {
+      if ((attributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE)) == 0)
+       return TRUE;
+    }
 
   if (test & G_FILE_TEST_IS_DIR)
-    return (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
+    {
+      if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
+       return TRUE;
+    }
 
-  if (test & G_FILE_TEST_IS_EXECUTABLE)
+  /* "while" so that we can exit this "loop" with a simple "break" */
+  while (test & G_FILE_TEST_IS_EXECUTABLE)
     {
       const gchar *lastdot = strrchr (filename, '.');
       const gchar *pathext = NULL, *p;
       int extlen;
 
       if (lastdot == NULL)
-       return FALSE;
+        break;
 
       if (_stricmp (lastdot, ".exe") == 0 ||
          _stricmp (lastdot, ".cmd") == 0 ||
@@ -228,7 +239,7 @@ g_file_test (const gchar *filename,
 
       pathext = g_getenv ("PATHEXT");
       if (pathext == NULL)
-       return FALSE;
+        break;
 
       pathext = g_utf8_casefold (pathext, -1);
 
@@ -256,7 +267,7 @@ g_file_test (const gchar *filename,
 
       g_free ((gchar *) pathext);
       g_free ((gchar *) lastdot);
-      return FALSE;
+      break;
     }
 
   return FALSE;
@@ -956,6 +967,20 @@ write_to_temp_file (const gchar  *contents,
       
       goto out;
     }
+
+#ifdef BTRFS_SUPER_MAGIC
+  {
+    struct statfs buf;
+
+    /* On Linux, on btrfs, skip the fsync since rename-over-existing is
+     * guaranteed to be atomic and this is the only case in which we
+     * would fsync() anyway.
+     */
+
+    if (fstatfs (fd, &buf) == 0 && buf.f_type == BTRFS_SUPER_MAGIC)
+      goto no_fsync;
+  }
+#endif
   
 #ifdef HAVE_FSYNC
   {
@@ -987,6 +1012,7 @@ write_to_temp_file (const gchar  *contents,
       }
   }
 #endif
+ no_fsync:
   
   errno = 0;
   if (fclose (file) == EOF)
@@ -1050,6 +1076,9 @@ write_to_temp_file (const gchar  *contents,
  * it returns %FALSE and sets @error. The error domain is #G_FILE_ERROR.
  * Possible error codes are those in the #GFileError enumeration.
  *
+ * Note that the name for the temporary file is constructed by appending up
+ * to 7 characters to @filename.
+ *
  * Return value: %TRUE on success, %FALSE if an error occurred
  *
  * Since: 2.8
@@ -1144,26 +1173,28 @@ g_file_set_contents (const gchar  *filename,
 /**
  * g_mkstemp_full:
  * @tmpl: template filename
- * @flags: flags to pass to an open() call in addition to O_EXCL and 
+ * @flags: flags to pass to an open() call in addition to O_EXCL and
  *         O_CREAT, which are passed automatically
  * @mode: permissios to create the temporary file with
  *
  * Opens a temporary file. See the mkstemp() documentation
- * on most UNIX-like systems. 
+ * on most UNIX-like systems.
  *
  * The parameter is a string that should follow the rules for
- * mkstemp() templates, i.e. contain the string "XXXXXX". 
+ * mkstemp() templates, i.e. contain the string "XXXXXX".
  * g_mkstemp_full() is slightly more flexible than mkstemp()
- * in that the sequence does not have to occur at the very end of the 
- * template and you can pass a @mode and additional @flags. The X 
+ * in that the sequence does not have to occur at the very end of the
+ * template and you can pass a @mode and additional @flags. The X
  * string will be modified to form the name of a file that didn't exist.
- * The string should be in the GLib file name encoding. Most importantly, 
+ * The string should be in the GLib file name encoding. Most importantly,
  * on Windows it should be in UTF-8.
  *
  * Return value: A file handle (as from open()) to the file
- * opened for reading and writing. The file handle should be
- * closed with close(). In case of errors, -1 is returned.  
- */ 
+ *     opened for reading and writing. The file handle should be
+ *     closed with close(). In case of errors, -1 is returned.
+ *
+ * Since: 2.22
+ */
 /*
  * g_mkstemp_full based on the mkstemp implementation from the GNU C library.
  * Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc.
@@ -1416,8 +1447,7 @@ g_build_path_va (const gchar  *separator,
 
       if (separator_len)
        {
-         while (start &&
-                strncmp (start, separator, separator_len) == 0)
+         while (strncmp (start, separator, separator_len) == 0)
            start += separator_len;
        }
 
@@ -1734,9 +1764,12 @@ g_build_filename (const gchar *first_element,
   return str;
 }
 
-#define KILOBYTE_FACTOR 1024.0
-#define MEGABYTE_FACTOR (1024.0 * 1024.0)
-#define GIGABYTE_FACTOR (1024.0 * 1024.0 * 1024.0)
+#define KILOBYTE_FACTOR (G_GOFFSET_CONSTANT (1024))
+#define MEGABYTE_FACTOR (KILOBYTE_FACTOR * KILOBYTE_FACTOR)
+#define GIGABYTE_FACTOR (MEGABYTE_FACTOR * KILOBYTE_FACTOR)
+#define TERABYTE_FACTOR (GIGABYTE_FACTOR * KILOBYTE_FACTOR)
+#define PETABYTE_FACTOR (TERABYTE_FACTOR * KILOBYTE_FACTOR)
+#define EXABYTE_FACTOR  (PETABYTE_FACTOR * KILOBYTE_FACTOR)
 
 /**
  * g_format_size_for_display:
@@ -1767,19 +1800,34 @@ g_format_size_for_display (goffset size)
       
       if (size < (goffset) MEGABYTE_FACTOR)
        {
-         displayed_size = (gdouble) size / KILOBYTE_FACTOR;
+         displayed_size = (gdouble) size / (gdouble) KILOBYTE_FACTOR;
          return g_strdup_printf (_("%.1f KB"), displayed_size);
        }
       else if (size < (goffset) GIGABYTE_FACTOR)
        {
-         displayed_size = (gdouble) size / MEGABYTE_FACTOR;
+         displayed_size = (gdouble) size / (gdouble) MEGABYTE_FACTOR;
          return g_strdup_printf (_("%.1f MB"), displayed_size);
        }
-      else
+      else if (size < (goffset) TERABYTE_FACTOR)
        {
-         displayed_size = (gdouble) size / GIGABYTE_FACTOR;
+         displayed_size = (gdouble) size / (gdouble) GIGABYTE_FACTOR;
          return g_strdup_printf (_("%.1f GB"), displayed_size);
        }
+      else if (size < (goffset) PETABYTE_FACTOR)
+       {
+         displayed_size = (gdouble) size / (gdouble) TERABYTE_FACTOR;
+         return g_strdup_printf (_("%.1f TB"), displayed_size);
+       }
+      else if (size < (goffset) EXABYTE_FACTOR)
+       {
+         displayed_size = (gdouble) size / (gdouble) PETABYTE_FACTOR;
+         return g_strdup_printf (_("%.1f PB"), displayed_size);
+       }
+      else
+        {
+         displayed_size = (gdouble) size / (gdouble) EXABYTE_FACTOR;
+         return g_strdup_printf (_("%.1f EB"), displayed_size);
+        }
     }
 }
 
@@ -1989,6 +2037,3 @@ g_file_open_tmp (const gchar  *tmpl,
 }
 
 #endif
-
-#define __G_FILEUTILS_C__
-#include "galiasdef.c"