[glib/th/gspawn-no-safe-close: 1/2] gutilsprivate: add internal _g_safe_close() wrapper to replace g_close()/close()
- From: Thomas Haller <thaller src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/th/gspawn-no-safe-close: 1/2] gutilsprivate: add internal _g_safe_close() wrapper to replace g_close()/close()
- Date: Tue, 18 Oct 2022 07:36:24 +0000 (UTC)
commit 1cbeee62663d6ded4a8bfd4349c906d092812ed3
Author: Thomas Haller <thaller redhat com>
Date: Tue Oct 18 08:42:08 2022 +0200
gutilsprivate: add internal _g_safe_close() wrapper to replace g_close()/close()
1) From internal code, we should never use close() directly, because
- we want to assert against EBADF to catch bugs (g_close() does that).
- we want to handle EINTR (g_close() does that, even if it currently
just ignores it).
2) on the upside, g_close() gets most these things right. But from internal code,
we should still not use g_close() directly, because
- the API of g_close() returns errors, which wrongly suggests that the
user should do something about those errors. They almost always should
not, see `man 2 close`.
- g_error() changes errno, which is usually undesirable, in particular
because we don't want to handle errors.
- g_close() is only async-signal-safe under certain conditions. It
means, we need to be careful where (or how) we use g_close().
Add an internal _g_safe_close() wrapper, to get all these things right.
This is to replace close() and g_close().
glib/gutils.c | 29 +++++++++++++++++++++++++++++
glib/gutilsprivate.h | 2 ++
2 files changed, 31 insertions(+)
---
diff --git a/glib/gutils.c b/glib/gutils.c
index 78ccd61214..4ad92da584 100644
--- a/glib/gutils.c
+++ b/glib/gutils.c
@@ -3246,3 +3246,32 @@ g_abort (void)
ExitProcess (127);
}
#endif
+
+/**
+ * _g_safe_close:
+ * fd: the file descriptor to close.
+ *
+ * This is a safe wrapper around g_close() and close(). From internal code,
+ * in almost all cases this function should be used instead of g_close()
+ * and close().
+ *
+ * This is guaranteed to be async-signal-safe (except assertion failures), so it
+ * can be used from a signal handler or between fork and exec.
+ *
+ * As `man 2 close` documents, there isn't much you can do about errors anyway.
+ * _g_safe_close() enforces this by returning no result.
+ *
+ * The function preserves errno.
+ *
+ * This function just calls g_close(), so it handles EINTR (currently by ignoring
+ * it) and EBADF (by asserting).
+ */
+void
+_g_safe_close (int fd)
+{
+ int errsv;
+
+ errsv = errno;
+ g_close (fd, NULL);
+ errno = errsv;
+}
diff --git a/glib/gutilsprivate.h b/glib/gutilsprivate.h
index 77bed4e87b..2359cf0794 100644
--- a/glib/gutilsprivate.h
+++ b/glib/gutilsprivate.h
@@ -54,6 +54,8 @@ g_nearest_pow (gsize num)
return n + 1;
}
+void _g_safe_close (int fd);
+
G_END_DECLS
#endif /* __G_UTILS_PRIVATE_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]