Skip to content
Snippets Groups Projects
Commit 074236b8 authored by Colin Walters's avatar Colin Walters
Browse files

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);
```
parent c83ec7f2
No related branches found
No related tags found
No related merge requests found
......@@ -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;
......
......@@ -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);
}
......@@ -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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment