mirror of
https://github.com/flatpak/flatpak.git
synced 2026-03-30 12:55:19 -04:00
glnx-errors.h: add glnx_null_throw[_*] variants
These are equivalent to the non-null throw, except that the returned
value is a NULL pointer. They can be used in functions where one wants
to return a pointer. E.g.:
GKeyFile *foo(GError **error) {
return glnx_null_throw (error, "foobar");
}
The function call redirections are wrapped around a compound statement
expression[1] so that they represent a single top-level expression. This
allows us to avoid -Wunused-value warnings vs using a comma operator if
the return value isn't used.
I made the 'args...' absorb the fmt argument as well so that callers can
still use it without always having to specify at least one additional
variadic argument. I had to check to be sure that the expansion is all
done by the preprocessor, so we don't need to worry about stack
intricacies.
[1] https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html
This commit is contained in:
@@ -49,6 +49,9 @@ glnx_throw (GError **error, const char *fmt, ...)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Like glnx_throw(), but yields a NULL pointer. */
|
||||
#define glnx_null_throw(error, args...) \
|
||||
({glnx_throw (error, args); NULL;})
|
||||
|
||||
/* Set @error using the value of `g_strerror (errno)`.
|
||||
*
|
||||
@@ -79,6 +82,10 @@ glnx_throw_errno (GError **error)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Like glnx_throw_errno(), but yields a NULL pointer. */
|
||||
#define glnx_null_throw_errno(error) \
|
||||
({glnx_throw_errno (error); NULL;})
|
||||
|
||||
/* Implementation detail of glnx_throw_errno_prefix() */
|
||||
void glnx_real_set_prefix_error_from_errno_va (GError **error,
|
||||
gint errsv,
|
||||
@@ -108,6 +115,10 @@ glnx_throw_errno_prefix (GError **error, const char *fmt, ...)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Like glnx_throw_errno_prefix(), but yields a NULL pointer. */
|
||||
#define glnx_null_throw_errno_prefix(error, args...) \
|
||||
({glnx_throw_errno_prefix (error, args); NULL;})
|
||||
|
||||
/* BEGIN LEGACY APIS */
|
||||
|
||||
#define glnx_set_error_from_errno(error) \
|
||||
|
||||
11
glnx-fdio.c
11
glnx-fdio.c
@@ -555,25 +555,20 @@ glnx_readlinkat_malloc (int dfd,
|
||||
|
||||
for (;;)
|
||||
{
|
||||
char *c;
|
||||
g_autofree char *c = NULL;
|
||||
ssize_t n;
|
||||
|
||||
c = g_malloc (l);
|
||||
n = TEMP_FAILURE_RETRY (readlinkat (dfd, subpath, c, l-1));
|
||||
if (n < 0)
|
||||
{
|
||||
glnx_set_error_from_errno (error);
|
||||
g_free (c);
|
||||
return FALSE;
|
||||
}
|
||||
return glnx_null_throw_errno (error);
|
||||
|
||||
if ((size_t) n < l-1)
|
||||
{
|
||||
c[n] = 0;
|
||||
return c;
|
||||
return g_steal_pointer (&c);
|
||||
}
|
||||
|
||||
g_free (c);
|
||||
l *= 2;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,19 @@ test_error_throw (void)
|
||||
g_assert (!glnx_throw (&error, "foo: %s %d", "hello", 42));
|
||||
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
|
||||
g_assert_cmpstr (error->message, ==, "foo: hello 42");
|
||||
g_clear_error (&error);
|
||||
|
||||
gpointer dummy = glnx_null_throw (&error, "literal foo");
|
||||
g_assert (dummy == NULL);
|
||||
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
|
||||
g_assert_cmpstr (error->message, ==, "literal foo");
|
||||
g_clear_error (&error);
|
||||
|
||||
gpointer dummy2 = glnx_null_throw (&error, "foo: %s %d", "hola", 24);
|
||||
g_assert (dummy2 == NULL);
|
||||
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
|
||||
g_assert_cmpstr (error->message, ==, "foo: hola 24");
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -52,6 +65,17 @@ test_error_errno (void)
|
||||
else
|
||||
g_assert_cmpint (fd, ==, -1);
|
||||
|
||||
fd = open (noent_path, O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
gpointer dummy = glnx_null_throw_errno (&error);
|
||||
g_assert (dummy == NULL);
|
||||
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
else
|
||||
g_assert_cmpint (fd, ==, -1);
|
||||
|
||||
fd = open (noent_path, O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
@@ -62,6 +86,30 @@ test_error_errno (void)
|
||||
}
|
||||
else
|
||||
g_assert_cmpint (fd, ==, -1);
|
||||
|
||||
fd = open (noent_path, O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
gpointer dummy = glnx_null_throw_errno_prefix (&error, "Failed to open file");
|
||||
g_assert (dummy == NULL);
|
||||
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
|
||||
g_assert (g_str_has_prefix (error->message, "Failed to open file"));
|
||||
g_clear_error (&error);
|
||||
}
|
||||
else
|
||||
g_assert_cmpint (fd, ==, -1);
|
||||
|
||||
fd = open (noent_path, O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
gpointer dummy = glnx_null_throw_errno_prefix (&error, "Failed to open %s", noent_path);
|
||||
g_assert (dummy == NULL);
|
||||
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
|
||||
g_assert (g_str_has_prefix (error->message, glnx_strjoina ("Failed to open ", noent_path)));
|
||||
g_clear_error (&error);
|
||||
}
|
||||
else
|
||||
g_assert_cmpint (fd, ==, -1);
|
||||
}
|
||||
|
||||
int main (int argc, char **argv)
|
||||
|
||||
Reference in New Issue
Block a user