[libglnx] errors: Add new glnx_throw_errno{,_prefix}() APIs
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libglnx] errors: Add new glnx_throw_errno{,_prefix}() APIs
- Date: Wed, 22 Mar 2017 15:32:22 +0000 (UTC)
commit 074236b88d0c742965fcca25a235fc79d3f87e48
Author: Colin Walters <walters verbum org>
Date: Tue Mar 21 10:23:37 2017 -0400
errors: Add new glnx_throw_errno{,_prefix}() APIs
We have a *lot* of code of the form:
```
if (unlinkat (fd, pathname) < 0)
{
glnx_set_error_from_errno (error);
goto out;
}
```
After conversion to `return FALSE style` which is in progress, it's way shorter,
and clearer like this:
```
if (unlinkat (fd, pathname) < 0)
return glnx_throw_errno (error);
```
glnx-dirfd.c | 6 +---
glnx-errors.c | 35 +++++++++----------------
glnx-errors.h | 79 ++++++++++++++++++++++++++++++++++++++++++++++----------
3 files changed, 80 insertions(+), 40 deletions(-)
---
diff --git a/glnx-dirfd.c b/glnx-dirfd.c
index 11388c1..08d9007 100644
--- a/glnx-dirfd.c
+++ b/glnx-dirfd.c
@@ -68,8 +68,7 @@ glnx_opendirat (int dfd,
int ret = glnx_opendirat_with_errno (dfd, path, follow);
if (ret == -1)
{
- glnx_set_prefix_error_from_errno (error, "%s", "openat");
- return FALSE;
+ return glnx_throw_errno_prefix (error, "openat");
}
*out_fd = ret;
return TRUE;
@@ -339,8 +338,7 @@ glnx_mkdtempat (int dfd,
/* Any other error will apply also to other names we might
* try, and there are 2^32 or so of them, so give up now.
*/
- glnx_set_prefix_error_from_errno (error, "%s", "mkdirat");
- return FALSE;
+ return glnx_throw_errno_prefix (error, "mkdirat");
}
return TRUE;
diff --git a/glnx-errors.c b/glnx-errors.c
index ab7bc0a..edbce20 100644
--- a/glnx-errors.c
+++ b/glnx-errors.c
@@ -24,30 +24,21 @@
#include <glnx-errors.h>
void
-glnx_real_set_prefix_error_from_errno (GError **error,
- gint errsv,
- const char *format,
- ...)
+glnx_real_set_prefix_error_from_errno_va (GError **error,
+ gint errsv,
+ const char *format,
+ va_list args)
{
if (!error)
return;
- else
- {
- GString *buf = g_string_new ("");
- va_list args;
-
- va_start (args, format);
- g_string_append_vprintf (buf, format, args);
- va_end (args);
- g_string_append (buf, ": ");
- g_string_append (buf, g_strerror (errsv));
-
- g_set_error_literal (error,
- G_IO_ERROR,
- g_io_error_from_errno (errsv),
- buf->str);
- g_string_free (buf, TRUE);
- errno = errsv;
- }
+ /* TODO - enhance GError to have a "set and take ownership" API */
+ g_autoptr(GString) buf = g_string_new ("");
+ g_string_append_vprintf (buf, format, args);
+ g_string_append (buf, ": ");
+ g_string_append (buf, g_strerror (errsv));
+ g_set_error_literal (error,
+ G_IO_ERROR,
+ g_io_error_from_errno (errsv),
+ buf->str);
}
diff --git a/glnx-errors.h b/glnx-errors.h
index fffef6c..7bf53d3 100644
--- a/glnx-errors.h
+++ b/glnx-errors.h
@@ -25,25 +25,76 @@
G_BEGIN_DECLS
+/* Set @error using the value of `g_strerror (errno)`.
+ *
+ * This function returns %FALSE so it can be used conveniently in a single
+ * statement:
+ *
+ * ``
+ * if (unlinkat (fd, somepathname) < 0)
+ * return glnx_throw_errno (error);
+ * ```
+ */
+static inline gboolean
+glnx_throw_errno (GError **error)
+{
+ /* Save the value of errno, in case one of the
+ * intermediate function calls happens to set it.
+ */
+ int errsv = errno;
+ g_set_error_literal (error, G_IO_ERROR,
+ g_io_error_from_errno (errsv),
+ g_strerror (errsv));
+ /* We also restore the value of errno, since that's
+ * what was done in a long-ago libgsystem commit
+ * https://git.gnome.org/browse/libgsystem/commit/?id=ed106741f7a0596dc8b960b31fdae671d31d666d
+ * but I certainly can't remember now why I did that.
+ */
+ errno = errsv;
+ return FALSE;
+}
+
+/* Implementation detail of glnx_throw_errno_prefix() */
+void glnx_real_set_prefix_error_from_errno_va (GError **error,
+ gint errsv,
+ const char *format,
+ va_list args) G_GNUC_PRINTF (3,0);
+
+/* Set @error using the value of `$prefix: g_strerror (errno)` where `$prefix`
+ * is computed via printf @fmt.
+ *
+ * This function returns %FALSE so it can be used conveniently in a single
+ * statement:
+ *
+ * ```
+ * return glnx_throw_errno_prefix (error, "unlinking %s", pathname);
+ * ```
+ */
+static inline gboolean G_GNUC_PRINTF (2,3)
+glnx_throw_errno_prefix (GError **error, const char *fmt, ...)
+{
+ int errsv = errno;
+ va_list args;
+ va_start (args, fmt);
+ glnx_real_set_prefix_error_from_errno_va (error, errsv, fmt, args);
+ va_end (args);
+ /* See comment above about preserving errno */
+ errno = errsv;
+ return FALSE;
+}
+
+/* BEGIN LEGACY APIS */
+
#define glnx_set_error_from_errno(error) \
do { \
- int errsv = errno; \
- g_set_error_literal (error, G_IO_ERROR, \
- g_io_error_from_errno (errsv), \
- g_strerror (errsv)); \
- errno = errsv; \
+ glnx_throw_errno (error); \
} while (0);
-#define glnx_set_prefix_error_from_errno(error, format, args...) \
- do { \
- int errsv = errno; \
- glnx_real_set_prefix_error_from_errno (error, errsv, format, args); \
- errno = errsv; \
+#define glnx_set_prefix_error_from_errno(error, format, args...) \
+ do { \
+ glnx_set_error_from_errno (error); \
+ g_prefix_error (error, format, args); \
} while (0);
-void glnx_real_set_prefix_error_from_errno (GError **error,
- gint errsv,
- const char *format,
- ...) G_GNUC_PRINTF (3,4);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]