[glib] Consistently save errno immediately after the operation setting it



commit 5cddde1fb2b8466d8104595008eafabd0728de5d
Author: Philip Withnall <withnall endlessm com>
Date:   Mon Jul 31 11:30:55 2017 +0100

    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

 gio/gcharsetconverter.c               |    4 ++-
 gio/gdbusaddress.c                    |    7 +++-
 gio/gdbusauthmechanismsha1.c          |   33 ++++++++++++++---------
 gio/gdbusmessage.c                    |    3 +-
 gio/gdbusserver.c                     |    9 ++++--
 gio/gdocumentportal.c                 |    5 ++-
 gio/gfile.c                           |    7 +++--
 gio/gio-querymodules.c                |    5 +++-
 gio/gio-tool-cat.c                    |    5 +++-
 gio/glocalfile.c                      |   26 +++++++++++++-----
 gio/glocalfileinfo.c                  |   23 ++++++++++++----
 gio/glocalfileoutputstream.c          |   16 ++++++-----
 gio/gnetworkmonitornetlink.c          |    6 ++--
 gio/gopenuriportal.c                  |   10 ++++---
 gio/gsocket.c                         |    9 ++++--
 gio/gsubprocess.c                     |   46 +++++++++++++++++++++++---------
 gio/gtestdbus.c                       |    7 +++-
 gio/gunixconnection.c                 |   15 ++++++----
 gio/gunixfdmessage.c                  |   11 +++++--
 gio/gunixinputstream.c                |   11 +++++---
 gio/gunixoutputstream.c               |   14 +++++----
 gio/inotify/inotify-kernel.c          |   12 +++++---
 gio/tests/dbus-launch.c               |    5 ++-
 gio/tests/gdbus-peer-object-manager.c |    5 ++-
 gio/tests/gdbus-peer.c                |    9 ++++--
 gio/tests/gdbus-unix-addresses.c      |   15 ++++++++--
 gio/tests/gsubprocess-testprog.c      |    3 +-
 glib/gerror.c                         |    4 ++-
 glib/giowin32.c                       |   42 ++++++++++++++++++-----------
 glib/gkeyfile.c                       |   24 +++++++++++-----
 glib/gmain.c                          |   10 +++++--
 glib/gslice.c                         |    4 ++-
 glib/gtester.c                        |    4 ++-
 glib/gtestutils.c                     |   19 ++++++++++---
 glib/gutils.c                         |    4 ++-
 glib/tests/fileutils.c                |    5 +++-
 glib/tests/protocol.c                 |    6 +++-
 tests/gobject/timeloop-closure.c      |    8 +++--
 tests/mainloop-test.c                 |    3 +-
 tests/spawn-test-win32-gui.c          |    9 ++++--
 tests/spawn-test.c                    |   15 +++++++---
 tests/testglib.c                      |    7 +++-
 tests/timeloop-basic.c                |    8 +++--
 tests/timeloop.c                      |    8 +++--
 44 files changed, 336 insertions(+), 165 deletions(-)
---
diff --git a/gio/gcharsetconverter.c b/gio/gcharsetconverter.c
index 26aa454..d529cbc 100644
--- a/gio/gcharsetconverter.c
+++ b/gio/gcharsetconverter.c
@@ -433,6 +433,7 @@ g_charset_converter_initable_init (GInitable     *initable,
                                   GError       **error)
 {
   GCharsetConverter  *conv;
+  int errsv;
 
   g_return_val_if_fail (G_IS_CHARSET_CONVERTER (initable), FALSE);
 
@@ -446,10 +447,11 @@ g_charset_converter_initable_init (GInitable     *initable,
     }
 
   conv->iconv = g_iconv_open (conv->to, conv->from);
+  errsv = errno;
 
   if (conv->iconv == (GIConv)-1)
     {
-      if (errno == EINVAL)
+      if (errsv == EINVAL)
        g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
                     _("Conversion from character set “%s” to “%s” is not supported"),
                     conv->from, conv->to);
diff --git a/gio/gdbusaddress.c b/gio/gdbusaddress.c
index f4fb41d..6fb3d2a 100644
--- a/gio/gdbusaddress.c
+++ b/gio/gdbusaddress.c
@@ -691,9 +691,11 @@ g_dbus_address_connect (const gchar   *address_entry,
           gchar nonce_contents[16 + 1];
           size_t num_bytes_read;
           FILE *f;
+          int errsv;
 
           /* be careful to read only 16 bytes - we also check that the file is only 16 bytes long */
           f = fopen (nonce_file, "rb");
+          errsv = errno;
           if (f == NULL)
             {
               g_set_error (error,
@@ -701,7 +703,7 @@ g_dbus_address_connect (const gchar   *address_entry,
                            G_IO_ERROR_INVALID_ARGUMENT,
                            _("Error opening nonce file “%s”: %s"),
                            nonce_file,
-                           g_strerror (errno));
+                           g_strerror (errsv));
               g_object_unref (ret);
               ret = NULL;
               goto out;
@@ -710,6 +712,7 @@ g_dbus_address_connect (const gchar   *address_entry,
                                   sizeof (gchar),
                                   16 + 1,
                                   f);
+          errsv = errno;
           if (num_bytes_read != 16)
             {
               if (num_bytes_read == 0)
@@ -719,7 +722,7 @@ g_dbus_address_connect (const gchar   *address_entry,
                                G_IO_ERROR_INVALID_ARGUMENT,
                                _("Error reading from nonce file “%s”: %s"),
                                nonce_file,
-                               g_strerror (errno));
+                               g_strerror (errsv));
                 }
               else
                 {
diff --git a/gio/gdbusauthmechanismsha1.c b/gio/gdbusauthmechanismsha1.c
index 0b17b90..a51430c 100644
--- a/gio/gdbusauthmechanismsha1.c
+++ b/gio/gdbusauthmechanismsha1.c
@@ -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;
     }
 
diff --git a/gio/gdbusmessage.c b/gio/gdbusmessage.c
index 9158858..e80794f 100644
--- a/gio/gdbusmessage.c
+++ b/gio/gdbusmessage.c
@@ -3504,7 +3504,8 @@ g_dbus_message_print (GDBusMessage *message,
                 }
               else
                 {
-                  g_string_append_printf (fs, "(fstat failed: %s)", g_strerror (errno));
+                  int errsv = errno;
+                  g_string_append_printf (fs, "(fstat failed: %s)", g_strerror (errsv));
                 }
               g_string_append_printf (str, "%*s  fd %d: %s\n", indent, "", fds[n], fs->str);
               g_string_free (fs, TRUE);
diff --git a/gio/gdbusserver.c b/gio/gdbusserver.c
index 20df4e2..07757f4 100644
--- a/gio/gdbusserver.c
+++ b/gio/gdbusserver.c
@@ -862,17 +862,20 @@ try_tcp (GDBusServer  *server,
       while (bytes_remaining > 0)
         {
           gssize ret;
+          int errsv;
+
           ret = write (fd, server->nonce + bytes_written, bytes_remaining);
+          errsv = errno;
           if (ret == -1)
             {
-              if (errno == EINTR)
+              if (errsv == EINTR)
                 goto again;
               g_set_error (error,
                            G_IO_ERROR,
-                           g_io_error_from_errno (errno),
+                           g_io_error_from_errno (errsv),
                            _("Error writing nonce file at “%s”: %s"),
                            server->nonce_file,
-                           g_strerror (errno));
+                           g_strerror (errsv));
               goto out;
             }
           bytes_written += ret;
diff --git a/gio/gdocumentportal.c b/gio/gdocumentportal.c
index e5d61ab..3e85bd2 100644
--- a/gio/gdocumentportal.c
+++ b/gio/gdocumentportal.c
@@ -101,7 +101,7 @@ g_document_portal_add_document (GFile   *file,
   char *doc_uri = NULL;
   char *path = NULL;
   GUnixFDList *fd_list = NULL;
-  int fd, fd_in;
+  int fd, fd_in, errsv;
   gboolean ret;
 
   if (!init_document_portal ())
@@ -113,10 +113,11 @@ g_document_portal_add_document (GFile   *file,
 
   path = g_file_get_path (file);
   fd = g_open (path, O_PATH | O_CLOEXEC);
+  errsv = errno;
 
   if (fd == -1)
     {
-      g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
+      g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
                    "Failed to open %s", path);
       goto out;
     }
diff --git a/gio/gfile.c b/gio/gfile.c
index dd518df..9967b73 100644
--- a/gio/gfile.c
+++ b/gio/gfile.c
@@ -3000,7 +3000,7 @@ btrfs_reflink_with_progress (GInputStream           *in,
 {
   goffset source_size;
   int fd_in, fd_out;
-  int ret;
+  int ret, errsv;
 
   fd_in = g_file_descriptor_based_get_fd (G_FILE_DESCRIPTOR_BASED (in));
   fd_out = g_file_descriptor_based_get_fd (G_FILE_DESCRIPTOR_BASED (out));
@@ -3015,14 +3015,15 @@ btrfs_reflink_with_progress (GInputStream           *in,
    *
    * By the time we get here, *in and *out are both regular files */
   ret = ioctl (fd_out, BTRFS_IOC_CLONE, fd_in);
+  errsv = errno;
 
   if (ret < 0)
     {
-      if (errno == EXDEV)
+      if (errsv == EXDEV)
        g_set_error_literal (error, G_IO_ERROR,
                             G_IO_ERROR_NOT_SUPPORTED,
                             _("Copy (reflink/clone) between mounts is not supported"));
-      else if (errno == EINVAL)
+      else if (errsv == EINVAL)
        g_set_error_literal (error, G_IO_ERROR,
                             G_IO_ERROR_NOT_SUPPORTED,
                             _("Copy (reflink/clone) is not supported or invalid"));
diff --git a/gio/gio-querymodules.c b/gio/gio-querymodules.c
index 5d488bc..667336a 100644
--- a/gio/gio-querymodules.c
+++ b/gio/gio-querymodules.c
@@ -116,7 +116,10 @@ query_dir (const char *dirname)
   else
     {
       if (g_unlink (cachename) != 0 && errno != ENOENT)
-        g_printerr ("Unable to unlink %s: %s\n", cachename, g_strerror (errno));
+        {
+          int errsv = errno;
+          g_printerr ("Unable to unlink %s: %s\n", cachename, g_strerror (errsv));
+        }
     }
 
   g_free (cachename);
diff --git a/gio/gio-tool-cat.c b/gio/gio-tool-cat.c
index dcf869c..1e40188 100644
--- a/gio/gio-tool-cat.c
+++ b/gio/gio-tool-cat.c
@@ -73,9 +73,12 @@ cat (GFile *file)
           p = buffer;
           while (res > 0)
             {
+              int errsv;
+
               written = write (STDOUT_FILENO, p, res);
+              errsv = errno;
 
-              if (written == -1 && errno != EINTR)
+              if (written == -1 && errsv != EINTR)
                 {
                   print_file_error (file, _("Error writing to stdout"));
                   success = FALSE;
diff --git a/gio/glocalfile.c b/gio/glocalfile.c
index 002c151..d417c49 100644
--- a/gio/glocalfile.c
+++ b/gio/glocalfile.c
@@ -1918,10 +1918,11 @@ g_local_file_trash (GFile         *file,
   char *dirname, *globaldir;
   GVfsClass *class;
   GVfs *vfs;
+  int errsv;
 
   if (g_lstat (local->filename, &file_stat) != 0)
     {
-      int errsv = errno;
+      errsv = errno;
 
       g_set_io_error (error,
                      _("Error trashing file %s: %s"),
@@ -1942,7 +1943,7 @@ g_local_file_trash (GFile         *file,
       if (g_mkdir_with_parents (trashdir, 0700) < 0)
        {
           char *display_name;
-          int errsv = errno;
+          errsv = errno;
 
           display_name = g_filename_display_name (trashdir);
           g_set_error (error, G_IO_ERROR,
@@ -2085,14 +2086,15 @@ g_local_file_trash (GFile         *file,
     g_free (infoname);
 
     fd = g_open (infofile, O_CREAT | O_EXCL, 0666);
-  } while (fd == -1 && errno == EEXIST);
+    errsv = errno;
+  } while (fd == -1 && errsv == EEXIST);
 
   g_free (basename);
   g_free (infodir);
 
   if (fd == -1)
     {
-      int errsv = errno;
+      errsv = errno;
 
       g_free (filesdir);
       g_free (topdir);
@@ -2145,7 +2147,7 @@ g_local_file_trash (GFile         *file,
 
   if (g_rename (local->filename, trashfile) == -1)
     {
-      int errsv = errno;
+      errsv = errno;
 
       g_unlink (infofile);
 
@@ -2665,10 +2667,16 @@ g_local_file_measure_size_of_file (gint           parent_fd,
 
 #if defined (AT_FDCWD)
   if (fstatat (parent_fd, name->data, &buf, AT_SYMLINK_NOFOLLOW) != 0)
-    return g_local_file_measure_size_error (state->flags, errno, name, error);
+    {
+      int errsv = errno;
+      return g_local_file_measure_size_error (state->flags, errsv, name, error);
+    }
 #elif defined (HAVE_LSTAT) || !defined (G_OS_WIN32)
   if (g_lstat (name->data, &buf) != 0)
-    return g_local_file_measure_size_error (state->flags, errno, name, error);
+    {
+      int errsv = errno;
+      return g_local_file_measure_size_error (state->flags, errsv, name, error);
+    }
 #else
   {
     const char *filename = (const gchar *) name->data;
@@ -2759,6 +2767,7 @@ g_local_file_measure_size_of_file (gint           parent_fd,
   if (S_ISDIR (buf.st_mode))
     {
       int dir_fd = -1;
+      int errsv;
 
       if (g_cancellable_set_error_if_cancelled (state->cancellable, error))
         return FALSE;
@@ -2769,8 +2778,9 @@ g_local_file_measure_size_of_file (gint           parent_fd,
 #else
       dir_fd = openat (parent_fd, name->data, O_RDONLY);
 #endif
+      errsv = errno;
       if (dir_fd < 0)
-        return g_local_file_measure_size_error (state->flags, errno, name, error);
+        return g_local_file_measure_size_error (state->flags, errsv, name, error);
 #endif
 
       if (!g_local_file_measure_size_of_contents (dir_fd, name, state, error))
diff --git a/gio/glocalfileinfo.c b/gio/glocalfileinfo.c
index eb364ac..1c97eef 100644
--- a/gio/glocalfileinfo.c
+++ b/gio/glocalfileinfo.c
@@ -401,13 +401,15 @@ get_one_xattr (const char *path,
   char value[64];
   char *value_p;
   ssize_t len;
+  int errsv;
 
   len = g_getxattr (path, xattr, value, sizeof (value)-1, follow_symlinks);
+  errsv = errno;
 
   value_p = NULL;
   if (len >= 0)
     value_p = value;
-  else if (len == -1 && errno == ERANGE)
+  else if (len == -1 && errsv == ERANGE)
     {
       len = g_getxattr (path, xattr, NULL, 0, follow_symlinks);
 
@@ -460,6 +462,8 @@ get_xattrs (const char            *path,
 
   if (all)
     {
+      int errsv;
+
       list_res_size = g_listxattr (path, NULL, 0, follow_symlinks);
 
       if (list_res_size == -1 ||
@@ -472,8 +476,9 @@ get_xattrs (const char            *path,
     retry:
       
       list_res_size = g_listxattr (path, list, list_size, follow_symlinks);
+      errsv = errno;
       
-      if (list_res_size == -1 && errno == ERANGE)
+      if (list_res_size == -1 && errsv == ERANGE)
        {
          list_size = list_size * 2;
          list = g_realloc (list, list_size);
@@ -558,13 +563,15 @@ get_one_xattr_from_fd (int         fd,
   char value[64];
   char *value_p;
   ssize_t len;
+  int errsv;
 
   len = g_fgetxattr (fd, xattr, value, sizeof (value) - 1);
+  errsv = errno;
 
   value_p = NULL;
   if (len >= 0)
     value_p = value;
-  else if (len == -1 && errno == ERANGE)
+  else if (len == -1 && errsv == ERANGE)
     {
       len = g_fgetxattr (fd, xattr, NULL, 0);
 
@@ -615,6 +622,8 @@ get_xattrs_from_fd (int                    fd,
 
   if (all)
     {
+      int errsv;
+
       list_res_size = g_flistxattr (fd, NULL, 0);
 
       if (list_res_size == -1 ||
@@ -627,8 +636,9 @@ get_xattrs_from_fd (int                    fd,
     retry:
       
       list_res_size = g_flistxattr (fd, list, list_size);
+      errsv = errno;
       
-      if (list_res_size == -1 && errno == ERANGE)
+      if (list_res_size == -1 && errsv == ERANGE)
        {
          list_size = list_size * 2;
          list = g_realloc (list, list_size);
@@ -1264,7 +1274,7 @@ get_content_type (const char          *basename,
        {
          guchar sniff_buffer[4096];
          gsize sniff_length;
-         int fd;
+         int fd, errsv;
 
          sniff_length = _g_unix_content_type_get_sniff_len ();
          if (sniff_length > 4096)
@@ -1272,7 +1282,8 @@ get_content_type (const char          *basename,
 
 #ifdef O_NOATIME         
           fd = g_open (path, O_RDONLY | O_NOATIME, 0);
-          if (fd < 0 && errno == EPERM)
+          errsv = errno;
+          if (fd < 0 && errsv == EPERM)
 #endif
            fd = g_open (path, O_RDONLY, 0);
 
diff --git a/gio/glocalfileoutputstream.c b/gio/glocalfileoutputstream.c
index 4b3733c..7600571 100644
--- a/gio/glocalfileoutputstream.c
+++ b/gio/glocalfileoutputstream.c
@@ -748,6 +748,7 @@ handle_overwrite_open (const char    *filename,
   int open_flags;
   int res;
   int mode;
+  int errsv;
 
   mode = mode_from_flags_or_info (flags, reference_info);
 
@@ -763,12 +764,13 @@ handle_overwrite_open (const char    *filename,
 #ifdef O_NOFOLLOW
   is_symlink = FALSE;
   fd = g_open (filename, open_flags | O_NOFOLLOW, mode);
+  errsv = errno;
 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
-  if (fd == -1 && errno == EMLINK)
+  if (fd == -1 && errsv == EMLINK)
 #elif defined(__NetBSD__)
-  if (fd == -1 && errno == EFTYPE)
+  if (fd == -1 && errsv == EFTYPE)
 #else
-  if (fd == -1 && errno == ELOOP)
+  if (fd == -1 && errsv == ELOOP)
 #endif
     {
       /* Could be a symlink, or it could be a regular ELOOP error,
@@ -778,13 +780,13 @@ handle_overwrite_open (const char    *filename,
     }
 #else
   fd = g_open (filename, open_flags, mode);
+  errsv = errno;
   /* This is racy, but we do it as soon as possible to minimize the race */
   is_symlink = g_file_test (filename, G_FILE_TEST_IS_SYMLINK);
 #endif
-    
+
   if (fd == -1)
     {
-      int errsv = errno;
       char *display_name = g_filename_display_name (filename);
       g_set_error (error, G_IO_ERROR,
                   g_io_error_from_errno (errsv),
@@ -799,10 +801,10 @@ handle_overwrite_open (const char    *filename,
 #else
   res = fstat (fd, &original_stat);
 #endif
+  errsv = errno;
 
-  if (res != 0) 
+  if (res != 0)
     {
-      int errsv = errno;
       char *display_name = g_filename_display_name (filename);
       g_set_error (error, G_IO_ERROR,
                   g_io_error_from_errno (errsv),
diff --git a/gio/gnetworkmonitornetlink.c b/gio/gnetworkmonitornetlink.c
index d3f1dce..942440b 100644
--- a/gio/gnetworkmonitornetlink.c
+++ b/gio/gnetworkmonitornetlink.c
@@ -94,7 +94,7 @@ g_network_monitor_netlink_initable_init (GInitable     *initable,
       int errsv = errno;
       g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
                    _("Could not create network monitor: %s"),
-                   g_strerror (errno));
+                   g_strerror (errsv));
       return FALSE;
     }
 
@@ -106,7 +106,7 @@ g_network_monitor_netlink_initable_init (GInitable     *initable,
       int errsv = errno;
       g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
                    _("Could not create network monitor: %s"),
-                   g_strerror (errno));
+                   g_strerror (errsv));
       (void) g_close (sockfd, NULL);
       return FALSE;
     }
@@ -125,7 +125,7 @@ g_network_monitor_netlink_initable_init (GInitable     *initable,
       int errsv = errno;
       g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
                    _("Could not create network monitor: %s"),
-                   g_strerror (errno));
+                   g_strerror (errsv));
       return FALSE;
     }
 
diff --git a/gio/gopenuriportal.c b/gio/gopenuriportal.c
index b06da84..da143a4 100644
--- a/gio/gopenuriportal.c
+++ b/gio/gopenuriportal.c
@@ -103,14 +103,15 @@ g_openuri_portal_open_uri (const char  *uri,
     {
       char *path = NULL;
       GUnixFDList *fd_list = NULL;
-      int fd, fd_id;
+      int fd, fd_id, errsv;
 
       path = g_file_get_path (file);
 
       fd = g_open (path, O_PATH | O_CLOEXEC);
+      errsv = errno;
       if (fd == -1)
         {
-          g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
+          g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
                        "Failed to open '%s'", path);
           return FALSE;
         }
@@ -305,17 +306,18 @@ g_openuri_portal_open_uri_async (const char          *uri,
     {
       char *path = NULL;
       GUnixFDList *fd_list = NULL;
-      int fd, fd_id;
+      int fd, fd_id, errsv;
 
       if (task)
         g_object_set_data (G_OBJECT (task), "open-file", GINT_TO_POINTER (TRUE));
 
       path = g_file_get_path (file);
       fd = g_open (path, O_PATH | O_CLOEXEC);
+      errsv = errno;
       if (fd == -1)
         {
           g_task_report_new_error (NULL, callback, user_data, NULL,
-                                   G_IO_ERROR, g_io_error_from_errno (errno),
+                                   G_IO_ERROR, g_io_error_from_errno (errsv),
                                    "OpenURI portal is not available");
           return;
         }
diff --git a/gio/gsocket.c b/gio/gsocket.c
index 248074a..eea502c 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -549,15 +549,16 @@ g_socket (gint     domain,
           gint     protocol,
           GError **error)
 {
-  int fd;
+  int fd, errsv;
 
 #ifdef SOCK_CLOEXEC
   fd = socket (domain, type | SOCK_CLOEXEC, protocol);
+  errsv = errno;
   if (fd != -1)
     return fd;
 
   /* It's possible that libc has SOCK_CLOEXEC but the kernel does not */
-  if (fd < 0 && (errno == EINVAL || errno == EPROTOTYPE))
+  if (fd < 0 && (errsv == EINVAL || errsv == EPROTOTYPE))
 #endif
     fd = socket (domain, type, protocol);
 
@@ -3984,8 +3985,10 @@ g_socket_condition_timed_wait (GSocket       *socket,
 
     while (TRUE)
       {
+       int errsv;
        result = g_poll (poll_fd, num, timeout);
-       if (result != -1 || errno != EINTR)
+       errsv = errno;
+       if (result != -1 || errsv != EINTR)
          break;
 
        if (timeout != -1)
diff --git a/gio/gsubprocess.c b/gio/gsubprocess.c
index e3c43b0..350eb1e 100644
--- a/gio/gsubprocess.c
+++ b/gio/gsubprocess.c
@@ -199,36 +199,49 @@ unset_cloexec (int fd)
 
   if (flags != -1)
     {
+      int errsv;
       flags &= (~FD_CLOEXEC);
       do
-        result = fcntl (fd, F_SETFD, flags);
-      while (result == -1 && errno == EINTR);
+        {
+          result = fcntl (fd, F_SETFD, flags);
+          errsv = errno;
+        }
+      while (result == -1 && errsv == EINTR);
     }
 }
 
 static int
 dupfd_cloexec (int parent_fd)
 {
-  int fd;
+  int fd, errsv;
 #ifdef F_DUPFD_CLOEXEC
   do
-    fd = fcntl (parent_fd, F_DUPFD_CLOEXEC, 3);
-  while (fd == -1 && errno == EINTR);
+    {
+      fd = fcntl (parent_fd, F_DUPFD_CLOEXEC, 3);
+      errsv = errno;
+    }
+  while (fd == -1 && errsv == EINTR);
 #else
   /* OS X Snow Lion and earlier don't have F_DUPFD_CLOEXEC:
    * https://bugzilla.gnome.org/show_bug.cgi?id=710962
    */
   int result, flags;
   do
-    fd = fcntl (parent_fd, F_DUPFD, 3);
-  while (fd == -1 && errno == EINTR);
+    {
+      fd = fcntl (parent_fd, F_DUPFD, 3);
+      errsv = errno;
+    }
+  while (fd == -1 && errsv == EINTR);
   flags = fcntl (fd, F_GETFD, 0);
   if (flags != -1)
     {
       flags |= FD_CLOEXEC;
       do
-        result = fcntl (fd, F_SETFD, flags);
-      while (result == -1 && errno == EINTR);
+        {
+          result = fcntl (fd, F_SETFD, flags);
+          errsv = errno;
+        }
+      while (result == -1 && errsv == EINTR);
     }
 #endif
   return fd;
@@ -245,6 +258,7 @@ child_setup (gpointer user_data)
   ChildData *child_data = user_data;
   gint i;
   gint result;
+  int errsv;
 
   /* We're on the child side now.  "Rename" the file descriptors in
    * child_data.fds[] to stdin/stdout/stderr.
@@ -257,8 +271,11 @@ child_setup (gpointer user_data)
     if (child_data->fds[i] != -1 && child_data->fds[i] != i)
       {
         do
-          result = dup2 (child_data->fds[i], i);
-        while (result == -1 && errno == EINTR);
+          {
+            result = dup2 (child_data->fds[i], i);
+            errsv = errno;
+          }
+        while (result == -1 && errsv == EINTR);
       }
 
   /* Basic fd assignments we can just unset FD_CLOEXEC */
@@ -301,8 +318,11 @@ child_setup (gpointer user_data)
           else
             {
               do
-                result = dup2 (parent_fd, child_fd);
-              while (result == -1 && errno == EINTR);
+                {
+                  result = dup2 (parent_fd, child_fd);
+                  errsv = errno;
+                }
+              while (result == -1 && errsv == EINTR);
               (void) close (parent_fd);
             }
         }
diff --git a/gio/gtestdbus.c b/gio/gtestdbus.c
index f10d33c..6eaf060 100644
--- a/gio/gtestdbus.c
+++ b/gio/gtestdbus.c
@@ -237,6 +237,7 @@ watcher_init (void)
 {
   static gsize started = 0;
   static GIOChannel *channel = NULL;
+  int errsv;
 
   if (g_once_init_enter (&started))
     {
@@ -245,14 +246,16 @@ watcher_init (void)
       /* fork a child to clean up when we are killed */
       if (pipe (pipe_fds) != 0)
         {
-          g_warning ("pipe() failed: %s", g_strerror (errno));
+          errsv = errno;
+          g_warning ("pipe() failed: %s", g_strerror (errsv));
           g_assert_not_reached ();
         }
 
       switch (fork ())
         {
         case -1:
-          g_warning ("fork() failed: %s", g_strerror (errno));
+          errsv = errno;
+          g_warning ("fork() failed: %s", g_strerror (errsv));
           g_assert_not_reached ();
           break;
 
diff --git a/gio/gunixconnection.c b/gio/gunixconnection.c
index 5f969fd..c85ac36 100644
--- a/gio/gunixconnection.c
+++ b/gio/gunixconnection.c
@@ -497,11 +497,12 @@ g_unix_connection_receive_credentials (GUnixConnection      *connection,
                              &opt_val,
                              NULL))
       {
+        int errsv = errno;
         g_set_error (error,
                      G_IO_ERROR,
-                     g_io_error_from_errno (errno),
+                     g_io_error_from_errno (errsv),
                      _("Error checking if SO_PASSCRED is enabled for socket: %s"),
-                     g_strerror (errno));
+                     g_strerror (errsv));
         goto out;
       }
     if (opt_val == 0)
@@ -512,11 +513,12 @@ g_unix_connection_receive_credentials (GUnixConnection      *connection,
                                  TRUE,
                                  NULL))
           {
+            int errsv = errno;
             g_set_error (error,
                          G_IO_ERROR,
-                         g_io_error_from_errno (errno),
+                         g_io_error_from_errno (errsv),
                          _("Error enabling SO_PASSCRED: %s"),
-                         g_strerror (errno));
+                         g_strerror (errsv));
             goto out;
           }
         turn_off_so_passcreds = TRUE;
@@ -605,11 +607,12 @@ g_unix_connection_receive_credentials (GUnixConnection      *connection,
                                FALSE,
                                NULL))
         {
+          int errsv = errno;
           g_set_error (error,
                        G_IO_ERROR,
-                       g_io_error_from_errno (errno),
+                       g_io_error_from_errno (errsv),
                        _("Error while disabling SO_PASSCRED: %s"),
-                       g_strerror (errno));
+                       g_strerror (errsv));
           goto out;
         }
     }
diff --git a/gio/gunixfdmessage.c b/gio/gunixfdmessage.c
index 5816703..b80283b 100644
--- a/gio/gunixfdmessage.c
+++ b/gio/gunixfdmessage.c
@@ -110,14 +110,19 @@ g_unix_fd_message_deserialize (int      level,
    */
   for (i = 0; i < n; i++)
     {
+      int errsv;
+
       do
-        s = fcntl (fds[i], F_SETFD, FD_CLOEXEC);
-      while (s < 0 && errno == EINTR);
+        {
+          s = fcntl (fds[i], F_SETFD, FD_CLOEXEC);
+          errsv = errno;
+        }
+      while (s < 0 && errsv == EINTR);
 
       if (s < 0)
         {
           g_warning ("Error setting close-on-exec flag on incoming fd: %s",
-                     g_strerror (errno));
+                     g_strerror (errsv));
           return NULL;
         }
     }
diff --git a/gio/gunixinputstream.c b/gio/gunixinputstream.c
index defa052..c63e4e5 100644
--- a/gio/gunixinputstream.c
+++ b/gio/gunixinputstream.c
@@ -355,15 +355,18 @@ g_unix_input_stream_read (GInputStream  *stream,
 
   while (1)
     {
+      int errsv;
+
       poll_fds[0].revents = poll_fds[1].revents = 0;
       do
-       poll_ret = g_poll (poll_fds, nfds, -1);
-      while (poll_ret == -1 && errno == EINTR);
+        {
+          poll_ret = g_poll (poll_fds, nfds, -1);
+          errsv = errno;
+        }
+      while (poll_ret == -1 && errsv == EINTR);
 
       if (poll_ret == -1)
        {
-          int errsv = errno;
-
          g_set_error (error, G_IO_ERROR,
                       g_io_error_from_errno (errsv),
                       _("Error reading from file descriptor: %s"),
diff --git a/gio/gunixoutputstream.c b/gio/gunixoutputstream.c
index 0a04f11..3cf96cf 100644
--- a/gio/gunixoutputstream.c
+++ b/gio/gunixoutputstream.c
@@ -341,15 +341,18 @@ g_unix_output_stream_write (GOutputStream  *stream,
 
   while (1)
     {
+      int errsv;
+
       poll_fds[0].revents = poll_fds[1].revents = 0;
       do
-       poll_ret = g_poll (poll_fds, nfds, -1);
-      while (poll_ret == -1 && errno == EINTR);
+        {
+          poll_ret = g_poll (poll_fds, nfds, -1);
+          errsv = errno;
+        }
+      while (poll_ret == -1 && errsv == EINTR);
 
       if (poll_ret == -1)
        {
-          int errsv = errno;
-
          g_set_error (error, G_IO_ERROR,
                       g_io_error_from_errno (errsv),
                       _("Error writing to file descriptor: %s"),
@@ -364,10 +367,9 @@ g_unix_output_stream_write (GOutputStream  *stream,
        continue;
 
       res = write (unix_stream->priv->fd, buffer, count);
+      errsv = errno;
       if (res == -1)
        {
-          int errsv = errno;
-
          if (errsv == EINTR || errsv == EAGAIN)
            continue;
 
diff --git a/gio/inotify/inotify-kernel.c b/gio/inotify/inotify-kernel.c
index 6758480..9a2e500 100644
--- a/gio/inotify/inotify-kernel.c
+++ b/gio/inotify/inotify-kernel.c
@@ -140,19 +140,21 @@ ik_source_read_some_events (InotifyKernelSource *iks,
                             gsize                buffer_len)
 {
   gssize result;
+  int errsv;
 
 again:
   result = read (iks->fd, buffer, buffer_len);
+  errsv = errno;
 
   if (result < 0)
     {
-      if (errno == EINTR)
+      if (errsv == EINTR)
         goto again;
 
-      if (errno == EAGAIN)
+      if (errsv == EAGAIN)
         return 0;
 
-      g_error ("inotify read(): %s", g_strerror (errno));
+      g_error ("inotify read(): %s", g_strerror (errsv));
     }
   else if (result == 0)
     g_error ("inotify unexpectedly hit eof");
@@ -178,11 +180,13 @@ ik_source_read_all_the_events (InotifyKernelSource *iks,
       gchar *new_buffer;
       guint n_readable;
       gint result;
+      int errsv;
 
       /* figure out how many more bytes there are to read */
       result = ioctl (iks->fd, FIONREAD, &n_readable);
+      errsv = errno;
       if (result != 0)
-        g_error ("inotify ioctl(FIONREAD): %s", g_strerror (errno));
+        g_error ("inotify ioctl(FIONREAD): %s", g_strerror (errsv));
 
       if (n_readable != 0)
         {
diff --git a/gio/tests/dbus-launch.c b/gio/tests/dbus-launch.c
index 97bb89c..5eeb1c0 100644
--- a/gio/tests/dbus-launch.c
+++ b/gio/tests/dbus-launch.c
@@ -39,6 +39,7 @@ write_all (const void *ptr,
   while (len > 0)
     {
       ssize_t done = write (STDOUT_FILENO, p, len);
+      int errsv = errno;
 
       if (done == 0)
         {
@@ -46,10 +47,10 @@ write_all (const void *ptr,
         }
       else if (done < 0)
         {
-          if (errno == EINTR)
+          if (errsv == EINTR)
             continue;
 
-          g_error ("%s: write: %s", ME, g_strerror (errno));
+          g_error ("%s: write: %s", ME, g_strerror (errsv));
         }
       else
         {
diff --git a/gio/tests/gdbus-peer-object-manager.c b/gio/tests/gdbus-peer-object-manager.c
index c5fc641..933cc52 100644
--- a/gio/tests/gdbus-peer-object-manager.c
+++ b/gio/tests/gdbus-peer-object-manager.c
@@ -219,8 +219,9 @@ setup (Test *test,
 
   if (socketpair (AF_UNIX, SOCK_STREAM, 0, pair) < 0)
     {
-      g_set_error (&error, G_IO_ERROR, g_io_error_from_errno (errno),
-                   "%s", g_strerror (errno));
+      int errsv = errno;
+      g_set_error (&error, G_IO_ERROR, g_io_error_from_errno (errsv),
+                   "%s", g_strerror (errsv));
       g_assert_no_error (error);
     }
 
diff --git a/gio/tests/gdbus-peer.c b/gio/tests/gdbus-peer.c
index 8737ee8..b4169ab 100644
--- a/gio/tests/gdbus-peer.c
+++ b/gio/tests/gdbus-peer.c
@@ -615,18 +615,21 @@ read_all_from_fd (gint fd, gsize *out_len, GError **error)
 
   do
     {
+      int errsv;
+
       num_read = read (fd, buf, sizeof (buf));
+      errsv = errno;
       if (num_read == -1)
         {
-          if (errno == EAGAIN || errno == EWOULDBLOCK)
+          if (errsv == EAGAIN || errsv == EWOULDBLOCK)
             continue;
           g_set_error (error,
                        G_IO_ERROR,
-                       g_io_error_from_errno (errno),
+                       g_io_error_from_errno (errsv),
                        "Failed reading %d bytes into offset %d: %s",
                        (gint) sizeof (buf),
                        (gint) str->len,
-                       g_strerror (errno));
+                       g_strerror (errsv));
           goto error;
         }
       else if (num_read > 0)
diff --git a/gio/tests/gdbus-unix-addresses.c b/gio/tests/gdbus-unix-addresses.c
index 23c41d0..8b58513 100644
--- a/gio/tests/gdbus-unix-addresses.c
+++ b/gio/tests/gdbus-unix-addresses.c
@@ -61,7 +61,10 @@ set_up_mock_xdg_runtime_dir (void)
 
   /* alters tmpdir in-place */
   if (g_mkdtemp_full (tmpdir, 0700) == NULL)
-    g_error ("g_mkdtemp_full: %s", g_strerror (errno));
+    {
+      int errsv = errno;
+      g_error ("g_mkdtemp_full: %s", g_strerror (errsv));
+    }
 
   mock_bus_path = g_strconcat (tmpdir, "/bus", NULL);
   addr = g_unix_socket_address_new (mock_bus_path);
@@ -81,10 +84,16 @@ tear_down_mock_xdg_runtime_dir (void)
   g_assert_no_error (error);
 
   if (g_unlink (mock_bus_path) < 0)
-    g_error ("g_unlink(\"%s\"): %s", mock_bus_path, g_strerror (errno));
+    {
+      int errsv = errno;
+      g_error ("g_unlink(\"%s\"): %s", mock_bus_path, g_strerror (errsv));
+    }
 
   if (g_rmdir (tmpdir) < 0)
-    g_error ("g_rmdir(\"%s\"): %s", tmpdir, g_strerror (errno));
+    {
+      int errsv = errno;
+      g_error ("g_rmdir(\"%s\"): %s", tmpdir, g_strerror (errsv));
+    }
 
   g_clear_object (&mock_bus);
   g_clear_pointer (&mock_bus_path, g_free);
diff --git a/gio/tests/gsubprocess-testprog.c b/gio/tests/gsubprocess-testprog.c
index ca2a6ba..74cb9e2 100644
--- a/gio/tests/gsubprocess-testprog.c
+++ b/gio/tests/gsubprocess-testprog.c
@@ -23,9 +23,10 @@ write_all (int           fd,
   while (len > 0)
     {
       gssize bytes_written = write (fd, buf, len);
+      int errsv = errno;
       if (bytes_written < 0)
        g_error ("Failed to write to fd %d: %s",
-                fd, g_strerror (errno));
+                fd, g_strerror (errsv));
       buf += bytes_written;
       len -= bytes_written;
     }
diff --git a/glib/gerror.c b/glib/gerror.c
index fc7e2bd..a92cbe2 100644
--- a/glib/gerror.c
+++ b/glib/gerror.c
@@ -124,8 +124,10 @@
  * foo_open_file (GError **error)
  * {
  *   gint fd;
+ *   int saved_errno;
  *
  *   fd = open ("file.txt", O_RDONLY);
+ *   saved_errno = errno;
  *
  *   if (fd < 0)
  *     {
@@ -133,7 +135,7 @@
  *                    FOO_ERROR,                 // error domain
  *                    FOO_ERROR_BLAH,            // error code
  *                    "Failed to open file: %s", // error message format string
- *                    g_strerror (errno));
+ *                    g_strerror (saved_errno));
  *       return -1;
  *     }
  *   else
diff --git a/glib/giowin32.c b/glib/giowin32.c
index f150f7b..0982388 100644
--- a/glib/giowin32.c
+++ b/glib/giowin32.c
@@ -537,12 +537,14 @@ create_thread (GIOWin32Channel     *channel,
               unsigned (__stdcall *thread) (void *parameter))
 {
   HANDLE thread_handle;
+  int errsv;
 
   thread_handle = (HANDLE) _beginthreadex (NULL, 0, thread, channel, 0,
                                           &channel->thread_id);
+  errsv = errno;
   if (thread_handle == 0)
     g_warning ("Error creating thread: %s.",
-              g_strerror (errno));
+              g_strerror (errsv));
   else if (!CloseHandle (thread_handle))
     {
       gchar *emsg = g_win32_error_message (GetLastError ());
@@ -1193,6 +1195,7 @@ g_io_win32_fd_and_console_read (GIOChannel *channel,
 {
   GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
   gint result;
+  int errsv;
   
   if (win32_channel->debug)
     g_print ("g_io_win32_fd_read: fd=%d count=%" G_GSIZE_FORMAT "\n",
@@ -1204,6 +1207,7 @@ g_io_win32_fd_and_console_read (GIOChannel *channel,
     }
 
   result = read (win32_channel->fd, buf, count);
+  errsv = errno;
 
   if (win32_channel->debug)
     g_print ("g_io_win32_fd_read: read() => %d\n", result);
@@ -1212,7 +1216,7 @@ g_io_win32_fd_and_console_read (GIOChannel *channel,
     {
       *bytes_read = 0;
 
-      switch (errno)
+      switch (errsv)
         {
 #ifdef EAGAIN
        case EAGAIN:
@@ -1220,8 +1224,8 @@ g_io_win32_fd_and_console_read (GIOChannel *channel,
 #endif
        default:
          g_set_error_literal (err, G_IO_CHANNEL_ERROR,
-                               g_io_channel_error_from_errno (errno),
-                               g_strerror (errno));
+                               g_io_channel_error_from_errno (errsv),
+                               g_strerror (errsv));
          return G_IO_STATUS_ERROR;
         }
     }
@@ -1240,6 +1244,7 @@ g_io_win32_fd_and_console_write (GIOChannel  *channel,
 {
   GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
   gint result;
+  int errsv;
 
   if (win32_channel->thread_id)
     {
@@ -1247,6 +1252,8 @@ g_io_win32_fd_and_console_write (GIOChannel  *channel,
     }
   
   result = write (win32_channel->fd, buf, count);
+  errsv = errno;
+
   if (win32_channel->debug)
     g_print ("g_io_win32_fd_write: fd=%d count=%" G_GSIZE_FORMAT " => %d\n",
             win32_channel->fd, count, result);
@@ -1255,7 +1262,7 @@ g_io_win32_fd_and_console_write (GIOChannel  *channel,
     {
       *bytes_written = 0;
 
-      switch (errno)
+      switch (errsv)
         {
 #ifdef EAGAIN
        case EAGAIN:
@@ -1263,8 +1270,8 @@ g_io_win32_fd_and_console_write (GIOChannel  *channel,
 #endif
        default:
          g_set_error_literal (err, G_IO_CHANNEL_ERROR,
-                               g_io_channel_error_from_errno (errno),
-                               g_strerror (errno));
+                               g_io_channel_error_from_errno (errsv),
+                               g_strerror (errsv));
          return G_IO_STATUS_ERROR;
         }
     }
@@ -1281,7 +1288,7 @@ g_io_win32_fd_seek (GIOChannel *channel,
                    GError    **err)
 {
   GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
-  int whence;
+  int whence, errsv;
   off_t tmp_offset;
   off_t result;
   
@@ -1310,14 +1317,15 @@ g_io_win32_fd_seek (GIOChannel *channel,
                            g_strerror (EINVAL));
       return G_IO_STATUS_ERROR;
     }
-  
+
   result = lseek (win32_channel->fd, tmp_offset, whence);
+  errsv = errno;
   
   if (result < 0)
     {
       g_set_error_literal (err, G_IO_CHANNEL_ERROR,
-                           g_io_channel_error_from_errno (errno),
-                           g_strerror (errno));
+                           g_io_channel_error_from_errno (errsv),
+                           g_strerror (errsv));
       return G_IO_STATUS_ERROR;
     }
 
@@ -1411,9 +1419,10 @@ g_io_win32_console_close (GIOChannel *channel,
   
   if (close (win32_channel->fd) < 0)
     {
+      int errsv = errno;
       g_set_error_literal (err, G_IO_CHANNEL_ERROR,
-                           g_io_channel_error_from_errno (errno),
-                           g_strerror (errno));
+                           g_io_channel_error_from_errno (errsv),
+                           g_strerror (errsv));
       return G_IO_STATUS_ERROR;
     }
 
@@ -1628,7 +1637,7 @@ g_io_channel_new_file (const gchar  *filename,
     MODE_A = 1 << 2,
     MODE_PLUS = 1 << 3,
   };
-  int mode_num;
+  int mode_num, errsv;
 
   g_return_val_if_fail (filename != NULL, NULL);
   g_return_val_if_fail (mode != NULL, NULL);
@@ -1699,6 +1708,7 @@ g_io_channel_new_file (const gchar  *filename,
 
   /* always open 'untranslated' */
   fid = g_open (filename, flags | _O_BINARY, pmode);
+  errsv = errno;
 
   if (g_io_win32_get_debug_flag ())
     {
@@ -1710,8 +1720,8 @@ g_io_channel_new_file (const gchar  *filename,
   if (fid < 0)
     {
       g_set_error_literal (error, G_FILE_ERROR,
-                           g_file_error_from_errno (errno),
-                           g_strerror (errno));
+                           g_file_error_from_errno (errsv),
+                           g_strerror (errsv));
       return (GIOChannel *)NULL;
     }
 
diff --git a/glib/gkeyfile.c b/glib/gkeyfile.c
index 9831fbe..4a69642 100644
--- a/glib/gkeyfile.c
+++ b/glib/gkeyfile.c
@@ -759,9 +759,10 @@ g_key_file_load_from_fd (GKeyFile       *key_file,
 
   if (fstat (fd, &stat_buf) < 0)
     {
+      int errsv = errno;
       g_set_error_literal (error, G_FILE_ERROR,
-                           g_file_error_from_errno (errno),
-                           g_strerror (errno));
+                           g_file_error_from_errno (errsv),
+                           g_strerror (errsv));
       return FALSE;
     }
 
@@ -781,19 +782,22 @@ g_key_file_load_from_fd (GKeyFile       *key_file,
 
   do
     {
+      int errsv;
+
       bytes_read = read (fd, read_buf, 4096);
+      errsv = errno;
 
       if (bytes_read == 0)  /* End of File */
         break;
 
       if (bytes_read < 0)
         {
-          if (errno == EINTR || errno == EAGAIN)
+          if (errsv == EINTR || errsv == EAGAIN)
             continue;
 
           g_set_error_literal (error, G_FILE_ERROR,
-                               g_file_error_from_errno (errno),
-                               g_strerror (errno));
+                               g_file_error_from_errno (errsv),
+                               g_strerror (errsv));
           return FALSE;
         }
 
@@ -848,17 +852,19 @@ g_key_file_load_from_file (GKeyFile       *key_file,
 {
   GError *key_file_error = NULL;
   gint fd;
+  int errsv;
 
   g_return_val_if_fail (key_file != NULL, FALSE);
   g_return_val_if_fail (file != NULL, FALSE);
 
   fd = g_open (file, O_RDONLY, 0);
+  errsv = errno;
 
   if (fd == -1)
     {
       g_set_error_literal (error, G_FILE_ERROR,
-                           g_file_error_from_errno (errno),
-                           g_strerror (errno));
+                           g_file_error_from_errno (errsv),
+                           g_strerror (errsv));
       return FALSE;
     }
 
@@ -4295,9 +4301,11 @@ g_key_file_parse_value_as_integer (GKeyFile     *key_file,
   gchar *eof_int;
   glong long_value;
   gint int_value;
+  int errsv;
 
   errno = 0;
   long_value = strtol (value, &eof_int, 10);
+  errsv = errno;
 
   if (*value == '\0' || (*eof_int != '\0' && !g_ascii_isspace(*eof_int)))
     {
@@ -4312,7 +4320,7 @@ g_key_file_parse_value_as_integer (GKeyFile     *key_file,
     }
 
   int_value = long_value;
-  if (int_value != long_value || errno == ERANGE)
+  if (int_value != long_value || errsv == ERANGE)
     {
       gchar *value_utf8 = g_utf8_make_valid (value, -1);
       g_set_error (error,
diff --git a/glib/gmain.c b/glib/gmain.c
index 6566571..8d6b2ce 100644
--- a/glib/gmain.c
+++ b/glib/gmain.c
@@ -4167,6 +4167,8 @@ g_main_context_poll (GMainContext *context,
 
   if (n_fds || timeout != 0)
     {
+      int ret, errsv;
+
 #ifdef G_MAIN_POLL_DEBUG
       poll_timer = NULL;
       if (_g_main_poll_debug)
@@ -4180,13 +4182,15 @@ g_main_context_poll (GMainContext *context,
       LOCK_CONTEXT (context);
 
       poll_func = context->poll_func;
-      
+
       UNLOCK_CONTEXT (context);
-      if ((*poll_func) (fds, n_fds, timeout) < 0 && errno != EINTR)
+      ret = (*poll_func) (fds, n_fds, timeout);
+      errsv = errno;
+      if (ret < 0 && errsv != EINTR)
        {
 #ifndef G_OS_WIN32
          g_warning ("poll(2) failed due to: %s.",
-                    g_strerror (errno));
+                    g_strerror (errsv));
 #else
          /* If g_poll () returns -1, it has already called g_warning() */
 #endif
diff --git a/glib/gslice.c b/glib/gslice.c
index b97b4e0..8be5bad 100644
--- a/glib/gslice.c
+++ b/glib/gslice.c
@@ -1274,13 +1274,15 @@ allocator_add_slab (Allocator *allocator,
   SlabInfo *sinfo;
   gsize addr, padding, n_chunks, color = 0;
   gsize page_size = allocator_aligned_page_size (allocator, SLAB_BPAGE_SIZE (allocator, chunk_size));
+  int errsv;
   /* allocate 1 page for the chunks and the slab */
   gpointer aligned_memory = allocator_memalign (page_size, page_size - NATIVE_MALLOC_PADDING);
+  errsv = errno;
   guint8 *mem = aligned_memory;
   guint i;
   if (!mem)
     {
-      const gchar *syserr = strerror (errno);
+      const gchar *syserr = strerror (errsv);
       mem_error ("failed to allocate %u bytes (alignment: %u): %s\n",
                  (guint) (page_size - NATIVE_MALLOC_PADDING), (guint) page_size, syserr);
     }
diff --git a/glib/gtester.c b/glib/gtester.c
index 7a38907..38a7f96 100644
--- a/glib/gtester.c
+++ b/glib/gtester.c
@@ -678,9 +678,11 @@ main (int    argc,
 
   if (output_filename)
     {
+      int errsv;
       log_fd = g_open (output_filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
+      errsv = errno;
       if (log_fd < 0)
-        g_error ("Failed to open log file '%s': %s", output_filename, g_strerror (errno));
+        g_error ("Failed to open log file '%s': %s", output_filename, g_strerror (errsv));
     }
 
   test_log_printfe ("<?xml version=\"1.0\"?>\n");
diff --git a/glib/gtestutils.c b/glib/gtestutils.c
index 70947e0..c02b13c 100644
--- a/glib/gtestutils.c
+++ b/glib/gtestutils.c
@@ -2694,9 +2694,12 @@ child_read (GIOChannel *io, GIOCondition cond, gpointer user_data)
     {
       for (total = 0; total < nread; total += nwrote)
         {
+          int errsv;
+
           nwrote = fwrite (buf + total, 1, nread - total, echo_file);
+          errsv = errno;
           if (nwrote == 0)
-            g_error ("write failed: %s", g_strerror (errno));
+            g_error ("write failed: %s", g_strerror (errsv));
         }
     }
 
@@ -2817,13 +2820,18 @@ g_test_trap_fork (guint64        usec_timeout,
 #ifdef G_OS_UNIX
   int stdout_pipe[2] = { -1, -1 };
   int stderr_pipe[2] = { -1, -1 };
+  int errsv;
 
   test_trap_clear();
   if (pipe (stdout_pipe) < 0 || pipe (stderr_pipe) < 0)
-    g_error ("failed to create pipes to fork test program: %s", g_strerror (errno));
+    {
+      errsv = errno;
+      g_error ("failed to create pipes to fork test program: %s", g_strerror (errsv));
+    }
   test_trap_last_pid = fork ();
+  errsv = errno;
   if (test_trap_last_pid < 0)
-    g_error ("failed to fork test program: %s", g_strerror (errno));
+    g_error ("failed to fork test program: %s", g_strerror (errsv));
   if (test_trap_last_pid == 0)  /* child */
     {
       int fd0 = -1;
@@ -2836,7 +2844,10 @@ g_test_trap_fork (guint64        usec_timeout,
             g_error ("failed to open /dev/null for stdin redirection");
         }
       if (sane_dup2 (stdout_pipe[1], 1) < 0 || sane_dup2 (stderr_pipe[1], 2) < 0 || (fd0 >= 0 && sane_dup2 
(fd0, 0) < 0))
-        g_error ("failed to dup2() in forked test program: %s", g_strerror (errno));
+        {
+          errsv = errno;
+          g_error ("failed to dup2() in forked test program: %s", g_strerror (errsv));
+        }
       if (fd0 >= 3)
         close (fd0);
       if (stdout_pipe[1] >= 3)
diff --git a/glib/gutils.c b/glib/gutils.c
index 70b08b6..099bba5 100644
--- a/glib/gutils.c
+++ b/glib/gutils.c
@@ -221,12 +221,14 @@ void
 g_atexit (GVoidFunc func)
 {
   gint result;
+  int errsv;
 
   result = atexit ((void (*)(void)) func);
+  errsv = errno;
   if (result)
     {
       g_error ("Could not register atexit() function: %s",
-               g_strerror (errno));
+               g_strerror (errsv));
     }
 }
 
diff --git a/glib/tests/fileutils.c b/glib/tests/fileutils.c
index 4c987a3..2fe22cc 100644
--- a/glib/tests/fileutils.c
+++ b/glib/tests/fileutils.c
@@ -444,7 +444,10 @@ test_mkdir_with_parents_1 (const gchar *base)
     g_error ("failed, %s exists, cannot test g_mkdir_with_parents\n", p2);
 
   if (g_mkdir_with_parents (p2, 0777) == -1)
-    g_error ("failed, g_mkdir_with_parents(%s) failed: %s\n", p2, g_strerror (errno));
+    {
+      int errsv = errno;
+      g_error ("failed, g_mkdir_with_parents(%s) failed: %s\n", p2, g_strerror (errsv));
+    }
 
   if (!g_file_test (p2, G_FILE_TEST_IS_DIR))
     g_error ("failed, g_mkdir_with_parents(%s) succeeded, but %s is not a directory\n", p2, p2);
diff --git a/glib/tests/protocol.c b/glib/tests/protocol.c
index d6286ff..18ebe61 100644
--- a/glib/tests/protocol.c
+++ b/glib/tests/protocol.c
@@ -143,7 +143,8 @@ test_message (void)
 
   if (0 > pipe (pipes))
     {
-      g_error ("error creating pipe: %s", g_strerror (errno));
+      int errsv = errno;
+      g_error ("error creating pipe: %s", g_strerror (errsv));
     }
 
   argv[1] = g_strdup_printf ("--GTestLogFD=%u", pipes[1]);
@@ -265,7 +266,8 @@ test_error (void)
 
       if (0 > pipe (pipes))
         {
-          g_error ("error creating pipe: %s", g_strerror (errno));
+          int errsv = errno;
+          g_error ("error creating pipe: %s", g_strerror (errsv));
         }
 
       argv[1] = g_strdup_printf ("--GTestLogFD=%u", pipes[1]);
diff --git a/tests/gobject/timeloop-closure.c b/tests/gobject/timeloop-closure.c
index 9de00d3..c904c2a 100644
--- a/tests/gobject/timeloop-closure.c
+++ b/tests/gobject/timeloop-closure.c
@@ -23,7 +23,8 @@ io_pipe (GIOChannel **channels)
 
   if (pipe(fds) < 0)
     {
-      fprintf (stderr, "Cannot create pipe %s\n", g_strerror (errno));
+      int errsv = errno;
+      fprintf (stderr, "Cannot create pipe %s\n", g_strerror (errsv));
       exit (1);
     }
 
@@ -134,7 +135,7 @@ input_callback (GIOChannel   *source,
 static void
 create_child (void)
 {
-  int pid;
+  int pid, errsv;
   GIOChannel *in_channels[2];
   GIOChannel *out_channels[2];
   GSource *source;
@@ -143,6 +144,7 @@ create_child (void)
   io_pipe (out_channels);
 
   pid = fork ();
+  errsv = errno;
 
   if (pid > 0)                 /* Parent */
     {
@@ -172,7 +174,7 @@ create_child (void)
     }
   else                         /* Error */
     {
-      fprintf (stderr, "Cannot fork: %s\n", g_strerror (errno));
+      fprintf (stderr, "Cannot fork: %s\n", g_strerror (errsv));
       exit (1);
     }
 }
diff --git a/tests/mainloop-test.c b/tests/mainloop-test.c
index 5d30550..9b8386a 100644
--- a/tests/mainloop-test.c
+++ b/tests/mainloop-test.c
@@ -202,7 +202,8 @@ io_pipe (GIOChannel **channels)
 
   if (pipe(fds) < 0)
     {
-      g_warning ("Cannot create pipe %s\n", g_strerror (errno));
+      int errsv = errno;
+      g_warning ("Cannot create pipe %s\n", g_strerror (errsv));
       exit (1);
     }
 
diff --git a/tests/spawn-test-win32-gui.c b/tests/spawn-test-win32-gui.c
index 45529d0..2798ce6 100644
--- a/tests/spawn-test-win32-gui.c
+++ b/tests/spawn-test-win32-gui.c
@@ -60,7 +60,8 @@ WinMain (struct HINSTANCE__ *hInstance,
       if (write (outfd, &n, sizeof (n)) == -1 ||
          write (outfd, "Hello there", n) == -1)
        {
-         sprintf (buf, "spawn-test-win32-gui: Write: %s", strerror (errno));
+         int errsv = errno;
+         sprintf (buf, "spawn-test-win32-gui: Write: %s", strerror (errsv));
          MessageBox (NULL, buf, lpszCmdLine, MB_ICONERROR|MB_SYSTEMMODAL);
          exit (1);
        }
@@ -81,8 +82,9 @@ WinMain (struct HINSTANCE__ *hInstance,
 
       if ((k = read (infd, buf, n)) != n)
        {
+         int errsv = errno;
          if (k == -1)
-           sprintf (buf, "spawn-test-win32-gui: Read: %s", strerror (errno));
+           sprintf (buf, "spawn-test-win32-gui: Read: %s", strerror (errsv));
          else
            sprintf (buf, "spawn-test-win32-gui: Got only %d bytes", k);
          MessageBox (NULL, buf, lpszCmdLine, MB_ICONERROR|MB_SYSTEMMODAL);
@@ -96,7 +98,8 @@ WinMain (struct HINSTANCE__ *hInstance,
       if (write (outfd, &n, sizeof (n)) == -1 ||
          write (outfd, "See ya", n) == -1)
        {
-         sprintf (buf, "spawn-test-win32-gui: Write: %s", strerror (errno));
+         int errsv = errno;
+         sprintf (buf, "spawn-test-win32-gui: Write: %s", strerror (errsv));
          MessageBox (NULL, buf, lpszCmdLine, MB_ICONERROR|MB_SYSTEMMODAL);
          exit (1);
        }
diff --git a/tests/spawn-test.c b/tests/spawn-test.c
index 217cfd9..05cce17 100644
--- a/tests/spawn-test.c
+++ b/tests/spawn-test.c
@@ -232,8 +232,9 @@ run_tests (void)
 
       if ((k = read (pipeup[0], &n, sizeof (n))) != sizeof (n))
        {
+         int errsv = errno;
          if (k == -1)
-           fprintf (stderr, "Read error: %s\n", g_strerror (errno));
+           fprintf (stderr, "Read error: %s\n", g_strerror (errsv));
          else
            fprintf (stderr, "Wanted to read %d bytes, got %d\n",
                     sizeof (n), k);
@@ -242,8 +243,9 @@ run_tests (void)
 
       if ((k = read (pipeup[0], buf, n)) != n)
        {
+         int errsv = errno;
          if (k == -1)
-           fprintf (stderr, "Read error: %s\n", g_strerror (errno));
+           fprintf (stderr, "Read error: %s\n", g_strerror (errsv));
          else
            fprintf (stderr, "Wanted to read %d bytes, got %d\n",
                     n, k);
@@ -254,14 +256,16 @@ run_tests (void)
       if (write (pipedown[1], &n, sizeof (n)) == -1 ||
          write (pipedown[1], "Bye then", n) == -1)
        {
-         fprintf (stderr, "Write error: %s\n", g_strerror (errno));
+         int errsv = errno;
+         fprintf (stderr, "Write error: %s\n", g_strerror (errsv));
          exit (1);
        }
 
       if ((k = read (pipeup[0], &n, sizeof (n))) != sizeof (n))
        {
+         int errsv = errno;
          if (k == -1)
-           fprintf (stderr, "Read error: %s\n", g_strerror (errno));
+           fprintf (stderr, "Read error: %s\n", g_strerror (errsv));
          else
            fprintf (stderr, "Wanted to read %d bytes, got %d\n",
                     sizeof (n), k);
@@ -270,8 +274,9 @@ run_tests (void)
 
       if ((k = read (pipeup[0], buf, n)) != n)
        {
+         int errsv = errno;
          if (k == -1)
-           fprintf (stderr, "Read error: %s\n", g_strerror (errno));
+           fprintf (stderr, "Read error: %s\n", g_strerror (errsv));
          else
            fprintf (stderr, "Wanted to read %d bytes, got %d\n",
                     n, k);
diff --git a/tests/testglib.c b/tests/testglib.c
index e9f7f36..b5a8331 100644
--- a/tests/testglib.c
+++ b/tests/testglib.c
@@ -907,6 +907,7 @@ test_file_functions (void)
   char template[32];
   char *name_used, chars[62];
   gint fd, n;
+  int errsv;
   
   strcpy (template, "foobar");
   fd = g_mkstemp (template);
@@ -919,15 +920,17 @@ test_file_functions (void)
   if (fd == -1)
     g_error ("g_mkstemp didn't work for template %s\n", template);
   n = write (fd, hello, hellolen);
+  errsv = errno;
   if (n == -1)
-    g_error ("write() failed: %s\n", g_strerror (errno));
+    g_error ("write() failed: %s\n", g_strerror (errsv));
   else if (n != hellolen)
     g_error ("write() should have written %d bytes, wrote %d\n", hellolen, n);
 
   lseek (fd, 0, 0);
   n = read (fd, chars, sizeof (chars));
+  errsv = errno;
   if (n == -1)
-    g_error ("read() failed: %s\n", g_strerror (errno));
+    g_error ("read() failed: %s\n", g_strerror (errsv));
   else if (n != hellolen)
     g_error ("read() should have read %d bytes, got %d\n", hellolen, n);
 
diff --git a/tests/timeloop-basic.c b/tests/timeloop-basic.c
index 2c11bc5..7f95226 100644
--- a/tests/timeloop-basic.c
+++ b/tests/timeloop-basic.c
@@ -25,7 +25,8 @@ my_pipe (int *fds)
 {
   if (pipe(fds) < 0)
     {
-      fprintf (stderr, "Cannot create pipe %s\n", strerror (errno));
+      int errsv = errno;
+      fprintf (stderr, "Cannot create pipe %s\n", strerror (errsv));
       exit (1);
     }
 }
@@ -121,7 +122,7 @@ input_callback (int source, int dest)
 void
 create_child (int pos)
 {
-  int pid;
+  int pid, errsv;
   int in_fds[2];
   int out_fds[2];
   
@@ -129,6 +130,7 @@ create_child (int pos)
   my_pipe (out_fds);
 
   pid = fork ();
+  errsv = errno;
 
   if (pid > 0)                 /* Parent */
     {
@@ -150,7 +152,7 @@ create_child (int pos)
     }
   else                         /* Error */
     {
-      fprintf (stderr,"Cannot fork: %s\n", strerror (errno));
+      fprintf (stderr,"Cannot fork: %s\n", strerror (errsv));
       exit (1);
     }
 }
diff --git a/tests/timeloop.c b/tests/timeloop.c
index a1f69ef..8b5aa36 100644
--- a/tests/timeloop.c
+++ b/tests/timeloop.c
@@ -22,7 +22,8 @@ io_pipe (GIOChannel **channels)
 
   if (pipe(fds) < 0)
     {
-      fprintf (stderr, "Cannot create pipe %s\n", g_strerror (errno));
+      int errsv = errno;
+      fprintf (stderr, "Cannot create pipe %s\n", g_strerror (errsv));
       exit (1);
     }
 
@@ -136,7 +137,7 @@ input_callback (GIOChannel   *source,
 static void
 create_child (void)
 {
-  int pid;
+  int pid, errsv;
   GIOChannel *in_channels[2];
   GIOChannel *out_channels[2];
   
@@ -144,6 +145,7 @@ create_child (void)
   io_pipe (out_channels);
 
   pid = fork ();
+  errsv = errno;
 
   if (pid > 0)                 /* Parent */
     {
@@ -166,7 +168,7 @@ create_child (void)
     }
   else                         /* Error */
     {
-      fprintf (stderr, "Cannot fork: %s\n", g_strerror (errno));
+      fprintf (stderr, "Cannot fork: %s\n", g_strerror (errsv));
       exit (1);
     }
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]