diff options
author | Thomas Haller <thaller@redhat.com> | 2022-10-18 09:07:35 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2022-10-20 08:16:38 +0200 |
commit | 3ed7f4d1ed7e49b5d38d837d3edba69f5b7eaaf6 (patch) | |
tree | a3c606a5f85aafe0604611f0357ae4f62aa21c78 | |
parent | 6418db829b6f56b92beb044f51f94c7a1bd7ae51 (diff) | |
download | glib-3ed7f4d1ed7e49b5d38d837d3edba69f5b7eaaf6.tar.gz |
gstdio: make g_close() async-signal-safe under certain conditions
g_close() does something useful. It is not trivial to get EINTR handling of
close() right, in a portable manner. g_close() abstracts this.
We should allow glib users to use the function even in async-signal-safe
contexts, at least if the user heeds the caveat about GError and take care
not to fail assertions.
-rw-r--r-- | glib/gstdio.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/glib/gstdio.c b/glib/gstdio.c index 22d1159ce..7fe7b32ed 100644 --- a/glib/gstdio.c +++ b/glib/gstdio.c @@ -1749,8 +1749,9 @@ g_utime (const gchar *filename, * @fd: A file descriptor * @error: a #GError * - * This wraps the close() call; in case of error, %errno will be + * This wraps the close() call. In case of error, %errno will be * preserved, but the error will also be stored as a #GError in @error. + * In case of success, %errno is undefined. * * Besides using #GError, there is another major reason to prefer this * function over the call provided by the system; on Unix, it will @@ -1759,6 +1760,9 @@ g_utime (const gchar *filename, * * It is a bug to call this function with an invalid file descriptor. * + * Since 2.76, this function is guaranteed to be async-signal-safe if (and only + * if) @error is %NULL and @fd is a valid open file descriptor. + * * Returns: %TRUE on success, %FALSE if there was an error. * * Since: 2.36 @@ -1769,6 +1773,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 +1797,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 |