[glib/th/gspawn-no-safe-close: 9/11] gstdio: make g_close() async-signal-safe under certain conditions




commit ff1afab08deeb72acf66dc67879a32eccbd0e360
Author: Thomas Haller <thaller redhat com>
Date:   Tue Oct 18 09:07:35 2022 +0200

    gstdio: make g_close() async-signal-safe under certain conditions
    
    g_close() does something useful. It's not trivial to get EINTR handling of
    close() right. We should allow glib users to use the function even in
    async-signal-safe contexts, at least if the heed the caveat about the
    GError and take care not to fail assertions.

 glib/gstdio.c | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)
---
diff --git a/glib/gstdio.c b/glib/gstdio.c
index ed46bdf2dd..8c96a5f97f 100644
--- a/glib/gstdio.c
+++ b/glib/gstdio.c
@@ -1759,6 +1759,13 @@ g_utime (const gchar    *filename,
  *
  * It is a bug to call this function with an invalid file descriptor.
  *
+ * Note that usually there is not much that can be done when this
+ * function fails. The best course of action may be to ignore any
+ * error.
+ *
+ * Since 2.76 is this function guaranteed to be async-signal-safe if (and only
+ * if) @error is not requested and if no assertion failure happens due to EBADF.
+ *
  * Returns: %TRUE on success, %FALSE if there was an error.
  *
  * Since: 2.36
@@ -1769,6 +1776,9 @@ g_close (gint       fd,
 {
   int res;
 
+  /* Important: if @error is NULL, we must not do anything that is
+   * not async-signal-safe.
+   */
   res = close (fd);
 
   if (res == -1)
@@ -1790,12 +1800,17 @@ g_close (gint       fd,
           return TRUE;
         }
 
-      g_set_error_literal (error, G_FILE_ERROR,
-                           g_file_error_from_errno (errsv),
-                           g_strerror (errsv));
+      if (error)
+        {
+          g_set_error_literal (error, G_FILE_ERROR,
+                               g_file_error_from_errno (errsv),
+                               g_strerror (errsv));
+        }
 
       if (errsv == EBADF)
         {
+          /* There is a bug. Fail an assertion. Note that this function is supposed to be
+           * async-signal-safe, but in case an assertion fails, all bets are already off. */
           if (fd >= 0)
             {
               /* Closing an non-negative, invalid file descriptor is a bug. The bug is


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