diff options
| author | Michael Biebl <biebl@debian.org> | 2017-01-17 20:25:09 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2017-01-17 20:25:09 +0100 |
| commit | 58f8be580039b0575b197b9573a1c92745d96d30 (patch) | |
| tree | 2c226233f623a0dcb529be0eb8cdf97e4a2ae0c0 /shared/nm-utils | |
| parent | 45cb5bb3c0e6edb887cf69b417fcaf7053814a9b (diff) | |
New upstream version 1.5.90 upstream/1.5.90
Diffstat (limited to 'shared/nm-utils')
| -rw-r--r-- | shared/nm-utils/nm-macros-internal.h | 172 | ||||
| -rw-r--r-- | shared/nm-utils/nm-shared-utils.c | 83 | ||||
| -rw-r--r-- | shared/nm-utils/nm-shared-utils.h | 27 | ||||
| -rw-r--r-- | shared/nm-utils/nm-test-utils.h | 70 | ||||
| -rw-r--r-- | shared/nm-utils/nm-vpn-plugin-macros.h | 32 |
5 files changed, 362 insertions, 22 deletions
diff --git a/shared/nm-utils/nm-macros-internal.h b/shared/nm-utils/nm-macros-internal.h index de90e3f5..70476b7e 100644 --- a/shared/nm-utils/nm-macros-internal.h +++ b/shared/nm-utils/nm-macros-internal.h @@ -28,7 +28,7 @@ #include "nm-glib.h" -/********************************************************/ +/*****************************************************************************/ #define _nm_packed __attribute__ ((packed)) #define _nm_unused __attribute__ ((unused)) @@ -36,6 +36,8 @@ #define _nm_const __attribute__ ((const)) #define _nm_printf(a,b) __attribute__ ((__format__ (__printf__, a, b))) +#define nm_offsetofend(t,m) (G_STRUCT_OFFSET (t,m) + sizeof (((t *) NULL)->m)) + #define nm_auto(fcn) __attribute__ ((cleanup(fcn))) /** @@ -85,6 +87,13 @@ _nm_auto_fclose_impl (FILE **pfd) } #define nm_auto_fclose nm_auto(_nm_auto_fclose_impl) +static inline void +_nm_auto_protect_errno (int *p_saved_errno) +{ + errno = *p_saved_errno; +} +#define NM_AUTO_PROTECT_ERRNO(errsv_saved) nm_auto(_nm_auto_protect_errno) _nm_unused const int errsv_saved = (errno) + /*****************************************************************************/ /* http://stackoverflow.com/a/11172679 */ @@ -104,7 +113,7 @@ _nm_auto_fclose_impl (FILE **pfd) TWOORMORE, TWOORMORE, TWOORMORE, ONE, throwaway) #define __NM_UTILS_MACRO_REST_SELECT_20TH(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, ...) a20 -/********************************************************/ +/*****************************************************************************/ /* http://stackoverflow.com/a/2124385/354393 */ @@ -129,7 +138,7 @@ _nm_auto_fclose_impl (FILE **pfd) 19,18,17,16,15,14,13,12,11,10, \ 9,8,7,6,5,4,3,2,1,0 -/********************************************************/ +/*****************************************************************************/ #if defined (__GNUC__) #define _NM_PRAGMA_WARNING_DO(warning) G_STRINGIFY(GCC diagnostic ignored warning) @@ -165,7 +174,7 @@ _nm_auto_fclose_impl (FILE **pfd) #define NM_PRAGMA_WARNING_REENABLE #endif -/********************************************************/ +/*****************************************************************************/ /** * NM_G_ERROR_MSG: @@ -185,11 +194,16 @@ NM_G_ERROR_MSG (GError *error) return error ? (error->message ? : "(null)") : "(no-error)"; \ } -/********************************************************/ +/*****************************************************************************/ /* macro to return strlen() of a compile time string. */ #define NM_STRLEN(str) ( sizeof ("" str) - 1 ) +/* Note: @value is only evaluated when *out_val is present. + * Thus, + * NM_SET_OUT (out_str, g_strdup ("hallo")); + * does the right thing. + */ #define NM_SET_OUT(out_val, value) \ G_STMT_START { \ typeof(*(out_val)) *_out_val = (out_val); \ @@ -199,7 +213,7 @@ NM_G_ERROR_MSG (GError *error) } \ } G_STMT_END -/********************************************************/ +/*****************************************************************************/ #define _NM_IN_SET_EVAL_1( op, _x, y) (_x == (y)) #define _NM_IN_SET_EVAL_2( op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_1 (op, _x, __VA_ARGS__) @@ -235,7 +249,7 @@ NM_G_ERROR_MSG (GError *error) * side-effects. */ #define NM_IN_SET_SE(x, ...) _NM_IN_SET_EVAL_N(|, x, NM_NARG (__VA_ARGS__), __VA_ARGS__) -/********************************************************/ +/*****************************************************************************/ static inline gboolean _NM_IN_STRSET_streq (const char *x, const char *s) @@ -279,6 +293,52 @@ _NM_IN_STRSET_streq (const char *x, const char *s) * side-effects. */ #define NM_IN_STRSET_SE(x, ...) _NM_IN_STRSET_EVAL_N(|, x, NM_NARG (__VA_ARGS__), __VA_ARGS__) +#define NM_STRCHAR_ALL(str, ch_iter, predicate) \ + ({ \ + gboolean _val = TRUE; \ + const char *_str = (str); \ + \ + if (_str) { \ + for (;;) { \ + const char ch_iter = _str[0]; \ + \ + if (ch_iter != '\0') { \ + if (predicate) {\ + _str++; \ + continue; \ + } \ + _val = FALSE; \ + } \ + break; \ + } \ + } \ + _val; \ + }) + +#define NM_STRCHAR_ANY(str, ch_iter, predicate) \ + ({ \ + gboolean _val = FALSE; \ + const char *_str = (str); \ + \ + if (_str) { \ + for (;;) { \ + const char ch_iter = _str[0]; \ + \ + if (ch_iter != '\0') { \ + if (predicate) { \ + ; \ + } else { \ + _str++; \ + continue; \ + } \ + _val = TRUE; \ + } \ + break; \ + } \ + } \ + _val; \ + }) + /*****************************************************************************/ #define nm_streq(s1, s2) (strcmp (s1, s2) == 0) @@ -298,6 +358,25 @@ nm_strdup_not_empty (const char *str) return str && str[0] ? g_strdup (str) : NULL; } +static inline char * +nm_str_realloc (char *str) +{ + gs_free char *s = str; + + /* Returns a new clone of @str and frees @str. The point is that @str + * possibly points to a larger chunck of memory. We want to freshly allocate + * a buffer. + * + * We could use realloc(), but that might not do anything or leave + * @str in its memory pool for chunks of a different size (bad for + * fragmentation). + * + * This is only useful when we want to keep the buffer around for a long + * time and want to re-allocate a more optimal buffer. */ + + return g_strdup (s); +} + /*****************************************************************************/ #define NM_PRINT_FMT_QUOTED(cond, prefix, str, suffix, str_else) \ @@ -526,6 +605,18 @@ _NM_BACKPORT_SYMBOL_IMPL(VERSION, RETURN_TYPE, FUNC, _##FUNC##_##VERSION, ARGS_T /*****************************************************************************/ +#define nm_str_skip_leading_spaces(str) \ + ({ \ + typeof (*(str)) *_str = (str); \ + _nm_unused const char *_str_type_check = _str; \ + \ + if (_str) { \ + while (g_ascii_isspace (_str[0])) \ + _str++; \ + } \ + _str; \ + }) + static inline char * nm_strstrip (char *str) { @@ -563,6 +654,19 @@ nm_strcmp_p_with_data (gconstpointer a, gconstpointer b, gpointer user_data) return strcmp (s1, s2); } +static inline int +nm_cmp_uint32_p_with_data (gconstpointer p_a, gconstpointer p_b, gpointer user_data) +{ + const guint32 a = *((const guint32 *) p_a); + const guint32 b = *((const guint32 *) p_b); + + if (a < b) + return -1; + if (a > b) + return 1; + return 0; +} + /*****************************************************************************/ /* Taken from systemd's UNIQ_T and UNIQ macros. */ @@ -621,6 +725,21 @@ nm_decode_version (guint version, guint *major, guint *minor, guint *micro) { *minor = (version & 0x0000FF00u) >> 8; *micro = (version & 0x000000FFu); } + +/*****************************************************************************/ + +/* taken from systemd's DECIMAL_STR_MAX() + * + * Returns the number of chars needed to format variables of the + * specified type as a decimal string. Adds in extra space for a + * negative '-' prefix (hence works correctly on signed + * types). Includes space for the trailing NUL. */ +#define NM_DECIMAL_STR_MAX(type) \ + (2+(sizeof(type) <= 1 ? 3 : \ + sizeof(type) <= 2 ? 5 : \ + sizeof(type) <= 4 ? 10 : \ + sizeof(type) <= 8 ? 20 : sizeof(int[-2*(sizeof(type) > 8)]))) + /*****************************************************************************/ /* if @str is NULL, return "(null)". Otherwise, allocate a buffer using @@ -654,23 +773,27 @@ nm_decode_version (guint version, guint *major, guint *minor, guint *micro) { #define nm_sprintf_buf(buf, format, ...) ({ \ char * _buf = (buf); \ + int _buf_len; \ \ /* some static assert trying to ensure that the buffer is statically allocated. * It disallows a buffer size of sizeof(gpointer) to catch that. */ \ G_STATIC_ASSERT (G_N_ELEMENTS (buf) == sizeof (buf) && sizeof (buf) != sizeof (char *)); \ - g_snprintf (_buf, sizeof (buf), \ - ""format"", ##__VA_ARGS__); \ + _buf_len = g_snprintf (_buf, sizeof (buf), \ + ""format"", ##__VA_ARGS__); \ + nm_assert (_buf_len < sizeof (buf)); \ _buf; \ }) #define nm_sprintf_bufa(n_elements, format, ...) \ ({ \ char *_buf; \ + int _buf_len; \ \ G_STATIC_ASSERT (sizeof (char[MAX ((n_elements), 1)]) == (n_elements)); \ _buf = g_alloca (n_elements); \ - g_snprintf (_buf, n_elements, \ - ""format"", ##__VA_ARGS__); \ + _buf_len = g_snprintf (_buf, (n_elements), \ + ""format"", ##__VA_ARGS__); \ + nm_assert (_buf_len < (n_elements)); \ _buf; \ }) @@ -721,6 +844,33 @@ nm_decode_version (guint version, guint *major, guint *minor, guint *micro) { #define false 0 #endif + +#ifdef _G_BOOLEAN_EXPR +/* g_assert() uses G_LIKELY(), which in turn uses _G_BOOLEAN_EXPR(). + * As glib's implementation uses a local variable _g_boolean_var_, + * we cannot do + * g_assert (some_macro ()); + * where some_macro() itself expands to ({g_assert(); ...}). + * In other words, you cannot have a g_assert() inside a g_assert() + * without getting a -Werror=shadow failure. + * + * Workaround that by re-defining _G_BOOLEAN_EXPR() + **/ +#undef _G_BOOLEAN_EXPR +#define __NM_G_BOOLEAN_EXPR_IMPL(v, expr) \ + ({ \ + int NM_UNIQ_T(V, v); \ + \ + if (expr) \ + NM_UNIQ_T(V, v) = 1; \ + else \ + NM_UNIQ_T(V, v) = 0; \ + NM_UNIQ_T(V, v); \ + }) +#define _G_BOOLEAN_EXPR(expr) __NM_G_BOOLEAN_EXPR_IMPL (NM_UNIQ, expr) +#endif + + /*****************************************************************************/ #endif /* __NM_MACROS_INTERNAL_H__ */ diff --git a/shared/nm-utils/nm-shared-utils.c b/shared/nm-utils/nm-shared-utils.c index 38f6529d..38bb8181 100644 --- a/shared/nm-utils/nm-shared-utils.c +++ b/shared/nm-utils/nm-shared-utils.c @@ -27,6 +27,85 @@ /*****************************************************************************/ +void +nm_utils_strbuf_append_c (char **buf, gsize *len, char c) +{ + switch (*len) { + case 0: + return; + case 1: + (*buf)[0] = '\0'; + *len = 0; + (*buf)++; + return; + default: + (*buf)[0] = c; + (*buf)[1] = '\0'; + (*len)--; + (*buf)++; + return; + } +} + +void +nm_utils_strbuf_append_str (char **buf, gsize *len, const char *str) +{ + gsize src_len; + + switch (*len) { + case 0: + return; + case 1: + if (!str || !*str) { + (*buf)[0] = '\0'; + return; + } + (*buf)[0] = '\0'; + *len = 0; + (*buf)++; + return; + default: + if (!str || !*str) { + (*buf)[0] = '\0'; + return; + } + src_len = g_strlcpy (*buf, str, *len); + if (src_len >= *len) { + *buf = &(*buf)[*len]; + *len = 0; + } else { + *buf = &(*buf)[src_len]; + *len -= src_len; + } + return; + } +} + +void +nm_utils_strbuf_append (char **buf, gsize *len, const char *format, ...) +{ + char *p = *buf; + va_list args; + gint retval; + + if (*len == 0) + return; + + va_start (args, format); + retval = g_vsnprintf (p, *len, format, args); + va_end (args); + + if (retval >= *len) { + *buf = &p[*len]; + *len = 0; + } else { + *buf = &p[retval]; + *len -= retval; + } +} + +/*****************************************************************************/ + /* _nm_utils_ascii_str_to_int64: * * A wrapper for g_ascii_strtoll, that checks whether the whole string @@ -45,7 +124,7 @@ gint64 _nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 max, gint64 fallback) { gint64 v; - char *s = NULL; + const char *s = NULL; if (str) { while (g_ascii_isspace (str[0])) @@ -57,7 +136,7 @@ _nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 ma } errno = 0; - v = g_ascii_strtoll (str, &s, base); + v = g_ascii_strtoll (str, (char **) &s, base); if (errno != 0) return fallback; diff --git a/shared/nm-utils/nm-shared-utils.h b/shared/nm-utils/nm-shared-utils.h index cfa8f994..5d8a3a86 100644 --- a/shared/nm-utils/nm-shared-utils.h +++ b/shared/nm-utils/nm-shared-utils.h @@ -22,14 +22,33 @@ #ifndef __NM_SHARED_UTILS_H__ #define __NM_SHARED_UTILS_H__ -/******************************************************************************/ +/*****************************************************************************/ + +static inline void +_nm_utils_strbuf_init (char *buf, gsize len, char **p_buf_ptr, gsize *p_buf_len) +{ + NM_SET_OUT (p_buf_len, len); + NM_SET_OUT (p_buf_ptr, buf); + buf[0] = '\0'; +} + +#define nm_utils_strbuf_init(buf, p_buf_ptr, p_buf_len) \ + G_STMT_START { \ + G_STATIC_ASSERT (G_N_ELEMENTS (buf) == sizeof (buf) && sizeof (buf) > sizeof (char *)); \ + _nm_utils_strbuf_init ((buf), sizeof (buf), (p_buf_ptr), (p_buf_len)); \ + } G_STMT_END +void nm_utils_strbuf_append (char **buf, gsize *len, const char *format, ...) _nm_printf (3, 4); +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); + +/*****************************************************************************/ gint64 _nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 max, gint64 fallback); gint _nm_utils_ascii_str_to_bool (const char *str, gint default_value); -/******************************************************************************/ +/*****************************************************************************/ /** * NMUtilsError: @@ -54,13 +73,13 @@ void nm_utils_error_set_cancelled (GError **error, gboolean nm_utils_error_is_cancelled (GError *error, gboolean consider_is_disposing); -/******************************************************************************/ +/*****************************************************************************/ gboolean nm_g_object_set_property (GObject *object, const gchar *property_name, const GValue *value, GError **error); -/******************************************************************************/ +/*****************************************************************************/ #endif /* __NM_SHARED_UTILS_H__ */ diff --git a/shared/nm-utils/nm-test-utils.h b/shared/nm-utils/nm-test-utils.h index dba41c4b..7e712dcd 100644 --- a/shared/nm-utils/nm-test-utils.h +++ b/shared/nm-utils/nm-test-utils.h @@ -106,12 +106,12 @@ #include "nm-utils.h" -/*******************************************************************************/ +/*****************************************************************************/ #define NMTST_G_RETURN_MSG_S(expr) "*: assertion '"NM_ASSERT_G_RETURN_EXPR(expr)"' failed" #define NMTST_G_RETURN_MSG(expr) NMTST_G_RETURN_MSG_S(#expr) -/*******************************************************************************/ +/*****************************************************************************/ /* general purpose functions that have no dependency on other nmtst functions */ @@ -168,7 +168,7 @@ g_assert (!(success)); \ } G_STMT_END -/*******************************************************************************/ +/*****************************************************************************/ struct __nmtst_internal { @@ -979,6 +979,10 @@ __define_nmtst_static(02, 1024) __define_nmtst_static(03, 1024) #undef __define_nmtst_static +#define NMTST_UUID_INIT(uuid) \ + gs_free char *_nmtst_hidden_##uuid = nm_utils_uuid_generate (); \ + const char *const uuid = _nmtst_hidden_##uuid + inline static const char * nmtst_uuid_generate (void) { @@ -1123,7 +1127,7 @@ __nmtst_spawn_sync (const char *working_directory, char **standard_out, char **s return exit_status; } -/*******************************************************************************/ +/*****************************************************************************/ inline static char * nmtst_file_resolve_relative_path (const char *rel, const char *cwd) @@ -1140,6 +1144,62 @@ nmtst_file_resolve_relative_path (const char *rel, const char *cwd) return g_build_filename (cwd, rel, NULL); } +inline static char * +nmtst_file_get_contents (const char *filename) +{ + GError *error = NULL; + gboolean success; + char *contents = NULL; + gsize len; + + success = g_file_get_contents (filename, &contents, &len, &error); + nmtst_assert_success (success && contents, error); + g_assert_cmpint (strlen (contents), ==, len); + return contents; +} + +/*****************************************************************************/ + +inline static void +nmtst_file_unlink_if_exists (const char *name) +{ + int errsv; + + g_assert (name && name[0]); + + if (unlink (name) != 0) { + errsv = errno; + if (errsv != ENOENT) + g_error ("nmtst_file_unlink_if_exists(%s): failed with %s", name, strerror (errsv)); + } +} + +inline static void +nmtst_file_unlink (const char *name) +{ + int errsv; + + g_assert (name && name[0]); + + if (unlink (name) != 0) { + errsv = errno; + g_error ("nmtst_file_unlink(%s): failed with %s", name, strerror (errsv)); + } +} + +inline static void +_nmtst_auto_unlinkfile (char **p_name) +{ + if (*p_name) { + nmtst_file_unlink (*p_name); + nm_clear_g_free (p_name); + } +} + +#define nmtst_auto_unlinkfile nm_auto(_nmtst_auto_unlinkfile) + +/*****************************************************************************/ + inline static void _nmtst_assert_resolve_relative_path_equals (const char *f1, const char *f2, const char *file, int line) { @@ -1156,7 +1216,7 @@ _nmtst_assert_resolve_relative_path_equals (const char *f1, const char *f2, cons } #define nmtst_assert_resolve_relative_path_equals(f1, f2) _nmtst_assert_resolve_relative_path_equals (f1, f2, __FILE__, __LINE__); -/*******************************************************************************/ +/*****************************************************************************/ #ifdef NM_SETTING_IP_CONFIG_H inline static void diff --git a/shared/nm-utils/nm-vpn-plugin-macros.h b/shared/nm-utils/nm-vpn-plugin-macros.h index 06f5b286..acc549f2 100644 --- a/shared/nm-utils/nm-vpn-plugin-macros.h +++ b/shared/nm-utils/nm-vpn-plugin-macros.h @@ -24,6 +24,38 @@ #include <syslog.h> +static inline int +nm_utils_syslog_coerce_from_nm (int syslog_level) +{ + /* NetworkManager uses internally NMLogLevel levels. When spawning + * the VPN plugin, it maps those levels to syslog levels as follows: + * + * LOGL_INFO = LOG_NOTICE, + * LOGL_DEBUG = LOG_INFO, + * LOGL_TRACE = LOG_DEBUG, + * + * However, when actually printing to syslog, we don't want to print messages + * with LOGL_INFO level as LOG_NOTICE, because they are *not* to be highlighted. + * + * In other words: NetworkManager has 3 levels that should not require highlighting: + * LOGL_INFO, LOGL_DEBUG, LOGL_TRACE. syslog on the other hand has only LOG_INFO and LOG_DEBUG. + * + * So, coerce those values before printing to syslog. When you receive the syslog_level + * from NetworkManager, instead of calling + * syslog(syslog_level, ...) + * you should call + * syslog(nm_utils_syslog_coerce_from_nm(syslog_level), ...) + */ + switch (syslog_level) { + case LOG_INFO: + return LOG_DEBUG; + case LOG_NOTICE: + return LOG_INFO; + default: + return syslog_level; + } +} + static inline const char * nm_utils_syslog_to_str (int syslog_level) { |