[network-manager-applet/th/vpn-secrets-bgo790655: 2/9] shared: re-import shared files
- From: Thomas Haller <thaller src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [network-manager-applet/th/vpn-secrets-bgo790655: 2/9] shared: re-import shared files
- Date: Tue, 21 Nov 2017 08:57:49 +0000 (UTC)
commit 93767350d6aeb9874810403e7bafde69d02421b1
Author: Thomas Haller <thaller redhat com>
Date: Mon Nov 20 21:24:34 2017 +0100
shared: re-import shared files
shared/nm-utils/nm-glib.h | 29 ++
shared/nm-utils/nm-macros-internal.h | 366 +++++++++++++++++++++------
shared/nm-utils/nm-shared-utils.c | 468 ++++++++++++++++++++++++++++++++--
shared/nm-utils/nm-shared-utils.h | 160 +++++++++++-
shared/nm-utils/nm-test-utils.h | 56 ++++
5 files changed, 974 insertions(+), 105 deletions(-)
---
diff --git a/shared/nm-utils/nm-glib.h b/shared/nm-utils/nm-glib.h
index dd18756..4ef538e 100644
--- a/shared/nm-utils/nm-glib.h
+++ b/shared/nm-utils/nm-glib.h
@@ -452,4 +452,33 @@ _nm_g_variant_new_take_string (gchar *string)
}
#define g_variant_new_take_string _nm_g_variant_new_take_string
+#if !GLIB_CHECK_VERSION(2, 38, 0)
+_nm_printf (1, 2)
+static inline GVariant *
+_nm_g_variant_new_printf (const char *format_string, ...)
+{
+ char *string;
+ va_list ap;
+
+ g_return_val_if_fail (format_string, NULL);
+
+ va_start (ap, format_string);
+ string = g_strdup_vprintf (format_string, ap);
+ va_end (ap);
+
+ return g_variant_new_take_string (string);
+}
+#define g_variant_new_printf(...) _nm_g_variant_new_printf(__VA_ARGS__)
+#else
+#define g_variant_new_printf(...) \
+ ({ \
+ GVariant *_v; \
+ \
+ G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
+ _v = g_variant_new_printf (__VA_ARGS__); \
+ G_GNUC_END_IGNORE_DEPRECATIONS \
+ _v; \
+ })
+#endif
+
#endif /* __NM_GLIB_H__ */
diff --git a/shared/nm-utils/nm-macros-internal.h b/shared/nm-utils/nm-macros-internal.h
index d11766f..ce13d3a 100644
--- a/shared/nm-utils/nm-macros-internal.h
+++ b/shared/nm-utils/nm-macros-internal.h
@@ -26,20 +26,41 @@
#include <stdlib.h>
#include <errno.h>
-#include "nm-glib.h"
+#define _nm_packed __attribute__ ((packed))
+#define _nm_unused __attribute__ ((unused))
+#define _nm_pure __attribute__ ((pure))
+#define _nm_const __attribute__ ((const))
+#define _nm_printf(a,b) __attribute__ ((__format__ (__printf__, a, b)))
+#define _nm_align(s) __attribute__ ((aligned (s)))
+#define _nm_alignof(type) __alignof (type)
+#define _nm_alignas(type) _nm_align (_nm_alignof (type))
/*****************************************************************************/
-#define _nm_packed __attribute__ ((packed))
-#define _nm_unused __attribute__ ((unused))
-#define _nm_pure __attribute__ ((pure))
-#define _nm_const __attribute__ ((const))
-#define _nm_printf(a,b) __attribute__ ((__format__ (__printf__, a, b)))
+#ifdef thread_local
+#define _nm_thread_local thread_local
+/*
+ * Don't break on glibc < 2.16 that doesn't define __STDC_NO_THREADS__
+ * see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53769
+ */
+#elif __STDC_VERSION__ >= 201112L && !(defined(__STDC_NO_THREADS__) || (defined(__GNU_LIBRARY__) &&
__GLIBC__ == 2 && __GLIBC_MINOR__ < 16))
+#define _nm_thread_local _Thread_local
+#else
+#define _nm_thread_local __thread
+#endif
+
+/*****************************************************************************/
+
+#include "nm-glib.h"
+
+/*****************************************************************************/
#define nm_offsetofend(t,m) (G_STRUCT_OFFSET (t,m) + sizeof (((t *) NULL)->m))
#define nm_auto(fcn) __attribute__ ((cleanup(fcn)))
+static inline int nm_close (int fd);
+
/**
* nm_auto_free:
*
@@ -49,6 +70,30 @@
GS_DEFINE_CLEANUP_FUNCTION(void*, _nm_auto_free_impl, free)
static inline void
+nm_free_secret (char *secret)
+{
+ if (secret) {
+ memset (secret, 0, strlen (secret));
+ g_free (secret);
+ }
+}
+
+static inline void
+_nm_auto_free_secret_impl (char **v)
+{
+ nm_free_secret (*v);
+}
+
+/**
+ * nm_auto_free_secret:
+ *
+ * Call g_free() on a variable location when it goes out of scope.
+ * Also, previously, calls memset(loc, 0, strlen(loc)) to clear out
+ * the secret.
+ */
+#define nm_auto_free_secret nm_auto(_nm_auto_free_secret_impl)
+
+static inline void
_nm_auto_unset_gvalue_impl (GValue *v)
{
g_value_unset (v);
@@ -77,7 +122,7 @@ _nm_auto_close_impl (int *pfd)
if (*pfd >= 0) {
int errsv = errno;
- (void) close (*pfd);
+ (void) nm_close (*pfd);
errno = errsv;
}
}
@@ -242,31 +287,137 @@ NM_G_ERROR_MSG (GError *error)
/*****************************************************************************/
-#if (defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 9 ))) || (defined
(__clang__))
+#ifndef _NM_CC_SUPPORT_AUTO_TYPE
+#if (defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9 )))
+#define _NM_CC_SUPPORT_AUTO_TYPE 1
+#else
+#define _NM_CC_SUPPORT_AUTO_TYPE 0
+#endif
+#endif
+
+#ifndef _NM_CC_SUPPORT_GENERIC
+#if (defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9 ))) || (defined
(__clang__))
#define _NM_CC_SUPPORT_GENERIC 1
#else
#define _NM_CC_SUPPORT_GENERIC 0
#endif
+#endif
+
+#if _NM_CC_SUPPORT_AUTO_TYPE
+#define _nm_auto_type __auto_type
+#endif
#if _NM_CC_SUPPORT_GENERIC
-#define _NM_CONSTCAST(type, obj) \
- (_Generic ((obj), \
- void * : ((type *) (obj)), \
- void *const : ((type *) (obj)), \
- const void * : ((const type *) (obj)), \
- const void *const: ((const type *) (obj)), \
- const type * : (obj), \
- const type *const: (obj), \
- type * : (obj), \
- type *const : (obj)))
+#define _NM_CONSTCAST_FULL_1(type, obj_expr, obj) \
+ (_Generic ((obj_expr), \
+ const void *const: ((const type *) (obj)), \
+ const void * : ((const type *) (obj)), \
+ void *const: (( type *) (obj)), \
+ void * : (( type *) (obj)), \
+ const type *const: ((const type *) (obj)), \
+ const type * : ((const type *) (obj)), \
+ type *const: (( type *) (obj)), \
+ type * : (( type *) (obj))))
+#define _NM_CONSTCAST_FULL_2(type, obj_expr, obj, alias_type2) \
+ (_Generic ((obj_expr), \
+ const void *const: ((const type *) (obj)), \
+ const void * : ((const type *) (obj)), \
+ void *const: (( type *) (obj)), \
+ void * : (( type *) (obj)), \
+ const alias_type2 *const: ((const type *) (obj)), \
+ const alias_type2 * : ((const type *) (obj)), \
+ alias_type2 *const: (( type *) (obj)), \
+ alias_type2 * : (( type *) (obj)), \
+ const type *const: ((const type *) (obj)), \
+ const type * : ((const type *) (obj)), \
+ type *const: (( type *) (obj)), \
+ type * : (( type *) (obj))))
+#define _NM_CONSTCAST_FULL_3(type, obj_expr, obj, alias_type2, alias_type3) \
+ (_Generic ((obj_expr), \
+ const void *const: ((const type *) (obj)), \
+ const void * : ((const type *) (obj)), \
+ void *const: (( type *) (obj)), \
+ void * : (( type *) (obj)), \
+ const alias_type2 *const: ((const type *) (obj)), \
+ const alias_type2 * : ((const type *) (obj)), \
+ alias_type2 *const: (( type *) (obj)), \
+ alias_type2 * : (( type *) (obj)), \
+ const alias_type3 *const: ((const type *) (obj)), \
+ const alias_type3 * : ((const type *) (obj)), \
+ alias_type3 *const: (( type *) (obj)), \
+ alias_type3 * : (( type *) (obj)), \
+ const type *const: ((const type *) (obj)), \
+ const type * : ((const type *) (obj)), \
+ type *const: (( type *) (obj)), \
+ type * : (( type *) (obj))))
+#define _NM_CONSTCAST_FULL_4(type, obj_expr, obj, alias_type2, alias_type3, alias_type4) \
+ (_Generic ((obj_expr), \
+ const void *const: ((const type *) (obj)), \
+ const void * : ((const type *) (obj)), \
+ void *const: (( type *) (obj)), \
+ void * : (( type *) (obj)), \
+ const alias_type2 *const: ((const type *) (obj)), \
+ const alias_type2 * : ((const type *) (obj)), \
+ alias_type2 *const: (( type *) (obj)), \
+ alias_type2 * : (( type *) (obj)), \
+ const alias_type3 *const: ((const type *) (obj)), \
+ const alias_type3 * : ((const type *) (obj)), \
+ alias_type3 *const: (( type *) (obj)), \
+ alias_type3 * : (( type *) (obj)), \
+ const alias_type4 *const: ((const type *) (obj)), \
+ const alias_type4 * : ((const type *) (obj)), \
+ alias_type4 *const: (( type *) (obj)), \
+ alias_type4 * : (( type *) (obj)), \
+ const type *const: ((const type *) (obj)), \
+ const type * : ((const type *) (obj)), \
+ type *const: (( type *) (obj)), \
+ type * : (( type *) (obj))))
+#define _NM_CONSTCAST_FULL_x(type, obj_expr, obj, n, ...) (_NM_CONSTCAST_FULL_##n (type, obj_expr, obj,
##__VA_ARGS__))
+#define _NM_CONSTCAST_FULL_y(type, obj_expr, obj, n, ...) (_NM_CONSTCAST_FULL_x (type, obj_expr, obj, n,
##__VA_ARGS__))
+#define NM_CONSTCAST_FULL( type, obj_expr, obj, ...) (_NM_CONSTCAST_FULL_y (type, obj_expr, obj,
NM_NARG (dummy, ##__VA_ARGS__), ##__VA_ARGS__))
#else
-/* _NM_CONSTCAST() is there to preserve constness of a pointer.
- * It uses C11's _Generic(). If that is not supported, we fall back
- * to casting away constness. So, with _Generic, we get some additional
- * static type checking by preserving constness, without, we cast it
- * to a non-const pointer. */
-#define _NM_CONSTCAST(type, obj) \
- ((type *) (obj))
+#define NM_CONSTCAST_FULL( type, obj_expr, obj, ...) ((type *) (obj))
+#endif
+
+#define NM_CONSTCAST(type, obj, ...) \
+ NM_CONSTCAST_FULL(type, (obj), (obj), ##__VA_ARGS__)
+
+#define NM_GOBJECT_CAST(type, obj, is_check, ...) \
+ ({ \
+ const void *_obj = (obj); \
+ \
+ nm_assert (_obj || (is_check (_obj))); \
+ NM_CONSTCAST_FULL (type, (obj), _obj, GObject, ##__VA_ARGS__); \
+ })
+
+#define NM_GOBJECT_CAST_NON_NULL(type, obj, is_check, ...) \
+ ({ \
+ const void *_obj = (obj); \
+ \
+ nm_assert (is_check (_obj)); \
+ NM_CONSTCAST_FULL (type, (obj), _obj, GObject, ##__VA_ARGS__); \
+ })
+
+#if _NM_CC_SUPPORT_GENERIC
+/* returns @value, if the type of @value matches @type.
+ * This requires support for C11 _Generic(). If no support is
+ * present, this returns @value directly.
+ *
+ * It's useful to check the let the compiler ensure that @value is
+ * of a certain type. */
+#define _NM_ENSURE_TYPE(type, value) (_Generic ((value), type: (value)))
+#else
+#define _NM_ENSURE_TYPE(type, value) (value)
+#endif
+
+#if _NM_CC_SUPPORT_GENERIC
+#define NM_PROPAGATE_CONST(test_expr, ptr) \
+ (_Generic ((test_expr), \
+ const typeof (*(test_expr)) *: ((const typeof (*(ptr)) *) (ptr)), \
+ default: (_Generic ((test_expr), \
+ typeof (*(test_expr)) *: (ptr)))))
+#else
+#define NM_PROPAGATE_CONST(test_expr, ptr) (ptr)
#endif
/*****************************************************************************/
@@ -410,21 +561,6 @@ _NM_IN_STRSET_streq (const char *x, const char *s)
/*****************************************************************************/
-static inline guint
-NM_HASH_COMBINE (guint h, guint val)
-{
- /* see g_str_hash() for reasons */
- return (h << 5) + h + val;
-}
-
-static inline guint
-NM_HASH_COMBINE_UINT64 (guint h, guint64 val)
-{
- return NM_HASH_COMBINE (h, (((guint) val) & 0xFFFFFFFFu) + ((guint) (val >> 32)));
-}
-
-/*****************************************************************************/
-
/* NM_CACHED_QUARK() returns the GQuark for @string, but caches
* it in a static variable to speed up future lookups.
*
@@ -563,39 +699,17 @@ _notify (obj_type *obj, _PropertyEnums prop) \
/*****************************************************************************/
-/* these are implemented as a macro, because they accept self
- * as both (type*) and (const type*), and return a const
- * private pointer accordingly. */
-#define __NM_GET_PRIVATE(self, type, is_check, addrop) \
+#define _NM_GET_PRIVATE(self, type, is_check, ...) (&(NM_GOBJECT_CAST_NON_NULL (type, (self), is_check,
##__VA_ARGS__)->_priv))
+#if _NM_CC_SUPPORT_AUTO_TYPE
+#define _NM_GET_PRIVATE_PTR(self, type, is_check, ...) \
({ \
- /* preserve the const-ness of self. Unfortunately, that
- * way, @self cannot be a void pointer */ \
- typeof (self) _self = (self); \
- \
- /* Get compiler error if variable is of wrong type */ \
- _nm_unused const type *const _self2 = (_self); \
+ _nm_auto_type _self = NM_GOBJECT_CAST_NON_NULL (type, (self), is_check, ##__VA_ARGS__); \
\
- nm_assert (is_check (_self)); \
- ( addrop ( _NM_CONSTCAST (type, _self)->_priv) ); \
+ NM_PROPAGATE_CONST (_self, _self->_priv); \
})
-
-#define _NM_GET_PRIVATE(self, type, is_check) __NM_GET_PRIVATE(self, type, is_check, &)
-#define _NM_GET_PRIVATE_PTR(self, type, is_check) __NM_GET_PRIVATE(self, type, is_check, )
-
-#define __NM_GET_PRIVATE_VOID(self, type, is_check, result_cmd) \
- ({ \
- /* (self) can be any non-const pointer. It will be cast to "type *".
- * We don't explicitly cast but assign first to (void *) which
- * will fail if @self is pointing to const. */ \
- void *const _self1 = (self); \
- type *const _self = _self1; \
- \
- nm_assert (is_check (_self)); \
- ( result_cmd ); \
- })
-
-#define _NM_GET_PRIVATE_VOID(self, type, is_check) __NM_GET_PRIVATE_VOID(self, type, is_check,
&_self->_priv)
-#define _NM_GET_PRIVATE_PTR_VOID(self, type, is_check) __NM_GET_PRIVATE_VOID(self, type, is_check,
_self->_priv)
+#else
+#define _NM_GET_PRIVATE_PTR(self, type, is_check, ...) (NM_GOBJECT_CAST_NON_NULL (type, (self), is_check,
##__VA_ARGS__)->_priv)
+#endif
/*****************************************************************************/
@@ -619,6 +733,36 @@ nm_g_object_unref (gpointer obj)
g_object_unref (obj);
}
+/* Assigns GObject @obj to destination @pdst, and takes an additional ref.
+ * The previous value of @pdst is unrefed.
+ *
+ * It makes sure to first increase the ref-count of @obj, and handles %NULL
+ * @obj correctly.
+ * */
+#define nm_g_object_ref_set(pp, obj) \
+ ({ \
+ typeof (*(pp)) *const _pp = (pp); \
+ typeof (**_pp) *const _obj = (obj); \
+ typeof (**_pp) *_p; \
+ gboolean _changed = FALSE; \
+ \
+ if ( _pp \
+ && ((_p = *_pp) != _obj)) { \
+ if (_obj) { \
+ nm_assert (G_IS_OBJECT (_obj)); \
+ g_object_ref (_obj); \
+ } \
+ if (_p) { \
+ nm_assert (G_IS_OBJECT (_p)); \
+ *_pp = NULL; \
+ g_object_unref (_p); \
+ } \
+ *_pp = _obj; \
+ _changed = TRUE; \
+ } \
+ _changed; \
+ })
+
/* basically, replaces
* g_clear_pointer (&location, g_free)
* with
@@ -631,13 +775,32 @@ nm_g_object_unref (gpointer obj)
#define nm_clear_g_free(pp) \
({ \
typeof (*(pp)) *_pp = (pp); \
- typeof (**_pp) *_p = *_pp; \
+ typeof (**_pp) *_p; \
+ gboolean _changed = FALSE; \
\
- if (_p) { \
+ if ( _pp \
+ && (_p = *_pp)) { \
*_pp = NULL; \
g_free (_p); \
+ _changed = TRUE; \
} \
- !!_p; \
+ _changed; \
+ })
+
+#define nm_clear_g_object(pp) \
+ ({ \
+ typeof (*(pp)) *_pp = (pp); \
+ typeof (**_pp) *_p; \
+ gboolean _changed = FALSE; \
+ \
+ if ( _pp \
+ && (_p = *_pp)) { \
+ nm_assert (G_IS_OBJECT (_p)); \
+ *_pp = NULL; \
+ g_object_unref (_p); \
+ _changed = TRUE; \
+ } \
+ _changed; \
})
static inline gboolean
@@ -809,6 +972,33 @@ nm_strstrip (char *str)
return str ? g_strstrip (str) : NULL;
}
+static inline const char *
+nm_strstrip_avoid_copy (const char *str, char **str_free)
+{
+ gsize l;
+ char *s;
+
+ nm_assert (str_free && !*str_free);
+
+ if (!str)
+ return NULL;
+
+ str = nm_str_skip_leading_spaces (str);
+ l = strlen (str);
+ if ( l == 0
+ || !g_ascii_isspace (str[l - 1]))
+ return str;
+ while ( l > 0
+ && g_ascii_isspace (str[l - 1]))
+ l--;
+
+ s = g_new (char, l + 1);
+ memcpy (s, str, l);
+ s[l] = '\0';
+ *str_free = s;
+ return s;
+}
+
/* g_ptr_array_sort()'s compare function takes pointers to the
* value. Thus, you cannot use strcmp directly. You can use
* nm_strcmp_p().
@@ -1057,4 +1247,34 @@ nm_decode_version (guint version, guint *major, guint *minor, guint *micro)
/*****************************************************************************/
+static inline int
+nm_steal_fd (int *p_fd)
+{
+ int fd;
+
+ if ( p_fd
+ && ((fd = *p_fd) >= 0)) {
+ *p_fd = -1;
+ return fd;
+ }
+ return -1;
+}
+
+/**
+ * nm_close:
+ *
+ * Like close() but throws an assertion if the input fd is
+ * invalid. Closing an invalid fd is a programming error, so
+ * it's better to catch it early.
+ */
+static inline int
+nm_close (int fd)
+{
+ int r;
+
+ r = close (fd);
+ nm_assert (r != -1 || fd < 0 || errno != EBADF);
+ return r;
+}
+
#endif /* __NM_MACROS_INTERNAL_H__ */
diff --git a/shared/nm-utils/nm-shared-utils.c b/shared/nm-utils/nm-shared-utils.c
index 0109818..79d1e6a 100644
--- a/shared/nm-utils/nm-shared-utils.c
+++ b/shared/nm-utils/nm-shared-utils.c
@@ -25,6 +25,8 @@
#include <errno.h>
#include <arpa/inet.h>
+#include <poll.h>
+#include <fcntl.h>
/*****************************************************************************/
@@ -32,6 +34,10 @@ const void *const _NM_PTRARRAY_EMPTY[1] = { NULL };
/*****************************************************************************/
+const NMIPAddr nm_ip_addr_zero = { 0 };
+
+/*****************************************************************************/
+
void
nm_utils_strbuf_append_c (char **buf, gsize *len, char c)
{
@@ -112,6 +118,162 @@ nm_utils_strbuf_append (char **buf, gsize *len, const char *format, ...)
/*****************************************************************************/
/**
+ * nm_strquote:
+ * @buf: the output buffer of where to write the quoted @str argument.
+ * @buf_len: the size of @buf.
+ * @str: (allow-none): the string to quote.
+ *
+ * Writes @str to @buf with quoting. The resulting buffer
+ * is always NUL terminated, unless @buf_len is zero.
+ * If @str is %NULL, it writes "(null)".
+ *
+ * If @str needs to be truncated, the closing quote is '^' instead
+ * of '"'.
+ *
+ * This is similar to nm_strquote_a(), which however uses alloca()
+ * to allocate a new buffer. Also, here @buf_len is the size of @buf,
+ * while nm_strquote_a() has the number of characters to print. The latter
+ * doesn't include the quoting.
+ *
+ * Returns: the input buffer with the quoted string.
+ */
+const char *
+nm_strquote (char *buf, gsize buf_len, const char *str)
+{
+ const char *const buf0 = buf;
+
+ if (!str) {
+ nm_utils_strbuf_append_str (&buf, &buf_len, "(null)");
+ goto out;
+ }
+
+ if (G_UNLIKELY (buf_len <= 2)) {
+ switch (buf_len) {
+ case 2:
+ *(buf++) = '^';
+ /* fall-through */
+ case 1:
+ *(buf++) = '\0';
+ break;
+ }
+ goto out;
+ }
+
+ *(buf++) = '"';
+ buf_len--;
+
+ nm_utils_strbuf_append_str (&buf, &buf_len, str);
+
+ /* if the string was too long we indicate truncation with a
+ * '^' instead of a closing quote. */
+ if (G_UNLIKELY (buf_len <= 1)) {
+ switch (buf_len) {
+ case 1:
+ buf[-1] = '^';
+ break;
+ case 0:
+ buf[-2] = '^';
+ break;
+ default:
+ nm_assert_not_reached ();
+ break;
+ }
+ } else {
+ nm_assert (buf_len >= 2);
+ *(buf++) = '"';
+ *(buf++) = '\0';
+ }
+
+out:
+ return buf0;
+}
+
+/*****************************************************************************/
+
+char _nm_utils_to_string_buffer[];
+
+void
+nm_utils_to_string_buffer_init (char **buf, gsize *len)
+{
+ if (!*buf) {
+ *buf = _nm_utils_to_string_buffer;
+ *len = sizeof (_nm_utils_to_string_buffer);
+ }
+}
+
+gboolean
+nm_utils_to_string_buffer_init_null (gconstpointer obj, char **buf, gsize *len)
+{
+ nm_utils_to_string_buffer_init (buf, len);
+ if (!obj) {
+ g_strlcpy (*buf, "(null)", *len);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*****************************************************************************/
+
+const char *
+nm_utils_flags2str (const NMUtilsFlags2StrDesc *descs,
+ gsize n_descs,
+ unsigned flags,
+ char *buf,
+ gsize len)
+{
+ gsize i;
+ char *p;
+
+#if NM_MORE_ASSERTS > 10
+ nm_assert (descs);
+ nm_assert (n_descs > 0);
+ for (i = 0; i < n_descs; i++) {
+ gsize j;
+
+ nm_assert (descs[i].name && descs[i].name[0]);
+ for (j = 0; j < i; j++)
+ nm_assert (descs[j].flag != descs[i].flag);
+ }
+#endif
+
+ nm_utils_to_string_buffer_init (&buf, &len);
+
+ if (!len)
+ return buf;
+
+ buf[0] = '\0';
+ p = buf;
+ if (!flags) {
+ for (i = 0; i < n_descs; i++) {
+ if (!descs[i].flag) {
+ nm_utils_strbuf_append_str (&p, &len, descs[i].name);
+ break;
+ }
+ }
+ return buf;
+ }
+
+ for (i = 0; flags && i < n_descs; i++) {
+ if ( descs[i].flag
+ && NM_FLAGS_ALL (flags, descs[i].flag)) {
+ flags &= ~descs[i].flag;
+
+ if (buf[0] != '\0')
+ nm_utils_strbuf_append_c (&p, &len, ',');
+ nm_utils_strbuf_append_str (&p, &len, descs[i].name);
+ }
+ }
+ if (flags) {
+ if (buf[0] != '\0')
+ nm_utils_strbuf_append_c (&p, &len, ',');
+ nm_utils_strbuf_append (&p, &len, "0x%x", flags);
+ }
+ return buf;
+};
+
+/*****************************************************************************/
+
+/**
* _nm_utils_ip4_prefix_to_netmask:
* @prefix: a CIDR prefix
*
@@ -170,52 +332,79 @@ nm_utils_ip_is_site_local (int addr_family,
/*****************************************************************************/
gboolean
-nm_utils_parse_inaddr (const char *text,
- int family,
- char **out_addr)
+nm_utils_parse_inaddr_bin (int addr_family,
+ const char *text,
+ gpointer out_addr)
{
- union {
- in_addr_t v4;
- struct in6_addr v6;
- } addrbin;
- char addrstr_buf[MAX (INET_ADDRSTRLEN, INET6_ADDRSTRLEN)];
+ NMIPAddr addrbin;
g_return_val_if_fail (text, FALSE);
- if (family == AF_UNSPEC)
- family = strchr (text, ':') ? AF_INET6 : AF_INET;
+ if (addr_family == AF_UNSPEC)
+ addr_family = strchr (text, ':') ? AF_INET6 : AF_INET;
else
- g_return_val_if_fail (NM_IN_SET (family, AF_INET, AF_INET6), FALSE);
+ g_return_val_if_fail (NM_IN_SET (addr_family, AF_INET, AF_INET6), FALSE);
- if (inet_pton (family, text, &addrbin) != 1)
+ /* use a temporary variable @addrbin, to guarantee that @out_addr
+ * is only modified on success. */
+ if (inet_pton (addr_family, text, &addrbin) != 1)
return FALSE;
- NM_SET_OUT (out_addr, g_strdup (inet_ntop (family, &addrbin, addrstr_buf, sizeof (addrstr_buf))));
+ if (out_addr) {
+ switch (addr_family) {
+ case AF_INET:
+ *((in_addr_t *) out_addr) = addrbin.addr4;
+ break;
+ case AF_INET6:
+ *((struct in6_addr *) out_addr) = addrbin.addr6;
+ break;
+ default:
+ nm_assert_not_reached ();
+ }
+ }
return TRUE;
}
gboolean
-nm_utils_parse_inaddr_prefix (const char *text,
- int family,
- char **out_addr,
- int *out_prefix)
+nm_utils_parse_inaddr (int addr_family,
+ const char *text,
+ char **out_addr)
+{
+ NMIPAddr addrbin;
+ char addrstr_buf[MAX (INET_ADDRSTRLEN, INET6_ADDRSTRLEN)];
+
+ nm_assert (!out_addr || !*out_addr);
+
+ if (!nm_utils_parse_inaddr_bin (addr_family, text, &addrbin))
+ return FALSE;
+ NM_SET_OUT (out_addr, g_strdup (inet_ntop (addr_family, &addrbin, addrstr_buf, sizeof
(addrstr_buf))));
+ return TRUE;
+}
+
+gboolean
+nm_utils_parse_inaddr_prefix_bin (int addr_family,
+ const char *text,
+ gpointer out_addr,
+ int *out_prefix)
{
gs_free char *addrstr_free = NULL;
int prefix = -1;
const char *slash;
const char *addrstr;
- union {
- in_addr_t v4;
- struct in6_addr v6;
- } addrbin;
- char addrstr_buf[MAX (INET_ADDRSTRLEN, INET6_ADDRSTRLEN)];
+ NMIPAddr addrbin;
+ int addr_len;
g_return_val_if_fail (text, FALSE);
- if (family == AF_UNSPEC)
- family = strchr (text, ':') ? AF_INET6 : AF_INET;
+ if (addr_family == AF_UNSPEC)
+ addr_family = strchr (text, ':') ? AF_INET6 : AF_INET;
+
+ if (addr_family == AF_INET)
+ addr_len = sizeof (in_addr_t);
+ else if (addr_family == AF_INET6)
+ addr_len = sizeof (struct in6_addr);
else
- g_return_val_if_fail (NM_IN_SET (family, AF_INET, AF_INET6), FALSE);
+ g_return_val_if_reached (FALSE);
slash = strchr (text, '/');
if (slash)
@@ -223,23 +412,39 @@ nm_utils_parse_inaddr_prefix (const char *text,
else
addrstr = text;
- if (inet_pton (family, addrstr, &addrbin) != 1)
+ if (inet_pton (addr_family, addrstr, &addrbin) != 1)
return FALSE;
if (slash) {
prefix = _nm_utils_ascii_str_to_int64 (slash + 1, 10,
0,
- family == AF_INET ? 32 : 128,
+ addr_family == AF_INET ? 32 : 128,
-1);
if (prefix == -1)
return FALSE;
}
- NM_SET_OUT (out_addr, g_strdup (inet_ntop (family, &addrbin, addrstr_buf, sizeof (addrstr_buf))));
+ if (out_addr)
+ memcpy (out_addr, &addrbin, addr_len);
NM_SET_OUT (out_prefix, prefix);
return TRUE;
}
+gboolean
+nm_utils_parse_inaddr_prefix (int addr_family,
+ const char *text,
+ char **out_addr,
+ int *out_prefix)
+{
+ NMIPAddr addrbin;
+ char addrstr_buf[MAX (INET_ADDRSTRLEN, INET6_ADDRSTRLEN)];
+
+ if (!nm_utils_parse_inaddr_prefix_bin (addr_family, text, &addrbin, out_prefix))
+ return FALSE;
+ NM_SET_OUT (out_addr, g_strdup (inet_ntop (addr_family, &addrbin, addrstr_buf, sizeof
(addrstr_buf))));
+ return TRUE;
+}
+
/*****************************************************************************/
/* _nm_utils_ascii_str_to_int64:
@@ -295,6 +500,118 @@ _nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 ma
/*****************************************************************************/
/**
+ * nm_utils_strsplit_set:
+ * @str: the string to split.
+ * @delimiters: the set of delimiters. If %NULL, defaults to " \t\n",
+ * like bash's $IFS.
+ *
+ * This is a replacement for g_strsplit_set() which avoids copying
+ * each word once (the entire strv array), but instead copies it once
+ * and all words point into that internal copy.
+ *
+ * Another difference from g_strsplit_set() is that this never returns
+ * empty words. Multiple delimiters are combined and treated as one.
+ *
+ * Returns: %NULL if @str is %NULL or contains only delimiters.
+ * Otherwise, a %NULL terminated strv array containing non-empty
+ * words, split at the delimiter characters (delimiter characters
+ * are removed).
+ * The strings to which the result strv array points to are allocated
+ * after the returned result itself. Don't free the strings themself,
+ * but free everything with g_free().
+ */
+const char **
+nm_utils_strsplit_set (const char *str, const char *delimiters)
+{
+ const char **ptr, **ptr0;
+ gsize alloc_size, plen, i;
+ gsize str_len;
+ char *s0;
+ char *s;
+ guint8 delimiters_table[256];
+
+ if (!str)
+ return NULL;
+
+ /* initialize lookup table for delimiter */
+ if (!delimiters)
+ delimiters = " \t\n";
+ memset (delimiters_table, 0, sizeof (delimiters_table));
+ for (i = 0; delimiters[i]; i++)
+ delimiters_table[(guint8) delimiters[i]] = 1;
+
+#define _is_delimiter(ch, delimiters_table) \
+ ((delimiters_table)[(guint8) (ch)] != 0)
+
+ /* skip initial delimiters, and return of the remaining string is
+ * empty. */
+ while (_is_delimiter (str[0], delimiters_table))
+ str++;
+ if (!str[0])
+ return NULL;
+
+ str_len = strlen (str) + 1;
+ alloc_size = 8;
+
+ /* we allocate the buffer larger, so to copy @str at the
+ * end of it as @s0. */
+ ptr0 = g_malloc ((sizeof (const char *) * (alloc_size + 1)) + str_len);
+ s0 = (char *) &ptr0[alloc_size + 1];
+ memcpy (s0, str, str_len);
+
+ plen = 0;
+ s = s0;
+ ptr = ptr0;
+
+ while (TRUE) {
+ if (plen >= alloc_size) {
+ const char **ptr_old = ptr;
+
+ /* reallocate the buffer. Note that for now the string
+ * continues to be in ptr0/s0. We fix that at the end. */
+ alloc_size += 2;
+ ptr = g_malloc ((sizeof (const char *) * (alloc_size + 1)) + str_len);
+ memcpy (ptr, ptr_old, sizeof (const char *) * plen);
+ if (ptr_old != ptr0)
+ g_free (ptr_old);
+ }
+
+ ptr[plen++] = s;
+
+ nm_assert (s[0] && !_is_delimiter (s[0], delimiters_table));
+
+ while (TRUE) {
+ s++;
+ if (_is_delimiter (s[0], delimiters_table))
+ break;
+ if (s[0] == '\0')
+ goto done;
+ }
+
+ s[0] = '\0';
+ s++;
+ while (_is_delimiter (s[0], delimiters_table))
+ s++;
+ if (s[0] == '\0')
+ break;
+ }
+done:
+ ptr[plen] = NULL;
+
+ if (ptr != ptr0) {
+ /* we reallocated the buffer. We must copy over the
+ * string @s0 and adjust the pointers. */
+ s = (char *) &ptr[alloc_size + 1];
+ memcpy (s, s0, str_len);
+ for (i = 0; i < plen; i++)
+ ptr[i] = &s[ptr[i] - s0];
+ g_free (ptr0);
+ }
+
+ return ptr;
+}
+
+/**
* nm_utils_strv_find_first:
* @list: the strv list to search
* @len: the length of the list, or a negative value if @list is %NULL terminated.
@@ -677,3 +994,98 @@ nm_utils_str_utf8safe_escape_take (char *str, NMUtilsStrUtf8SafeFlags flags)
}
return str;
}
+
+/*****************************************************************************/
+
+/* taken from systemd's fd_wait_for_event(). Note that the timeout
+ * is here in nano-seconds, not micro-seconds. */
+int
+nm_utils_fd_wait_for_event (int fd, int event, gint64 timeout_ns)
+{
+ struct pollfd pollfd = {
+ .fd = fd,
+ .events = event,
+ };
+ struct timespec ts, *pts;
+ int r;
+
+ if (timeout_ns < 0)
+ pts = NULL;
+ else {
+ ts.tv_sec = (time_t) (timeout_ns / NM_UTILS_NS_PER_SECOND);
+ ts.tv_nsec = (long int) (timeout_ns % NM_UTILS_NS_PER_SECOND);
+ pts = &ts;
+ }
+
+ r = ppoll (&pollfd, 1, pts, NULL);
+ if (r < 0)
+ return -errno;
+ if (r == 0)
+ return 0;
+ return pollfd.revents;
+}
+
+/* taken from systemd's loop_read() */
+ssize_t
+nm_utils_fd_read_loop (int fd, void *buf, size_t nbytes, bool do_poll)
+{
+ uint8_t *p = buf;
+ ssize_t n = 0;
+
+ g_return_val_if_fail (fd >= 0, -EINVAL);
+ g_return_val_if_fail (buf, -EINVAL);
+
+ /* If called with nbytes == 0, let's call read() at least
+ * once, to validate the operation */
+
+ if (nbytes > (size_t) SSIZE_MAX)
+ return -EINVAL;
+
+ do {
+ ssize_t k;
+
+ k = read (fd, p, nbytes);
+ if (k < 0) {
+ if (errno == EINTR)
+ continue;
+
+ if (errno == EAGAIN && do_poll) {
+
+ /* We knowingly ignore any return value here,
+ * and expect that any error/EOF is reported
+ * via read() */
+
+ (void) nm_utils_fd_wait_for_event (fd, POLLIN, -1);
+ continue;
+ }
+
+ return n > 0 ? n : -errno;
+ }
+
+ if (k == 0)
+ return n;
+
+ g_assert ((size_t) k <= nbytes);
+
+ p += k;
+ nbytes -= k;
+ n += k;
+ } while (nbytes > 0);
+
+ return n;
+}
+
+/* taken from systemd's loop_read_exact() */
+int
+nm_utils_fd_read_loop_exact (int fd, void *buf, size_t nbytes, bool do_poll)
+{
+ ssize_t n;
+
+ n = nm_utils_fd_read_loop (fd, buf, nbytes, do_poll);
+ if (n < 0)
+ return (int) n;
+ if ((size_t) n != nbytes)
+ return -EIO;
+
+ return 0;
+}
diff --git a/shared/nm-utils/nm-shared-utils.h b/shared/nm-utils/nm-shared-utils.h
index 8d1085f..a092a6b 100644
--- a/shared/nm-utils/nm-shared-utils.h
+++ b/shared/nm-utils/nm-shared-utils.h
@@ -22,6 +22,63 @@
#ifndef __NM_SHARED_UTILS_H__
#define __NM_SHARED_UTILS_H__
+#include <netinet/in.h>
+
+/*****************************************************************************/
+
+static inline char
+nm_utils_addr_family_to_char (int addr_family)
+{
+ switch (addr_family) {
+ case AF_INET: return '4';
+ case AF_INET6: return '6';
+ }
+ g_return_val_if_reached ('?');
+}
+
+static inline gsize
+nm_utils_addr_family_to_size (int addr_family)
+{
+ switch (addr_family) {
+ case AF_INET: return sizeof (in_addr_t);
+ case AF_INET6: return sizeof (struct in6_addr);
+ }
+ g_return_val_if_reached (0);
+}
+
+#define nm_assert_addr_family(addr_family) \
+ nm_assert (NM_IN_SET ((addr_family), AF_INET, AF_INET6))
+
+/*****************************************************************************/
+
+typedef struct {
+ union {
+ guint8 addr_ptr[1];
+ in_addr_t addr4;
+ struct in6_addr addr6;
+
+ /* NMIPAddr is really a union for IP addresses.
+ * However, as ethernet addresses fit in here nicely, use
+ * it also for an ethernet MAC address. */
+ guint8 addr_eth[6 /*ETH_ALEN*/];
+ };
+} NMIPAddr;
+
+extern const NMIPAddr nm_ip_addr_zero;
+
+static inline void
+nm_ip_addr_set (int addr_family, gpointer dst, const NMIPAddr *src)
+{
+ nm_assert_addr_family (addr_family);
+ nm_assert (dst);
+ nm_assert (src);
+
+ if (addr_family != AF_INET6)
+ *((in_addr_t *) dst) = src->addr4;
+ else
+ *((struct in6_addr *) dst) = src->addr6;
+}
+
/*****************************************************************************/
#define NM_CMP_RETURN(c) \
@@ -132,8 +189,12 @@ void nm_utils_strbuf_append (char **buf, gsize *len, const char *format, ...) _n
void nm_utils_strbuf_append_c (char **buf, gsize *len, char c);
void nm_utils_strbuf_append_str (char **buf, gsize *len, const char *str);
+const char *nm_strquote (char *buf, gsize buf_len, const char *str);
+
/*****************************************************************************/
+const char **nm_utils_strsplit_set (const char *str, const char *delimiters);
+
gssize nm_utils_strv_find_first (char **list, gssize len, const char *needle);
char **_nm_utils_strv_cleanup (char **strv,
@@ -151,12 +212,21 @@ gboolean nm_utils_ip_is_site_local (int addr_family,
/*****************************************************************************/
-gboolean nm_utils_parse_inaddr (const char *text,
- int family,
+gboolean nm_utils_parse_inaddr_bin (int addr_family,
+ const char *text,
+ gpointer out_addr);
+
+gboolean nm_utils_parse_inaddr (int addr_family,
+ const char *text,
char **out_addr);
-gboolean nm_utils_parse_inaddr_prefix (const char *text,
- int family,
+gboolean nm_utils_parse_inaddr_prefix_bin (int addr_family,
+ const char *text,
+ gpointer out_addr,
+ int *out_prefix);
+
+gboolean nm_utils_parse_inaddr_prefix (int addr_family,
+ const char *text,
char **out_addr,
int *out_prefix);
@@ -167,6 +237,74 @@ gint _nm_utils_ascii_str_to_bool (const char *str,
/*****************************************************************************/
+extern char _nm_utils_to_string_buffer[2096];
+
+void nm_utils_to_string_buffer_init (char **buf, gsize *len);
+gboolean nm_utils_to_string_buffer_init_null (gconstpointer obj, char **buf, gsize *len);
+
+/*****************************************************************************/
+
+typedef struct {
+ unsigned flag;
+ const char *name;
+} NMUtilsFlags2StrDesc;
+
+#define NM_UTILS_FLAGS2STR(f, n) { .flag = f, .name = ""n, }
+
+#define _NM_UTILS_FLAGS2STR_DEFINE(scope, fcn_name, flags_type, ...) \
+scope const char * \
+fcn_name (flags_type flags, char *buf, gsize len) \
+{ \
+ static const NMUtilsFlags2StrDesc descs[] = { \
+ __VA_ARGS__ \
+ }; \
+ G_STATIC_ASSERT (sizeof (flags_type) <= sizeof (unsigned)); \
+ return nm_utils_flags2str (descs, G_N_ELEMENTS (descs), flags, buf, len); \
+};
+
+#define NM_UTILS_FLAGS2STR_DEFINE(fcn_name, flags_type, ...) \
+ _NM_UTILS_FLAGS2STR_DEFINE (, fcn_name, flags_type, __VA_ARGS__)
+#define NM_UTILS_FLAGS2STR_DEFINE_STATIC(fcn_name, flags_type, ...) \
+ _NM_UTILS_FLAGS2STR_DEFINE (static, fcn_name, flags_type, __VA_ARGS__)
+
+const char *nm_utils_flags2str (const NMUtilsFlags2StrDesc *descs,
+ gsize n_descs,
+ unsigned flags,
+ char *buf,
+ gsize len);
+
+/*****************************************************************************/
+
+#define NM_UTILS_ENUM2STR(v, n) (void) 0; case v: s = ""n""; break; (void) 0
+#define NM_UTILS_ENUM2STR_IGNORE(v) (void) 0; case v: break; (void) 0
+
+#define _NM_UTILS_ENUM2STR_DEFINE(scope, fcn_name, lookup_type, int_fmt, ...) \
+scope const char * \
+fcn_name (lookup_type val, char *buf, gsize len) \
+{ \
+ nm_utils_to_string_buffer_init (&buf, &len); \
+ if (len) { \
+ const char *s = NULL; \
+ switch (val) { \
+ (void) 0, \
+ __VA_ARGS__ \
+ (void) 0; \
+ }; \
+ if (s) \
+ g_strlcpy (buf, s, len); \
+ else \
+ g_snprintf (buf, len, "(%"int_fmt")", val); \
+ } \
+ return buf; \
+}
+
+#define NM_UTILS_ENUM2STR_DEFINE(fcn_name, lookup_type, ...) \
+ _NM_UTILS_ENUM2STR_DEFINE (, fcn_name, lookup_type, "d", __VA_ARGS__)
+#define NM_UTILS_ENUM2STR_DEFINE_STATIC(fcn_name, lookup_type, ...) \
+ _NM_UTILS_ENUM2STR_DEFINE (static, fcn_name, lookup_type, "d", __VA_ARGS__)
+
+/*****************************************************************************/
+
#define _nm_g_slice_free_fcn_define(mem_size) \
static inline void \
_nm_g_slice_free_fcn_##mem_size (gpointer mem_block) \
@@ -178,6 +316,7 @@ _nm_g_slice_free_fcn_define (1)
_nm_g_slice_free_fcn_define (2)
_nm_g_slice_free_fcn_define (4)
_nm_g_slice_free_fcn_define (8)
+_nm_g_slice_free_fcn_define (12)
_nm_g_slice_free_fcn_define (16)
#define _nm_g_slice_free_fcn1(mem_size) \
@@ -192,6 +331,7 @@ _nm_g_slice_free_fcn_define (16)
case 2: _fcn = _nm_g_slice_free_fcn_2; break; \
case 4: _fcn = _nm_g_slice_free_fcn_4; break; \
case 8: _fcn = _nm_g_slice_free_fcn_8; break; \
+ case 12: _fcn = _nm_g_slice_free_fcn_12; break; \
case 16: _fcn = _nm_g_slice_free_fcn_16; break; \
default: g_assert_not_reached (); _fcn = NULL; break; \
} \
@@ -267,4 +407,16 @@ char *nm_utils_str_utf8safe_escape_take (char *str, NMUtilsStrUtf8SafeFlags flag
/*****************************************************************************/
+#define NM_UTILS_NS_PER_SECOND ((gint64) 1000000000)
+#define NM_UTILS_NS_PER_MSEC ((gint64) 1000000)
+#define NM_UTILS_NS_TO_MSEC_CEIL(nsec) (((nsec) + (NM_UTILS_NS_PER_MSEC - 1)) / NM_UTILS_NS_PER_MSEC)
+
+/*****************************************************************************/
+
+int nm_utils_fd_wait_for_event (int fd, int event, gint64 timeout_ns);
+ssize_t nm_utils_fd_read_loop (int fd, void *buf, size_t nbytes, bool do_poll);
+int nm_utils_fd_read_loop_exact (int fd, void *buf, size_t nbytes, bool do_poll);
+
+/*****************************************************************************/
+
#endif /* __NM_SHARED_UTILS_H__ */
diff --git a/shared/nm-utils/nm-test-utils.h b/shared/nm-utils/nm-test-utils.h
index f7a87aa..8d3ff10 100644
--- a/shared/nm-utils/nm-test-utils.h
+++ b/shared/nm-utils/nm-test-utils.h
@@ -1697,6 +1697,62 @@ nmtst_assert_setting_verifies (NMSetting *setting)
g_assert (success);
}
+#if defined(__NM_SIMPLE_CONNECTION_H__) && NM_CHECK_VERSION (1, 10, 0) && (!defined (NM_VERSION_MAX_ALLOWED)
|| NM_VERSION_MAX_ALLOWED >= NM_VERSION_1_10)
+static inline void
+_nmtst_assert_connection_has_settings (NMConnection *connection, gboolean has_at_least, gboolean
has_at_most, ...)
+{
+ gs_unref_hashtable GHashTable *names = NULL;
+ gs_free NMSetting **settings = NULL;
+ va_list ap;
+ const char *name;
+ guint i, len;
+ gs_unref_ptrarray GPtrArray *names_arr = NULL;
+
+ g_assert (NM_IS_CONNECTION (connection));
+
+ names = g_hash_table_new (g_str_hash, g_str_equal);
+ names_arr = g_ptr_array_new ();
+
+ va_start (ap, has_at_most);
+ while ((name = va_arg (ap, const char *))) {
+ if (!nm_g_hash_table_add (names, (gpointer) name))
+ g_assert_not_reached ();
+ g_ptr_array_add (names_arr, (gpointer) name);
+ }
+ va_end (ap);
+
+ g_ptr_array_add (names_arr, NULL);
+
+ settings = nm_connection_get_settings (connection, &len);
+ for (i = 0; i < len; i++) {
+ if ( !g_hash_table_remove (names, nm_setting_get_name (settings[i]))
+ && has_at_most) {
+ g_error ("nmtst_assert_connection_has_settings(): has setting \"%s\" which is not
expected",
+ nm_setting_get_name (settings[i]));
+ }
+ }
+ if ( g_hash_table_size (names) > 0
+ && has_at_least) {
+ gs_free char *expected_str = g_strjoinv (" ", (char **) names_arr->pdata);
+ gs_free const char **settings_names = NULL;
+ gs_free char *has_str = NULL;
+
+ settings_names = g_new0 (const char *, len + 1);
+ for (i = 0; i < len; i++)
+ settings_names[i] = nm_setting_get_name (settings[i]);
+ has_str = g_strjoinv (" ", (char **) settings_names);
+
+ g_error ("nmtst_assert_connection_has_settings(): the setting lacks %u expected settings
(expected: [%s] vs. has: [%s])",
+ g_hash_table_size (names),
+ expected_str,
+ has_str);
+ }
+}
+#define nmtst_assert_connection_has_settings(connection, ...) _nmtst_assert_connection_has_settings
((connection), TRUE, TRUE, __VA_ARGS__, NULL)
+#define nmtst_assert_connection_has_settings_at_least(connection, ...) _nmtst_assert_connection_has_settings
((connection), TRUE, FALSE, __VA_ARGS__, NULL)
+#define nmtst_assert_connection_has_settings_at_most(connection, ...) _nmtst_assert_connection_has_settings
((connection), FALSE, TRUE, __VA_ARGS__, NULL)
+#endif
+
static inline void
nmtst_assert_setting_verify_fails (NMSetting *setting,
GQuark expect_error_domain,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]