mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-04-11 10:13:07 +02:00
Save the errno in various places
Sat Apr 16 20:15:44 2005 Soeren Sandmann <sandmann@redhat.com> * glib/gfileutils.c (g_file_replace): Save the errno in various places * glib/gfileutils.c (set_umask_permissions): Fork a child and do chmod() to the umask() permissions there.
This commit is contained in:
parent
88c866246a
commit
da536e7e42
@ -1,3 +1,11 @@
|
|||||||
|
Sat Apr 16 20:15:44 2005 Soeren Sandmann <sandmann@redhat.com>
|
||||||
|
|
||||||
|
* glib/gfileutils.c (g_file_replace): Save the errno in various
|
||||||
|
places
|
||||||
|
|
||||||
|
* glib/gfileutils.c (set_umask_permissions): Fork a child and do
|
||||||
|
chmod() to the umask() permissions there.
|
||||||
|
|
||||||
2005-04-10 Matthias Clasen <mclasen@redhat.com>
|
2005-04-10 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
* glib/gmessages.h (g_debug): Use G_LOG_LEVEL_DEBUG in
|
* glib/gmessages.h (g_debug): Use G_LOG_LEVEL_DEBUG in
|
||||||
|
@ -1,3 +1,11 @@
|
|||||||
|
Sat Apr 16 20:15:44 2005 Soeren Sandmann <sandmann@redhat.com>
|
||||||
|
|
||||||
|
* glib/gfileutils.c (g_file_replace): Save the errno in various
|
||||||
|
places
|
||||||
|
|
||||||
|
* glib/gfileutils.c (set_umask_permissions): Fork a child and do
|
||||||
|
chmod() to the umask() permissions there.
|
||||||
|
|
||||||
2005-04-10 Matthias Clasen <mclasen@redhat.com>
|
2005-04-10 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
* glib/gmessages.h (g_debug): Use G_LOG_LEVEL_DEBUG in
|
* glib/gmessages.h (g_debug): Use G_LOG_LEVEL_DEBUG in
|
||||||
|
@ -1,3 +1,11 @@
|
|||||||
|
Sat Apr 16 20:15:44 2005 Soeren Sandmann <sandmann@redhat.com>
|
||||||
|
|
||||||
|
* glib/gfileutils.c (g_file_replace): Save the errno in various
|
||||||
|
places
|
||||||
|
|
||||||
|
* glib/gfileutils.c (set_umask_permissions): Fork a child and do
|
||||||
|
chmod() to the umask() permissions there.
|
||||||
|
|
||||||
2005-04-10 Matthias Clasen <mclasen@redhat.com>
|
2005-04-10 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
* glib/gmessages.h (g_debug): Use G_LOG_LEVEL_DEBUG in
|
* glib/gmessages.h (g_debug): Use G_LOG_LEVEL_DEBUG in
|
||||||
|
@ -1,3 +1,11 @@
|
|||||||
|
Sat Apr 16 20:15:44 2005 Soeren Sandmann <sandmann@redhat.com>
|
||||||
|
|
||||||
|
* glib/gfileutils.c (g_file_replace): Save the errno in various
|
||||||
|
places
|
||||||
|
|
||||||
|
* glib/gfileutils.c (set_umask_permissions): Fork a child and do
|
||||||
|
chmod() to the umask() permissions there.
|
||||||
|
|
||||||
2005-04-10 Matthias Clasen <mclasen@redhat.com>
|
2005-04-10 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
* glib/gmessages.h (g_debug): Use G_LOG_LEVEL_DEBUG in
|
* glib/gmessages.h (g_debug): Use G_LOG_LEVEL_DEBUG in
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
@ -816,7 +817,6 @@ g_file_get_contents (const gchar *filename,
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
rename_file (const char *old_name,
|
rename_file (const char *old_name,
|
||||||
const char *new_name,
|
const char *new_name,
|
||||||
@ -828,7 +828,7 @@ rename_file (const char *old_name,
|
|||||||
int save_errno = errno;
|
int save_errno = errno;
|
||||||
gchar *display_old_name = g_filename_display_name (old_name);
|
gchar *display_old_name = g_filename_display_name (old_name);
|
||||||
gchar *display_new_name = g_filename_display_name (new_name);
|
gchar *display_new_name = g_filename_display_name (new_name);
|
||||||
|
|
||||||
g_set_error (err,
|
g_set_error (err,
|
||||||
G_FILE_ERROR,
|
G_FILE_ERROR,
|
||||||
g_file_error_from_errno (save_errno),
|
g_file_error_from_errno (save_errno),
|
||||||
@ -846,6 +846,114 @@ rename_file (const char *old_name,
|
|||||||
return TRUE;
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int save_errno;
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
|
pid = fork ();
|
||||||
|
|
||||||
|
if (pid == -1)
|
||||||
|
{
|
||||||
|
save_errno = errno;
|
||||||
|
g_set_error (err,
|
||||||
|
G_FILE_ERROR,
|
||||||
|
g_file_error_from_errno (save_errno),
|
||||||
|
_("Could not change file mode: fork() failed: %s"),
|
||||||
|
g_strerror (save_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;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
if (waitpid (pid, &status, 0) == -1)
|
||||||
|
{
|
||||||
|
save_errno = errno;
|
||||||
|
|
||||||
|
g_set_error (err,
|
||||||
|
G_FILE_ERROR,
|
||||||
|
g_file_error_from_errno (save_errno),
|
||||||
|
_("Could not change file mode: waitpid() failed: %s"),
|
||||||
|
g_strerror (save_errno));
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WIFEXITED (status))
|
||||||
|
{
|
||||||
|
save_errno = WEXITSTATUS (status);
|
||||||
|
|
||||||
|
if (save_errno == 0)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_set_error (err,
|
||||||
|
G_FILE_ERROR,
|
||||||
|
g_file_error_from_errno (save_errno),
|
||||||
|
_("Could not change file mode: chmod() failed: %s"),
|
||||||
|
g_strerror (save_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 *
|
static gchar *
|
||||||
write_to_temp_file (const gchar *contents,
|
write_to_temp_file (const gchar *contents,
|
||||||
gssize length,
|
gssize length,
|
||||||
@ -865,11 +973,11 @@ write_to_temp_file (const gchar *contents,
|
|||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
fd = g_mkstemp (tmp_name);
|
fd = g_mkstemp (tmp_name);
|
||||||
save_errno = errno;
|
|
||||||
display_name = g_filename_display_name (tmp_name);
|
display_name = g_filename_display_name (tmp_name);
|
||||||
|
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
{
|
{
|
||||||
|
save_errno = errno;
|
||||||
g_set_error (err,
|
g_set_error (err,
|
||||||
G_FILE_ERROR,
|
G_FILE_ERROR,
|
||||||
g_file_error_from_errno (save_errno),
|
g_file_error_from_errno (save_errno),
|
||||||
@ -879,16 +987,25 @@ write_to_temp_file (const gchar *contents,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!set_umask_permissions (fd, err))
|
||||||
|
{
|
||||||
|
close (fd);
|
||||||
|
g_unlink (tmp_name);
|
||||||
|
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
file = fdopen (fd, "wb");
|
file = fdopen (fd, "wb");
|
||||||
if (!file)
|
if (!file)
|
||||||
{
|
{
|
||||||
|
save_errno = errno;
|
||||||
g_set_error (err,
|
g_set_error (err,
|
||||||
G_FILE_ERROR,
|
G_FILE_ERROR,
|
||||||
g_file_error_from_errno (errno),
|
g_file_error_from_errno (save_errno),
|
||||||
_("Failed to open file '%s' for writing: fdopen() failed: %s"),
|
_("Failed to open file '%s' for writing: fdopen() failed: %s"),
|
||||||
display_name,
|
display_name,
|
||||||
g_strerror (errno));
|
g_strerror (save_errno));
|
||||||
|
|
||||||
close (fd);
|
close (fd);
|
||||||
g_unlink (tmp_name);
|
g_unlink (tmp_name);
|
||||||
@ -903,15 +1020,17 @@ write_to_temp_file (const gchar *contents,
|
|||||||
errno = 0;
|
errno = 0;
|
||||||
|
|
||||||
n_written = fwrite (contents, 1, length, file);
|
n_written = fwrite (contents, 1, length, file);
|
||||||
|
|
||||||
if (n_written < length)
|
if (n_written < length)
|
||||||
{
|
{
|
||||||
|
save_errno = errno;
|
||||||
|
|
||||||
g_set_error (err,
|
g_set_error (err,
|
||||||
G_FILE_ERROR,
|
G_FILE_ERROR,
|
||||||
g_file_error_from_errno (errno),
|
g_file_error_from_errno (save_errno),
|
||||||
_("Failed to write file '%s': fwrite() failed: %s"),
|
_("Failed to write file '%s': fwrite() failed: %s"),
|
||||||
display_name,
|
display_name,
|
||||||
g_strerror (errno));
|
g_strerror (save_errno));
|
||||||
|
|
||||||
fclose (file);
|
fclose (file);
|
||||||
g_unlink (tmp_name);
|
g_unlink (tmp_name);
|
||||||
@ -922,21 +1041,23 @@ write_to_temp_file (const gchar *contents,
|
|||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
if (fclose (file) == EOF)
|
if (fclose (file) == EOF)
|
||||||
{
|
{
|
||||||
|
save_errno = 0;
|
||||||
|
|
||||||
g_set_error (err,
|
g_set_error (err,
|
||||||
G_FILE_ERROR,
|
G_FILE_ERROR,
|
||||||
g_file_error_from_errno (errno),
|
g_file_error_from_errno (save_errno),
|
||||||
_("Failed to close file '%s': fclose() failed: %s"),
|
_("Failed to close file '%s': fclose() failed: %s"),
|
||||||
display_name,
|
display_name,
|
||||||
g_strerror (errno));
|
g_strerror (save_errno));
|
||||||
|
|
||||||
g_unlink (tmp_name);
|
g_unlink (tmp_name);
|
||||||
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = g_strdup (tmp_name);
|
|
||||||
|
|
||||||
|
retval = g_strdup (tmp_name);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
g_free (tmp_name);
|
g_free (tmp_name);
|
||||||
g_free (display_name);
|
g_free (display_name);
|
||||||
@ -1039,12 +1160,14 @@ g_file_replace (const gchar *filename,
|
|||||||
{
|
{
|
||||||
gchar *display_filename = g_filename_display_name (filename);
|
gchar *display_filename = g_filename_display_name (filename);
|
||||||
|
|
||||||
|
save_errno = errno;
|
||||||
|
|
||||||
g_set_error (error,
|
g_set_error (error,
|
||||||
G_FILE_ERROR,
|
G_FILE_ERROR,
|
||||||
g_file_error_from_errno (errno),
|
g_file_error_from_errno (save_errno),
|
||||||
_("Existing file '%s' could not be removed: g_unlink() failed: %s"),
|
_("Existing file '%s' could not be removed: g_unlink() failed: %s"),
|
||||||
display_filename,
|
display_filename,
|
||||||
g_strerror (errno));
|
g_strerror (save_errno));
|
||||||
|
|
||||||
g_free (display_filename);
|
g_free (display_filename);
|
||||||
g_unlink (tmp_filename);
|
g_unlink (tmp_filename);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user