summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2017-03-21 10:23:37 -0400
committerColin Walters <walters@verbum.org>2017-03-22 11:03:32 -0400
commit074236b88d0c742965fcca25a235fc79d3f87e48 (patch)
tree426e615726098628392b701e51389f5dd6752c2a
parentc83ec7f213bd2e435043a435906e46aa9c0a2b6a (diff)
downloadlibglnx-074236b88d0c742965fcca25a235fc79d3f87e48.tar.gz
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); ```
-rw-r--r--glnx-dirfd.c6
-rw-r--r--glnx-errors.c35
-rw-r--r--glnx-errors.h79
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