*/
#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"
-
-static gint create_temp_file (gchar *tmpl,
- int permissions);
+#ifdef HAVE_LINUX_MAGIC_H /* for btrfs check */
+#include <linux/magic.h>
+#include <sys/vfs.h>
+#endif
/**
* g_mkdir_with_parents:
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 ||
pathext = g_getenv ("PATHEXT");
if (pathext == NULL)
- return FALSE;
+ break;
pathext = g_utf8_casefold (pathext, -1);
g_free ((gchar *) pathext);
g_free ((gchar *) lastdot);
- return FALSE;
+ break;
}
return FALSE;
tmp_name = g_strdup_printf ("%s.XXXXXX", dest_file);
errno = 0;
- fd = create_temp_file (tmp_name, 0666);
+ fd = g_mkstemp_full (tmp_name, O_RDWR | O_BINARY, 0666);
save_errno = errno;
display_name = g_filename_display_name (tmp_name);
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
{
}
}
#endif
+ no_fsync:
errno = 0;
if (fclose (file) == EOF)
* 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
return retval;
}
+/**
+ * g_mkstemp_full:
+ * @tmpl: template filename
+ * @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.
+ *
+ * The parameter is a string that should follow the rules for
+ * 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
+ * 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,
+ * 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.
+ *
+ * Since: 2.22
+ */
/*
- * create_temp_file based on the mkstemp implementation from the GNU C library.
+ * 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.
*/
-static gint
-create_temp_file (gchar *tmpl,
- int permissions)
+gint
+g_mkstemp_full (gchar *tmpl,
+ int flags,
+ int mode)
{
char *XXXXXX;
int count, fd;
GTimeVal tv;
static int counter = 0;
+ g_return_val_if_fail (tmpl != NULL, -1);
+
+
/* find the last occurrence of "XXXXXX" */
XXXXXX = g_strrstr (tmpl, "XXXXXX");
XXXXXX[5] = letters[v % NLETTERS];
/* tmpl is in UTF-8 on Windows, thus use g_open() */
- fd = g_open (tmpl, O_RDWR | O_CREAT | O_EXCL | O_BINARY, permissions);
+ fd = g_open (tmpl, flags | O_CREAT | O_EXCL, mode);
if (fd >= 0)
return fd;
gint
g_mkstemp (gchar *tmpl)
{
- return create_temp_file (tmpl, 0600);
+ return g_mkstemp_full (tmpl, O_RDWR | O_BINARY, 0600);
}
/**
if (separator_len)
{
- while (start &&
- strncmp (start, separator, separator_len) == 0)
+ while (strncmp (start, separator, separator_len) == 0)
start += separator_len;
}
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:
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);
+ }
}
}
}
#endif
-
-#define __G_FILEUTILS_C__
-#include "galiasdef.c"