Consistently save errno immediately after the operation setting it

Prevent the situation where errno is set by function A, then function B
is called (which is typically _(), but could be anything else) and it
overwrites errno, then errno is checked by the caller.

errno is a horrific API, and we need to be careful to save its value as
soon as a function call (which might set it) returns. i.e. Follow the
pattern:
  int errsv, ret;
  ret = some_call_which_might_set_errno ();
  errsv = errno;

  if (ret < 0)
    puts (strerror (errsv));

This patch implements that pattern throughout GLib. There might be a few
places in the test code which still use errno directly. They should be
ported as necessary. It doesn’t modify all the call sites like this:
  if (some_call_which_might_set_errno () && errno == ESOMETHING)
since the refactoring involved is probably more harmful than beneficial
there. It does, however, refactor other call sites regardless of whether
they were originally buggy.

https://bugzilla.gnome.org/show_bug.cgi?id=785577
This commit is contained in:
Philip Withnall
2017-07-31 11:30:55 +01:00
parent 41a4a70b43
commit 5cddde1fb2
44 changed files with 337 additions and 166 deletions

View File

@@ -255,12 +255,13 @@ ensure_keyring_directory (GError **error)
struct stat statbuf;
if (stat (path, &statbuf) != 0)
{
int errsv = errno;
g_set_error (error,
G_IO_ERROR,
g_io_error_from_errno (errno),
g_io_error_from_errno (errsv),
_("Error when getting information for directory “%s”: %s"),
path,
g_strerror (errno));
g_strerror (errsv));
g_free (path);
path = NULL;
goto out;
@@ -288,12 +289,13 @@ ensure_keyring_directory (GError **error)
if (g_mkdir (path, 0700) != 0)
{
int errsv = errno;
g_set_error (error,
G_IO_ERROR,
g_io_error_from_errno (errno),
g_io_error_from_errno (errsv),
_("Error creating directory “%s”: %s"),
path,
g_strerror (errno));
g_strerror (errsv));
g_free (path);
path = NULL;
goto out;
@@ -489,6 +491,7 @@ keyring_acquire_lock (const gchar *path,
gint ret;
guint num_tries;
guint num_create_tries;
int errsv;
g_return_val_if_fail (path != NULL, FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
@@ -526,12 +529,13 @@ keyring_acquire_lock (const gchar *path,
*/
if (g_unlink (lock) != 0)
{
errsv = errno;
g_set_error (error,
G_IO_ERROR,
g_io_error_from_errno (errno),
g_io_error_from_errno (errsv),
_("Error deleting stale lock file “%s”: %s"),
lock,
g_strerror (errno));
g_strerror (errsv));
goto out;
}
_log ("Deleted stale lock file '%s'", lock);
@@ -546,11 +550,12 @@ keyring_acquire_lock (const gchar *path,
0,
#endif
0700);
errsv = errno;
if (ret == -1)
{
#ifdef EEXISTS
/* EEXIST: pathname already exists and O_CREAT and O_EXCL were used. */
if (errno == EEXISTS)
if (errsv == EEXISTS)
{
num_create_tries++;
if (num_create_tries < 5)
@@ -560,10 +565,10 @@ keyring_acquire_lock (const gchar *path,
num_create_tries = num_create_tries; /* To avoid -Wunused-but-set-variable */
g_set_error (error,
G_IO_ERROR,
g_io_error_from_errno (errno),
g_io_error_from_errno (errsv),
_("Error creating lock file “%s”: %s"),
lock,
g_strerror (errno));
g_strerror (errsv));
goto out;
}
@@ -588,22 +593,24 @@ keyring_release_lock (const gchar *path,
lock = g_strdup_printf ("%s.lock", path);
if (close (lock_fd) != 0)
{
int errsv = errno;
g_set_error (error,
G_IO_ERROR,
g_io_error_from_errno (errno),
g_io_error_from_errno (errsv),
_("Error closing (unlinked) lock file “%s”: %s"),
lock,
g_strerror (errno));
g_strerror (errsv));
goto out;
}
if (g_unlink (lock) != 0)
{
int errsv = errno;
g_set_error (error,
G_IO_ERROR,
g_io_error_from_errno (errno),
g_io_error_from_errno (errsv),
_("Error unlinking lock file “%s”: %s"),
lock,
g_strerror (errno));
g_strerror (errsv));
goto out;
}