* library function.
* @G_FILE_ERROR_PIPE: Broken pipe; there is no process reading from the
* other end of a pipe. Every library function that returns this
- * error code also generates a `SIGPIPE' signal; this signal
+ * error code also generates a 'SIGPIPE' signal; this signal
* terminates the program if not handled or blocked. Thus, your
* program will never actually see this code unless it has handled
- * or blocked `SIGPIPE'.
+ * or blocked 'SIGPIPE'.
* @G_FILE_ERROR_AGAIN: Resource temporarily unavailable; the call might
* work if you try again later.
* @G_FILE_ERROR_INTR: Interrupted function call; an asynchronous signal
#ifdef EEXIST
case EEXIST:
return G_FILE_ERROR_EXIST;
- break;
#endif
#ifdef EISDIR
case EISDIR:
return G_FILE_ERROR_ISDIR;
- break;
#endif
#ifdef EACCES
case EACCES:
return G_FILE_ERROR_ACCES;
- break;
#endif
#ifdef ENAMETOOLONG
case ENAMETOOLONG:
return G_FILE_ERROR_NAMETOOLONG;
- break;
#endif
#ifdef ENOENT
case ENOENT:
return G_FILE_ERROR_NOENT;
- break;
#endif
#ifdef ENOTDIR
case ENOTDIR:
return G_FILE_ERROR_NOTDIR;
- break;
#endif
#ifdef ENXIO
case ENXIO:
return G_FILE_ERROR_NXIO;
- break;
#endif
#ifdef ENODEV
case ENODEV:
return G_FILE_ERROR_NODEV;
- break;
#endif
#ifdef EROFS
case EROFS:
return G_FILE_ERROR_ROFS;
- break;
#endif
#ifdef ETXTBSY
case ETXTBSY:
return G_FILE_ERROR_TXTBSY;
- break;
#endif
#ifdef EFAULT
case EFAULT:
return G_FILE_ERROR_FAULT;
- break;
#endif
#ifdef ELOOP
case ELOOP:
return G_FILE_ERROR_LOOP;
- break;
#endif
#ifdef ENOSPC
case ENOSPC:
return G_FILE_ERROR_NOSPC;
- break;
#endif
#ifdef ENOMEM
case ENOMEM:
return G_FILE_ERROR_NOMEM;
- break;
#endif
#ifdef EMFILE
case EMFILE:
return G_FILE_ERROR_MFILE;
- break;
#endif
#ifdef ENFILE
case ENFILE:
return G_FILE_ERROR_NFILE;
- break;
#endif
#ifdef EBADF
case EBADF:
return G_FILE_ERROR_BADF;
- break;
#endif
#ifdef EINVAL
case EINVAL:
return G_FILE_ERROR_INVAL;
- break;
#endif
#ifdef EPIPE
case EPIPE:
return G_FILE_ERROR_PIPE;
- break;
#endif
#ifdef EAGAIN
case EAGAIN:
return G_FILE_ERROR_AGAIN;
- break;
#endif
#ifdef EINTR
case EINTR:
return G_FILE_ERROR_INTR;
- break;
#endif
#ifdef EIO
case EIO:
return G_FILE_ERROR_IO;
- break;
#endif
#ifdef EPERM
case EPERM:
return G_FILE_ERROR_PERM;
- break;
#endif
#ifdef ENOSYS
case ENOSYS:
return G_FILE_ERROR_NOSYS;
- break;
#endif
default:
return G_FILE_ERROR_FAILED;
- break;
}
}
g_set_error (error,
G_FILE_ERROR,
G_FILE_ERROR_NOMEM,
- g_dngettext (GETTEXT_PACKAGE, "Could not allocate %ld byte to read file \"%s\"", "Could not allocate %lu bytes to read file \"%s\"", (gulong)total_allocated),
+ g_dngettext (GETTEXT_PACKAGE, "Could not allocate %lu byte to read file \"%s\"", "Could not allocate %lu bytes to read file \"%s\"", (gulong)total_allocated),
(gulong) total_allocated,
display_filename);
g_set_error (error,
G_FILE_ERROR,
G_FILE_ERROR_NOMEM,
- g_dngettext (GETTEXT_PACKAGE, "Could not allocate %ld byte to read file \"%s\"", "Could not allocate %lu bytes to read file \"%s\"", (gulong)alloc_size),
+ g_dngettext (GETTEXT_PACKAGE, "Could not allocate %lu byte to read file \"%s\"", "Could not allocate %lu bytes to read file \"%s\"", (gulong)alloc_size),
(gulong) alloc_size,
display_filename);
return TRUE;
}
+static char *
+format_error_message (const gchar *filename,
+ const gchar *format_string) G_GNUC_FORMAT(2);
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+
+static char *
+format_error_message (const gchar *filename,
+ const gchar *format_string)
+{
+ gint saved_errno = errno;
+ gchar *display_name;
+ gchar *msg;
+
+ display_name = g_filename_display_name (filename);
+ msg = g_strdup_printf (format_string, display_name, g_strerror (saved_errno));
+ g_free (display_name);
+
+ return msg;
+}
+
+#pragma GCC diagnostic pop
+
+/* format string must have two '%s':
+ *
+ * - the place for the filename
+ * - the place for the strerror
+ */
+static void
+set_file_error (GError **error,
+ const gchar *filename,
+ const gchar *format_string)
+
+{
+ int saved_errno = errno;
+ char *msg = format_error_message (filename, format_string);
+
+ g_set_error_literal (error, G_FILE_ERROR, g_file_error_from_errno (saved_errno),
+ msg);
+ g_free (msg);
+}
+
static gchar *
write_to_temp_file (const gchar *contents,
gssize length,
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", dest_file);
errno = 0;
fd = g_mkstemp_full (tmp_name, O_RDWR | O_BINARY, 0666);
- 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));
-
+ set_file_error (err, tmp_name, _("Failed to create file '%s': %s"));
goto out;
}
- errno = 0;
- file = fdopen (fd, "wb");
- if (!file)
+#ifdef HAVE_FALLOCATE
+ if (length > 0)
{
- save_errno = errno;
- g_set_error (err,
- G_FILE_ERROR,
- g_file_error_from_errno (save_errno),
- _("Failed to open file '%s' for writing: fdopen() failed: %s"),
- display_name,
- g_strerror (save_errno));
-
- close (fd);
- g_unlink (tmp_name);
-
- goto out;
+ /* We do this on a 'best effort' basis... It may not be supported
+ * on the underlying filesystem.
+ */
+ (void) fallocate (fd, 0, 0, length);
}
-
- if (length > 0)
+#endif
+ while (length > 0)
{
- gsize n_written;
-
- errno = 0;
+ gssize s;
- n_written = fwrite (contents, 1, length, file);
+ s = write (fd, contents, length);
- if (n_written < length)
- {
- save_errno = errno;
-
- g_set_error (err,
- G_FILE_ERROR,
- g_file_error_from_errno (save_errno),
- _("Failed to write file '%s': fwrite() failed: %s"),
- display_name,
- g_strerror (save_errno));
+ if (s < 0)
+ {
+ if (errno == EINTR)
+ continue;
- fclose (file);
- g_unlink (tmp_name);
-
- goto out;
- }
- }
+ set_file_error (err, tmp_name, _("Failed to write file '%s': write() failed: %s"));
+ close (fd);
+ g_unlink (tmp_name);
- errno = 0;
- if (fflush (file) != 0)
- {
- save_errno = errno;
-
- g_set_error (err,
- G_FILE_ERROR,
- g_file_error_from_errno (save_errno),
- _("Failed to write file '%s': fflush() failed: %s"),
- display_name,
- g_strerror (save_errno));
+ goto out;
+ }
- fclose (file);
- g_unlink (tmp_name);
-
- goto out;
+ g_assert (s <= length);
+
+ contents += s;
+ length -= s;
}
#ifdef BTRFS_SUPER_MAGIC
goto no_fsync;
}
#endif
-
+
#ifdef HAVE_FSYNC
{
struct stat statbuf;
* the new and the old file on some filesystems. (I.E. those that don't
* guarantee the data is written to the disk before the metadata.)
*/
- if (g_lstat (dest_file, &statbuf) == 0 &&
- statbuf.st_size > 0 &&
- fsync (fileno (file)) != 0)
+ if (g_lstat (dest_file, &statbuf) == 0 && statbuf.st_size > 0 && fsync (fd) != 0)
{
- save_errno = errno;
-
- g_set_error (err,
- G_FILE_ERROR,
- g_file_error_from_errno (save_errno),
- _("Failed to write file '%s': fsync() failed: %s"),
- display_name,
- g_strerror (save_errno));
+ set_file_error (err, tmp_name, _("Failed to write file '%s': fsync() failed: %s"));
+ close (fd);
+ g_unlink (tmp_name);
- fclose (file);
- g_unlink (tmp_name);
-
- goto out;
+ goto out;
}
}
#endif
#ifdef BTRFS_SUPER_MAGIC
no_fsync:
#endif
-
- errno = 0;
- if (fclose (file) == EOF)
- {
- save_errno = errno;
-
- g_set_error (err,
- G_FILE_ERROR,
- g_file_error_from_errno (save_errno),
- _("Failed to close file '%s': fclose() failed: %s"),
- display_name,
- g_strerror (save_errno));
+ errno = 0;
+ if (!g_close (fd, err))
+ {
g_unlink (tmp_name);
-
+
goto out;
}
retval = g_strdup (tmp_name);
-
+
out:
g_free (tmp_name);
- g_free (display_name);
-
+
return retval;
}
if (max_len == 0)
max_len = (G_PATH_LENGTH == -1) ? 2048 : G_PATH_LENGTH;
- /* We don't use getcwd(3) on SUNOS, because, it does a popen("pwd")
- * and, if that wasn't bad enough, hangs in doing so.
- */
-#if (defined (sun) && !defined (__SVR4)) || !defined(HAVE_GETCWD)
+#if !defined(HAVE_GETCWD)
buffer = g_new (gchar, max_len + 1);
*buffer = 0;
dir = getwd (buffer);