diff options
Diffstat (limited to 'shared/nm-utils')
| -rw-r--r-- | shared/nm-utils/gsystem-local-alloc.h | 208 | ||||
| -rw-r--r-- | shared/nm-utils/nm-compat.c | 3 | ||||
| -rw-r--r-- | shared/nm-utils/nm-enum-utils.c | 4 | ||||
| -rw-r--r-- | shared/nm-utils/nm-enum-utils.h | 2 | ||||
| -rw-r--r-- | shared/nm-utils/nm-glib.h | 428 | ||||
| -rw-r--r-- | shared/nm-utils/nm-hash-utils.h | 16 | ||||
| -rw-r--r-- | shared/nm-utils/nm-io-utils.c | 430 | ||||
| -rw-r--r-- | shared/nm-utils/nm-io-utils.h | 63 | ||||
| -rw-r--r-- | shared/nm-utils/nm-macros-internal.h | 289 | ||||
| -rw-r--r-- | shared/nm-utils/nm-secret-utils.c | 134 | ||||
| -rw-r--r-- | shared/nm-utils/nm-secret-utils.h | 151 | ||||
| -rw-r--r-- | shared/nm-utils/nm-shared-utils.c | 676 | ||||
| -rw-r--r-- | shared/nm-utils/nm-shared-utils.h | 208 | ||||
| -rw-r--r-- | shared/nm-utils/nm-test-utils.h | 38 | ||||
| -rw-r--r-- | shared/nm-utils/unaligned.h | 4 |
15 files changed, 345 insertions, 2309 deletions
diff --git a/shared/nm-utils/gsystem-local-alloc.h b/shared/nm-utils/gsystem-local-alloc.h new file mode 100644 index 00000000..51b62519 --- /dev/null +++ b/shared/nm-utils/gsystem-local-alloc.h @@ -0,0 +1,208 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2012 Colin Walters <walters@verbum.org>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GSYSTEM_LOCAL_ALLOC_H__ +#define __GSYSTEM_LOCAL_ALLOC_H__ + +#include <gio/gio.h> + +G_BEGIN_DECLS + +#define GS_DEFINE_CLEANUP_FUNCTION(Type, name, func) \ + static inline void name (void *v) \ + { \ + func (*(Type*)v); \ + } + +#define GS_DEFINE_CLEANUP_FUNCTION0(Type, name, func) \ + static inline void name (void *v) \ + { \ + if (*(Type*)v) \ + func (*(Type*)v); \ + } + +/* These functions shouldn't be invoked directly; + * they are stubs that: + * 1) Take a pointer to the location (typically itself a pointer). + * 2) Provide %NULL-safety where it doesn't exist already (e.g. g_object_unref) + */ + +/** + * gs_free: + * + * Call g_free() on a variable location when it goes out of scope. + */ +#define gs_free __attribute__ ((cleanup(gs_local_free))) +GS_DEFINE_CLEANUP_FUNCTION(void*, gs_local_free, g_free) + +/** + * gs_unref_object: + * + * Call g_object_unref() on a variable location when it goes out of + * scope. Note that unlike g_object_unref(), the variable may be + * %NULL. + */ +#define gs_unref_object __attribute__ ((cleanup(gs_local_obj_unref))) +GS_DEFINE_CLEANUP_FUNCTION0(GObject*, gs_local_obj_unref, g_object_unref) + +/** + * gs_unref_variant: + * + * Call g_variant_unref() on a variable location when it goes out of + * scope. Note that unlike g_variant_unref(), the variable may be + * %NULL. + */ +#define gs_unref_variant __attribute__ ((cleanup(gs_local_variant_unref))) +GS_DEFINE_CLEANUP_FUNCTION0(GVariant*, gs_local_variant_unref, g_variant_unref) + +/** + * gs_free_variant_iter: + * + * Call g_variant_iter_free() on a variable location when it goes out of + * scope. + */ +#define gs_free_variant_iter __attribute__ ((cleanup(gs_local_variant_iter_free))) +GS_DEFINE_CLEANUP_FUNCTION0(GVariantIter*, gs_local_variant_iter_free, g_variant_iter_free) + +/** + * gs_free_variant_builder: + * + * Call g_variant_builder_unref() on a variable location when it goes out of + * scope. + */ +#define gs_unref_variant_builder __attribute__ ((cleanup(gs_local_variant_builder_unref))) +GS_DEFINE_CLEANUP_FUNCTION0(GVariantBuilder*, gs_local_variant_builder_unref, g_variant_builder_unref) + +/** + * gs_unref_array: + * + * Call g_array_unref() on a variable location when it goes out of + * scope. Note that unlike g_array_unref(), the variable may be + * %NULL. + + */ +#define gs_unref_array __attribute__ ((cleanup(gs_local_array_unref))) +GS_DEFINE_CLEANUP_FUNCTION0(GArray*, gs_local_array_unref, g_array_unref) + +/** + * gs_unref_ptrarray: + * + * Call g_ptr_array_unref() on a variable location when it goes out of + * scope. Note that unlike g_ptr_array_unref(), the variable may be + * %NULL. + + */ +#define gs_unref_ptrarray __attribute__ ((cleanup(gs_local_ptrarray_unref))) +GS_DEFINE_CLEANUP_FUNCTION0(GPtrArray*, gs_local_ptrarray_unref, g_ptr_array_unref) + +/** + * gs_unref_hashtable: + * + * Call g_hash_table_unref() on a variable location when it goes out + * of scope. Note that unlike g_hash_table_unref(), the variable may + * be %NULL. + */ +#define gs_unref_hashtable __attribute__ ((cleanup(gs_local_hashtable_unref))) +GS_DEFINE_CLEANUP_FUNCTION0(GHashTable*, gs_local_hashtable_unref, g_hash_table_unref) + +/** + * gs_free_list: + * + * Call g_list_free() on a variable location when it goes out + * of scope. + */ +#define gs_free_list __attribute__ ((cleanup(gs_local_free_list))) +GS_DEFINE_CLEANUP_FUNCTION(GList*, gs_local_free_list, g_list_free) + +/** + * gs_free_slist: + * + * Call g_slist_free() on a variable location when it goes out + * of scope. + */ +#define gs_free_slist __attribute__ ((cleanup(gs_local_free_slist))) +GS_DEFINE_CLEANUP_FUNCTION(GSList*, gs_local_free_slist, g_slist_free) + +/** + * gs_free_checksum: + * + * Call g_checksum_free() on a variable location when it goes out + * of scope. Note that unlike g_checksum_free(), the variable may + * be %NULL. + */ +#define gs_free_checksum __attribute__ ((cleanup(gs_local_checksum_free))) +GS_DEFINE_CLEANUP_FUNCTION0(GChecksum*, gs_local_checksum_free, g_checksum_free) + +/** + * gs_unref_bytes: + * + * Call g_bytes_unref() on a variable location when it goes out + * of scope. Note that unlike g_bytes_unref(), the variable may + * be %NULL. + */ +#define gs_unref_bytes __attribute__ ((cleanup(gs_local_bytes_unref))) +GS_DEFINE_CLEANUP_FUNCTION0(GBytes*, gs_local_bytes_unref, g_bytes_unref) + +/** + * gs_strfreev: + * + * Call g_strfreev() on a variable location when it goes out of scope. + */ +#define gs_strfreev __attribute__ ((cleanup(gs_local_strfreev))) +GS_DEFINE_CLEANUP_FUNCTION(char**, gs_local_strfreev, g_strfreev) + +/** + * gs_free_error: + * + * Call g_error_free() on a variable location when it goes out of scope. + */ +#define gs_free_error __attribute__ ((cleanup(gs_local_free_error))) +GS_DEFINE_CLEANUP_FUNCTION0(GError*, gs_local_free_error, g_error_free) + +/** + * gs_unref_keyfile: + * + * Call g_key_file_unref() on a variable location when it goes out of scope. + */ +#define gs_unref_keyfile __attribute__ ((cleanup(gs_local_keyfile_unref))) +GS_DEFINE_CLEANUP_FUNCTION0(GKeyFile*, gs_local_keyfile_unref, g_key_file_unref) + +static inline void +gs_cleanup_close_fdp (int *fdp) +{ + int fd; + + g_assert (fdp); + + fd = *fdp; + if (fd != -1) + (void) close (fd); +} + +/** + * gs_fd_close: + * + * Call close() on a variable location when it goes out of scope. + */ +#define gs_fd_close __attribute__((cleanup(gs_cleanup_close_fdp))) + +G_END_DECLS + +#endif diff --git a/shared/nm-utils/nm-compat.c b/shared/nm-utils/nm-compat.c index aa7c42f1..90328c06 100644 --- a/shared/nm-utils/nm-compat.c +++ b/shared/nm-utils/nm-compat.c @@ -60,8 +60,7 @@ _get_keys (NMSettingVpn *setting, if (len) { g_ptr_array_sort (a, nm_strcmp_p); g_ptr_array_add (a, NULL); - keys = g_malloc (a->len * sizeof (gpointer)); - memcpy (keys, a->pdata, a->len * sizeof (gpointer)); + keys = g_memdup (a->pdata, a->len * sizeof (gpointer)); /* we need to cache the keys *somewhere*. */ g_object_set_qdata_full (G_OBJECT (setting), diff --git a/shared/nm-utils/nm-enum-utils.c b/shared/nm-utils/nm-enum-utils.c index a4f6e809..b83c4207 100644 --- a/shared/nm-utils/nm-enum-utils.c +++ b/shared/nm-utils/nm-enum-utils.c @@ -323,11 +323,11 @@ _nm_utils_enum_from_str_full (GType type, } const char ** -_nm_utils_enum_get_values (GType type, int from, int to) +_nm_utils_enum_get_values (GType type, gint from, gint to) { GTypeClass *klass; GPtrArray *array; - int i; + gint i; char sbuf[64]; klass = g_type_class_ref (type); diff --git a/shared/nm-utils/nm-enum-utils.h b/shared/nm-utils/nm-enum-utils.h index 1827fdf4..d6dae859 100644 --- a/shared/nm-utils/nm-enum-utils.h +++ b/shared/nm-utils/nm-enum-utils.h @@ -41,7 +41,7 @@ gboolean _nm_utils_enum_from_str_full (GType type, char **err_token, const NMUtilsEnumValueInfo *value_infos); -const char **_nm_utils_enum_get_values (GType type, int from, int to); +const char **_nm_utils_enum_get_values (GType type, gint from, gint to); /*****************************************************************************/ diff --git a/shared/nm-utils/nm-glib.h b/shared/nm-utils/nm-glib.h index 770cf0fe..010f1820 100644 --- a/shared/nm-utils/nm-glib.h +++ b/shared/nm-utils/nm-glib.h @@ -20,13 +20,10 @@ #ifndef __NM_GLIB_H__ #define __NM_GLIB_H__ -/*****************************************************************************/ +#include <gio/gio.h> +#include <string.h> -#ifndef __NM_MACROS_INTERNAL_H__ -#error "nm-glib.h requires nm-macros-internal.h. Do not include this directly" -#endif - -/*****************************************************************************/ +#include "gsystem-local-alloc.h" #ifdef __clang__ @@ -42,98 +39,6 @@ #endif -/*****************************************************************************/ - -static inline void -__g_type_ensure (GType type) -{ -#if !GLIB_CHECK_VERSION(2,34,0) - if (G_UNLIKELY (type == (GType)-1)) - g_error ("can't happen"); -#else - G_GNUC_BEGIN_IGNORE_DEPRECATIONS; - g_type_ensure (type); - G_GNUC_END_IGNORE_DEPRECATIONS; -#endif -} -#define g_type_ensure __g_type_ensure - -/*****************************************************************************/ - -#if !GLIB_CHECK_VERSION(2,34,0) - -#define g_clear_pointer(pp, destroy) \ - G_STMT_START { \ - G_STATIC_ASSERT (sizeof *(pp) == sizeof (gpointer)); \ - /* Only one access, please */ \ - gpointer *_pp = (gpointer *) (pp); \ - gpointer _p; \ - /* This assignment is needed to avoid a gcc warning */ \ - GDestroyNotify _destroy = (GDestroyNotify) (destroy); \ - \ - _p = *_pp; \ - if (_p) \ - { \ - *_pp = NULL; \ - _destroy (_p); \ - } \ - } G_STMT_END - -#endif - -/*****************************************************************************/ - -#if !GLIB_CHECK_VERSION(2,34,0) - -/* These are used to clean up the output of test programs; we can just let - * them no-op in older glib. - */ -#define g_test_expect_message(log_domain, log_level, pattern) -#define g_test_assert_expected_messages() - -#else - -/* We build with -DGLIB_MAX_ALLOWED_VERSION set to 2.32 to make sure we don't - * accidentally use new API that we shouldn't. But we don't want warnings for - * the APIs that we emulate above. - */ - -#define g_test_expect_message(domain, level, format...) \ - G_STMT_START { \ - G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ - g_test_expect_message (domain, level, format); \ - G_GNUC_END_IGNORE_DEPRECATIONS \ - } G_STMT_END - -#define g_test_assert_expected_messages_internal(domain, file, line, func) \ - G_STMT_START { \ - G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ - g_test_assert_expected_messages_internal (domain, file, line, func); \ - G_GNUC_END_IGNORE_DEPRECATIONS \ - } G_STMT_END - -#endif - -/*****************************************************************************/ - -#if GLIB_CHECK_VERSION (2, 35, 0) -/* For glib >= 2.36, g_type_init() is deprecated. - * But since 2.35.1 (7c42ab23b55c43ab96d0ac2124b550bf1f49c1ec) this function - * does nothing. Replace the call with empty statement. */ -#define nm_g_type_init() G_STMT_START { (void) 0; } G_STMT_END -#else -#define nm_g_type_init() G_STMT_START { g_type_init (); } G_STMT_END -#endif - -/*****************************************************************************/ - -/* g_test_initialized() is only available since glib 2.36. */ -#if !GLIB_CHECK_VERSION (2, 36, 0) -#define g_test_initialized() (g_test_config_vars->test_initialized) -#endif - -/*****************************************************************************/ - /* g_assert_cmpmem() is only available since glib 2.46. */ #if !GLIB_CHECK_VERSION (2, 45, 7) #define g_assert_cmpmem(m1, l1, m2, l2) G_STMT_START {\ @@ -148,8 +53,6 @@ __g_type_ensure (GType type) } G_STMT_END #endif -/*****************************************************************************/ - /* Rumtime check for glib version. First do a compile time check which * (if satisfied) shortcuts the runtime check. */ static inline gboolean @@ -164,254 +67,6 @@ nm_glib_check_version (guint major, guint minor, guint micro) && glib_micro_version < micro)); } -/*****************************************************************************/ - -/* g_test_skip() is only available since glib 2.38. Add a compatibility wrapper. */ -static inline void -__nmtst_g_test_skip (const char *msg) -{ -#if GLIB_CHECK_VERSION (2, 38, 0) - G_GNUC_BEGIN_IGNORE_DEPRECATIONS - g_test_skip (msg); - G_GNUC_END_IGNORE_DEPRECATIONS -#else - g_debug ("%s", msg); -#endif -} -#define g_test_skip __nmtst_g_test_skip - -/*****************************************************************************/ - -/* g_test_add_data_func_full() is only available since glib 2.34. Add a compatibility wrapper. */ -static inline void -__g_test_add_data_func_full (const char *testpath, - gpointer test_data, - GTestDataFunc test_func, - GDestroyNotify data_free_func) -{ -#if GLIB_CHECK_VERSION (2, 34, 0) - G_GNUC_BEGIN_IGNORE_DEPRECATIONS - g_test_add_data_func_full (testpath, test_data, test_func, data_free_func); - G_GNUC_END_IGNORE_DEPRECATIONS -#else - g_return_if_fail (testpath != NULL); - g_return_if_fail (testpath[0] == '/'); - g_return_if_fail (test_func != NULL); - - g_test_add_vtable (testpath, 0, test_data, NULL, - (GTestFixtureFunc) test_func, - (GTestFixtureFunc) data_free_func); -#endif -} -#define g_test_add_data_func_full __g_test_add_data_func_full - -/*****************************************************************************/ - -#if !GLIB_CHECK_VERSION (2, 34, 0) -#define G_DEFINE_QUARK(QN, q_n) \ -GQuark \ -q_n##_quark (void) \ -{ \ - static GQuark q; \ - \ - if G_UNLIKELY (q == 0) \ - q = g_quark_from_static_string (#QN); \ - \ - return q; \ -} -#endif - -/*****************************************************************************/ - -static inline gboolean -nm_g_hash_table_replace (GHashTable *hash, gpointer key, gpointer value) -{ - /* glib 2.40 added a return value indicating whether the key already existed - * (910191597a6c2e5d5d460e9ce9efb4f47d9cc63c). */ -#if GLIB_CHECK_VERSION(2, 40, 0) - return g_hash_table_replace (hash, key, value); -#else - gboolean contained = g_hash_table_contains (hash, key); - - g_hash_table_replace (hash, key, value); - return !contained; -#endif -} - -static inline gboolean -nm_g_hash_table_insert (GHashTable *hash, gpointer key, gpointer value) -{ - /* glib 2.40 added a return value indicating whether the key already existed - * (910191597a6c2e5d5d460e9ce9efb4f47d9cc63c). */ -#if GLIB_CHECK_VERSION(2, 40, 0) - return g_hash_table_insert (hash, key, value); -#else - gboolean contained = g_hash_table_contains (hash, key); - - g_hash_table_insert (hash, key, value); - return !contained; -#endif -} - -static inline gboolean -nm_g_hash_table_add (GHashTable *hash, gpointer key) -{ - /* glib 2.40 added a return value indicating whether the key already existed - * (910191597a6c2e5d5d460e9ce9efb4f47d9cc63c). */ -#if GLIB_CHECK_VERSION(2, 40, 0) - return g_hash_table_add (hash, key); -#else - gboolean contained = g_hash_table_contains (hash, key); - - g_hash_table_add (hash, key); - return !contained; -#endif -} - -/*****************************************************************************/ - -#if !GLIB_CHECK_VERSION(2, 40, 0) || defined (NM_GLIB_COMPAT_H_TEST) -static inline void -_nm_g_ptr_array_insert (GPtrArray *array, - int index_, - gpointer data) -{ - g_return_if_fail (array); - g_return_if_fail (index_ >= -1); - g_return_if_fail (index_ <= (int) array->len); - - g_ptr_array_add (array, data); - - if (index_ != -1 && index_ != (int) (array->len - 1)) { - memmove (&(array->pdata[index_ + 1]), - &(array->pdata[index_]), - (array->len - index_ - 1) * sizeof (gpointer)); - array->pdata[index_] = data; - } -} -#endif - -#if !GLIB_CHECK_VERSION(2, 40, 0) -#define g_ptr_array_insert(array, index, data) G_STMT_START { _nm_g_ptr_array_insert (array, index, data); } G_STMT_END -#else -#define g_ptr_array_insert(array, index, data) \ - G_STMT_START { \ - G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ - g_ptr_array_insert (array, index, data); \ - G_GNUC_END_IGNORE_DEPRECATIONS \ - } G_STMT_END -#endif - -/*****************************************************************************/ - -#if !GLIB_CHECK_VERSION (2, 40, 0) -static inline gboolean -_g_key_file_save_to_file (GKeyFile *key_file, - const char *filename, - GError **error) -{ - char *contents; - gboolean success; - gsize length; - - g_return_val_if_fail (key_file != NULL, FALSE); - g_return_val_if_fail (filename != NULL, FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - contents = g_key_file_to_data (key_file, &length, NULL); - g_assert (contents != NULL); - - success = g_file_set_contents (filename, contents, length, error); - g_free (contents); - - return success; -} -#define g_key_file_save_to_file(key_file, filename, error) \ - _g_key_file_save_to_file (key_file, filename, error) -#else -#define g_key_file_save_to_file(key_file, filename, error) \ - ({ \ - gboolean _success; \ - \ - G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ - _success = g_key_file_save_to_file (key_file, filename, error); \ - G_GNUC_END_IGNORE_DEPRECATIONS \ - _success; \ - }) -#endif - -/*****************************************************************************/ - -#if GLIB_CHECK_VERSION (2, 36, 0) -#define g_credentials_get_unix_pid(creds, error) \ - ({ \ - G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ - (g_credentials_get_unix_pid) ((creds), (error)); \ - G_GNUC_END_IGNORE_DEPRECATIONS \ - }) -#else -#define g_credentials_get_unix_pid(creds, error) \ - ({ \ - struct ucred *native_creds; \ - \ - native_creds = g_credentials_get_native ((creds), G_CREDENTIALS_TYPE_LINUX_UCRED); \ - g_assert (native_creds); \ - native_creds->pid; \ - }) -#endif - -/*****************************************************************************/ - -#if !GLIB_CHECK_VERSION(2, 40, 0) || defined (NM_GLIB_COMPAT_H_TEST) -static inline gpointer * -_nm_g_hash_table_get_keys_as_array (GHashTable *hash_table, - guint *length) -{ - GHashTableIter iter; - gpointer key, *ret; - guint i = 0; - - g_return_val_if_fail (hash_table, NULL); - - ret = g_new0 (gpointer, g_hash_table_size (hash_table) + 1); - g_hash_table_iter_init (&iter, hash_table); - - while (g_hash_table_iter_next (&iter, &key, NULL)) - ret[i++] = key; - - ret[i] = NULL; - - if (length) - *length = i; - - return ret; -} -#endif -#if !GLIB_CHECK_VERSION(2, 40, 0) -#define g_hash_table_get_keys_as_array(hash_table, length) \ - ({ \ - _nm_g_hash_table_get_keys_as_array (hash_table, length); \ - }) -#else -#define g_hash_table_get_keys_as_array(hash_table, length) \ - ({ \ - G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ - (g_hash_table_get_keys_as_array) ((hash_table), (length)); \ - G_GNUC_END_IGNORE_DEPRECATIONS \ - }) -#endif - -/*****************************************************************************/ - -#ifndef g_info -/* g_info was only added with 2.39.2 */ -#define g_info(...) g_log (G_LOG_DOMAIN, \ - G_LOG_LEVEL_INFO, \ - __VA_ARGS__) -#endif - -/*****************************************************************************/ - #if !GLIB_CHECK_VERSION(2, 44, 0) static inline gpointer g_steal_pointer (gpointer pp) @@ -430,11 +85,9 @@ g_steal_pointer (gpointer pp) (0 ? (*(pp)) : (g_steal_pointer) (pp)) #endif -/*****************************************************************************/ - static inline gboolean -_nm_g_strv_contains (const char * const *strv, - const char *str) +_nm_g_strv_contains (const gchar * const *strv, + const gchar *str) { #if !GLIB_CHECK_VERSION(2, 44, 0) g_return_val_if_fail (strv != NULL, FALSE); @@ -454,80 +107,11 @@ _nm_g_strv_contains (const char * const *strv, } #define g_strv_contains _nm_g_strv_contains -/*****************************************************************************/ - -static inline GVariant * -_nm_g_variant_new_take_string (char *string) -{ -#if !GLIB_CHECK_VERSION(2, 36, 0) - GVariant *value; - - g_return_val_if_fail (string != NULL, NULL); - g_return_val_if_fail (g_utf8_validate (string, -1, NULL), NULL); - - value = g_variant_new_string (string); - g_free (string); - return value; -#elif !GLIB_CHECK_VERSION(2, 38, 0) - GVariant *value; - GBytes *bytes; - - g_return_val_if_fail (string != NULL, NULL); - g_return_val_if_fail (g_utf8_validate (string, -1, NULL), NULL); - - bytes = g_bytes_new_take (string, strlen (string) + 1); - value = g_variant_new_from_bytes (G_VARIANT_TYPE_STRING, bytes, TRUE); - g_bytes_unref (bytes); - - return value; -#else - G_GNUC_BEGIN_IGNORE_DEPRECATIONS - return g_variant_new_take_string (string); - G_GNUC_END_IGNORE_DEPRECATIONS -#endif -} -#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 - -/*****************************************************************************/ - #if !GLIB_CHECK_VERSION (2, 56, 0) #define g_object_ref(Obj) ((typeof(Obj)) g_object_ref (Obj)) #define g_object_ref_sink(Obj) ((typeof(Obj)) g_object_ref_sink (Obj)) #endif -/*****************************************************************************/ - #ifndef g_autofree /* we still don't rely on recent glib to provide g_autofree. Hence, we continue * to use our gs_* free macros that we took from libgsystem. @@ -536,6 +120,4 @@ _nm_g_variant_new_printf (const char *format_string, ...) #define g_autofree gs_free #endif -/*****************************************************************************/ - #endif /* __NM_GLIB_H__ */ diff --git a/shared/nm-utils/nm-hash-utils.h b/shared/nm-utils/nm-hash-utils.h index b797fb75..b7742e0f 100644 --- a/shared/nm-utils/nm-hash-utils.h +++ b/shared/nm-utils/nm-hash-utils.h @@ -57,11 +57,6 @@ nm_hash_update (NMHashState *state, const void *ptr, gsize n) nm_assert (ptr); nm_assert (n > 0); - /* Note: the data passed in here might be sensitive data (secrets), - * that we should nm_explicty_zero() afterwards. However, since - * we are using siphash24 with a random key, that is not really - * necessary. Something to keep in mind, if we ever move away from - * this hash implementation. */ c_siphash_append (&state->_state, ptr, n); } @@ -173,7 +168,7 @@ nm_hash_update_mem (NMHashState *state, const void *ptr, gsize n) * instead. */ nm_hash_update (state, &n, sizeof (n)); if (n > 0) - nm_hash_update (state, ptr, n); + c_siphash_append (&state->_state, ptr, n); } static inline void @@ -214,15 +209,6 @@ guint nm_direct_hash (gconstpointer str); guint nm_hash_str (const char *str); guint nm_str_hash (gconstpointer str); -#define nm_hash_val(static_seed, val) \ - ({ \ - NMHashState _h; \ - \ - nm_hash_init (&_h, static_seed); \ - nm_hash_update_val (&_h, val); \ - nm_hash_complete (&_h); \ - }) - /*****************************************************************************/ /* nm_pstr_*() are for hashing keys that are pointers to strings, diff --git a/shared/nm-utils/nm-io-utils.c b/shared/nm-utils/nm-io-utils.c deleted file mode 100644 index 88cb13ff..00000000 --- a/shared/nm-utils/nm-io-utils.c +++ /dev/null @@ -1,430 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - * (C) Copyright 2018 Red Hat, Inc. - */ - -#include "nm-default.h" - -#include "nm-io-utils.h" - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> - -#include "nm-shared-utils.h" -#include "nm-secret-utils.h" - -/*****************************************************************************/ - -_nm_printf (3, 4) -static int -_get_contents_error (GError **error, int errsv, const char *format, ...) -{ - if (errsv < 0) - errsv = -errsv; - else if (!errsv) - errsv = errno; - - if (error) { - char *msg; - va_list args; - - va_start (args, format); - msg = g_strdup_vprintf (format, args); - va_end (args); - g_set_error (error, - G_FILE_ERROR, - g_file_error_from_errno (errsv), - "%s: %s", - msg, g_strerror (errsv)); - g_free (msg); - } - return -errsv; -} - -static char * -_mem_realloc (char *old, gboolean do_bzero_mem, gsize cur_len, gsize new_len) -{ - char *new; - - /* re-allocating to zero bytes is an odd case. We don't need it - * and it's not supported. */ - nm_assert (new_len > 0); - - /* regardless of success/failure, @old will always be freed/consumed. */ - - if (do_bzero_mem && cur_len > 0) { - new = g_try_malloc (new_len); - if (new) - memcpy (new, old, NM_MIN (cur_len, new_len)); - nm_explicit_bzero (old, cur_len); - g_free (old); - } else { - new = g_try_realloc (old, new_len); - if (!new) - g_free (old); - } - - return new; -} - -/** - * nm_utils_fd_get_contents: - * @fd: open file descriptor to read. The fd will not be closed, - * but don't rely on its state afterwards. - * @close_fd: if %TRUE, @fd will be closed by the function. - * Passing %TRUE here might safe a syscall for dup(). - * @max_length: allocate at most @max_length bytes. If the - * file is larger, reading will fail. Set to zero to use - * a very large default. - * WARNING: @max_length is here to avoid a crash for huge/unlimited files. - * For example, stat(/sys/class/net/enp0s25/ifindex) gives a filesize of - * 4K, although the actual real is small. @max_length is the memory - * allocated in the process of reading the file, thus it must be at least - * the size reported by fstat. - * If you set it to 1K, read will fail because fstat() claims the - * file is larger. - * @flags: %NMUtilsFileGetContentsFlags for reading the file. - * @contents: the output buffer with the file read. It is always - * NUL terminated. The buffer is at most @max_length long, including - * the NUL byte. That is, it reads only files up to a length of - * @max_length - 1 bytes. - * @length: optional output argument of the read file size. - * - * A reimplementation of g_file_get_contents() with a few differences: - * - accepts an open fd, instead of a path name. This allows you to - * use openat(). - * - limits the maxium filesize to max_length. - * - * Returns: a negative error code on failure. - */ -int -nm_utils_fd_get_contents (int fd, - gboolean close_fd, - gsize max_length, - NMUtilsFileGetContentsFlags flags, - char **contents, - gsize *length, - GError **error) -{ - nm_auto_close int fd_keeper = close_fd ? fd : -1; - struct stat stat_buf; - gs_free char *str = NULL; - const bool do_bzero_mem = NM_FLAGS_HAS (flags, NM_UTILS_FILE_GET_CONTENTS_FLAG_SECRET); - - g_return_val_if_fail (fd >= 0, -EINVAL); - g_return_val_if_fail (contents, -EINVAL); - g_return_val_if_fail (!error || !*error, -EINVAL); - - if (fstat (fd, &stat_buf) < 0) - return _get_contents_error (error, 0, "failure during fstat"); - - if (!max_length) { - /* default to a very large size, but not extreme */ - max_length = 2 * 1024 * 1024; - } - - if ( stat_buf.st_size > 0 - && S_ISREG (stat_buf.st_mode)) { - const gsize n_stat = stat_buf.st_size; - ssize_t n_read; - - if (n_stat > max_length - 1) - return _get_contents_error (error, EMSGSIZE, "file too large (%zu+1 bytes with maximum %zu bytes)", n_stat, max_length); - - str = g_try_malloc (n_stat + 1); - if (!str) - return _get_contents_error (error, ENOMEM, "failure to allocate buffer of %zu+1 bytes", n_stat); - - n_read = nm_utils_fd_read_loop (fd, str, n_stat, TRUE); - if (n_read < 0) { - if (do_bzero_mem) - nm_explicit_bzero (str, n_stat); - return _get_contents_error (error, n_read, "error reading %zu bytes from file descriptor", n_stat); - } - str[n_read] = '\0'; - - if (n_read < n_stat) { - if (!(str = _mem_realloc (str, do_bzero_mem, n_stat + 1, n_read + 1))) - return _get_contents_error (error, ENOMEM, "failure to reallocate buffer with %zu bytes", n_read + 1); - } - NM_SET_OUT (length, n_read); - } else { - nm_auto_fclose FILE *f = NULL; - char buf[4096]; - gsize n_have, n_alloc; - int fd2; - - if (fd_keeper >= 0) - fd2 = nm_steal_fd (&fd_keeper); - else { - fd2 = fcntl (fd, F_DUPFD_CLOEXEC, 0); - if (fd2 < 0) - return _get_contents_error (error, 0, "error during dup"); - } - - if (!(f = fdopen (fd2, "r"))) { - nm_close (fd2); - return _get_contents_error (error, 0, "failure during fdopen"); - } - - n_have = 0; - n_alloc = 0; - - while (!feof (f)) { - int errsv; - gsize n_read; - - n_read = fread (buf, 1, sizeof (buf), f); - errsv = errno; - if (ferror (f)) { - if (do_bzero_mem) - nm_explicit_bzero (buf, sizeof (buf)); - return _get_contents_error (error, errsv, "error during fread"); - } - - if ( n_have > G_MAXSIZE - 1 - n_read - || n_have + n_read + 1 > max_length) { - if (do_bzero_mem) - nm_explicit_bzero (buf, sizeof (buf)); - return _get_contents_error (error, EMSGSIZE, "file stream too large (%zu+1 bytes with maximum %zu bytes)", - (n_have > G_MAXSIZE - 1 - n_read) ? G_MAXSIZE : n_have + n_read, - max_length); - } - - if (n_have + n_read + 1 >= n_alloc) { - gsize old_n_alloc = n_alloc; - - if (n_alloc != 0) { - nm_assert (str); - if (n_alloc >= max_length / 2) - n_alloc = max_length; - else - n_alloc *= 2; - } else { - nm_assert (!str); - n_alloc = NM_MIN (n_read + 1, sizeof (buf)); - } - - if (!(str = _mem_realloc (str, do_bzero_mem, old_n_alloc, n_alloc))) { - if (do_bzero_mem) - nm_explicit_bzero (buf, sizeof (buf)); - return _get_contents_error (error, ENOMEM, "failure to allocate buffer of %zu bytes", n_alloc); - } - } - - memcpy (str + n_have, buf, n_read); - n_have += n_read; - } - - if (do_bzero_mem) - nm_explicit_bzero (buf, sizeof (buf)); - - if (n_alloc == 0) - str = g_new0 (char, 1); - else { - str[n_have] = '\0'; - if (n_have + 1 < n_alloc) { - if (!(str = _mem_realloc (str, do_bzero_mem, n_alloc, n_have + 1))) - return _get_contents_error (error, ENOMEM, "failure to truncate buffer to %zu bytes", n_have + 1); - } - } - - NM_SET_OUT (length, n_have); - } - - *contents = g_steal_pointer (&str); - return 0; -} - -/** - * nm_utils_file_get_contents: - * @dirfd: optional file descriptor to use openat(). If negative, use plain open(). - * @filename: the filename to open. Possibly relative to @dirfd. - * @max_length: allocate at most @max_length bytes. - * WARNING: see nm_utils_fd_get_contents() hint about @max_length. - * @flags: %NMUtilsFileGetContentsFlags for reading the file. - * @contents: the output buffer with the file read. It is always - * NUL terminated. The buffer is at most @max_length long, including - * the NUL byte. That is, it reads only files up to a length of - * @max_length - 1 bytes. - * @length: optional output argument of the read file size. - * - * A reimplementation of g_file_get_contents() with a few differences: - * - accepts an @dirfd to open @filename relative to that path via openat(). - * - limits the maxium filesize to max_length. - * - uses O_CLOEXEC on internal file descriptor - * - * Returns: a negative error code on failure. - */ -int -nm_utils_file_get_contents (int dirfd, - const char *filename, - gsize max_length, - NMUtilsFileGetContentsFlags flags, - char **contents, - gsize *length, - GError **error) -{ - int fd; - int errsv; - - g_return_val_if_fail (filename && filename[0], -EINVAL); - - if (dirfd >= 0) { - fd = openat (dirfd, filename, O_RDONLY | O_CLOEXEC); - if (fd < 0) { - errsv = errno; - - g_set_error (error, - G_FILE_ERROR, - g_file_error_from_errno (errsv), - "Failed to open file \"%s\" with openat: %s", - filename, - g_strerror (errsv)); - return -errsv; - } - } else { - fd = open (filename, O_RDONLY | O_CLOEXEC); - if (fd < 0) { - errsv = errno; - - g_set_error (error, - G_FILE_ERROR, - g_file_error_from_errno (errsv), - "Failed to open file \"%s\": %s", - filename, - g_strerror (errsv)); - return -errsv; - } - } - return nm_utils_fd_get_contents (fd, - TRUE, - max_length, - flags, - contents, - length, - error); -} - -/*****************************************************************************/ - -/* - * Copied from GLib's g_file_set_contents() et al., but allows - * specifying a mode for the new file. - */ -gboolean -nm_utils_file_set_contents (const char *filename, - const char *contents, - gssize length, - mode_t mode, - GError **error) -{ - gs_free char *tmp_name = NULL; - struct stat statbuf; - int errsv; - gssize s; - int fd; - - g_return_val_if_fail (filename, FALSE); - g_return_val_if_fail (contents || !length, FALSE); - g_return_val_if_fail (!error || !*error, FALSE); - g_return_val_if_fail (length >= -1, FALSE); - - if (length == -1) - length = strlen (contents); - - tmp_name = g_strdup_printf ("%s.XXXXXX", filename); - fd = g_mkstemp_full (tmp_name, O_RDWR, mode); - if (fd < 0) { - errsv = errno; - g_set_error (error, - G_FILE_ERROR, - g_file_error_from_errno (errsv), - "failed to create file %s: %s", - tmp_name, - g_strerror (errsv)); - return FALSE; - } - - while (length > 0) { - s = write (fd, contents, length); - if (s < 0) { - errsv = errno; - if (errsv == EINTR) - continue; - - nm_close (fd); - unlink (tmp_name); - - g_set_error (error, - G_FILE_ERROR, - g_file_error_from_errno (errsv), - "failed to write to file %s: %s", - tmp_name, - g_strerror (errsv)); - return FALSE; - } - - g_assert (s <= length); - - contents += s; - length -= s; - } - - /* If the final destination exists and is > 0 bytes, we want to sync the - * newly written file to ensure the data is on disk when we rename over - * the destination. Otherwise if we get a system crash we can lose both - * the new and the old file on some filesystems. (I.E. those that don't - * guarantee the data is written to the disk before the metadata.) - */ - if ( lstat (filename, &statbuf) == 0 - && statbuf.st_size > 0 - && fsync (fd) != 0) { - errsv = errno; - - nm_close (fd); - unlink (tmp_name); - - g_set_error (error, - G_FILE_ERROR, - g_file_error_from_errno (errsv), - "failed to fsync %s: %s", - tmp_name, - g_strerror (errsv)); - return FALSE; - } - - nm_close (fd); - - if (rename (tmp_name, filename)) { - errsv = errno; - unlink (tmp_name); - g_set_error (error, - G_FILE_ERROR, - g_file_error_from_errno (errsv), - "failed to rename %s to %s: %s", - tmp_name, - filename, - g_strerror (errsv)); - return FALSE; - } - - return TRUE; -} diff --git a/shared/nm-utils/nm-io-utils.h b/shared/nm-utils/nm-io-utils.h deleted file mode 100644 index dc72a2a6..00000000 --- a/shared/nm-utils/nm-io-utils.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - * (C) Copyright 2018 Red Hat, Inc. - */ - -#ifndef __NM_IO_UTILS_H__ -#define __NM_IO_UTILS_H__ - -#include "nm-macros-internal.h" - -/*****************************************************************************/ - -/** - * NMUtilsFileGetContentsFlags: - * @NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE: no flag - * @NM_UTILS_FILE_GET_CONTENTS_FLAG_SECRET: if present, ensure that no - * data is left in memory. Essentially, it means to call explicity_bzero() - * to not leave key material on the heap (when reading secrets). - */ -typedef enum { - NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE = 0, - NM_UTILS_FILE_GET_CONTENTS_FLAG_SECRET = (1 << 0), -} NMUtilsFileGetContentsFlags; - -int nm_utils_fd_get_contents (int fd, - gboolean close_fd, - gsize max_length, - NMUtilsFileGetContentsFlags flags, - char **contents, - gsize *length, - GError **error); - -int nm_utils_file_get_contents (int dirfd, - const char *filename, - gsize max_length, - NMUtilsFileGetContentsFlags flags, - char **contents, - gsize *length, - GError **error); - -gboolean nm_utils_file_set_contents (const char *filename, - const char *contents, - gssize length, - mode_t mode, - GError **error); - -#endif /* __NM_IO_UTILS_H__ */ diff --git a/shared/nm-utils/nm-macros-internal.h b/shared/nm-utils/nm-macros-internal.h index 084219b4..ef3039e6 100644 --- a/shared/nm-utils/nm-macros-internal.h +++ b/shared/nm-utils/nm-macros-internal.h @@ -16,7 +16,6 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2012 Colin Walters <walters@verbum.org>. * (C) Copyright 2014 Red Hat, Inc. */ @@ -26,11 +25,6 @@ #include <stdio.h> #include <stdlib.h> #include <errno.h> -#include <string.h> - -#include <gio/gio.h> - -/*****************************************************************************/ #define _nm_packed __attribute__ ((packed)) #define _nm_unused __attribute__ ((unused)) @@ -40,8 +34,6 @@ #define _nm_align(s) __attribute__ ((aligned (s))) #define _nm_alignof(type) __alignof (type) #define _nm_alignas(type) _nm_align (_nm_alignof (type)) -#define nm_auto(fcn) __attribute__ ((cleanup(fcn))) - #if __GNUC__ >= 7 #define _nm_fallthrough __attribute__ ((fallthrough)) @@ -65,146 +57,13 @@ /*****************************************************************************/ -#define NM_AUTO_DEFINE_FCN_VOID(CastType, name, func) \ -static inline void name (void *v) \ -{ \ - func (*((CastType *) v)); \ -} - -#define NM_AUTO_DEFINE_FCN_VOID0(CastType, name, func) \ -static inline void name (void *v) \ -{ \ - if (*((CastType *) v)) \ - func (*((CastType *) v)); \ -} - -#define NM_AUTO_DEFINE_FCN(Type, name, func) \ -static inline void name (Type *v) \ -{ \ - func (*v); \ -} - -#define NM_AUTO_DEFINE_FCN0(Type, name, func) \ -static inline void name (Type *v) \ -{ \ - if (*v) \ - func (*v); \ -} - -/*****************************************************************************/ - -/** - * gs_free: - * - * Call g_free() on a variable location when it goes out of scope. - */ -#define gs_free nm_auto(gs_local_free) -NM_AUTO_DEFINE_FCN_VOID (void *, gs_local_free, g_free) - -/** - * gs_unref_object: - * - * Call g_object_unref() on a variable location when it goes out of - * scope. Note that unlike g_object_unref(), the variable may be - * %NULL. - */ -#define gs_unref_object nm_auto(gs_local_obj_unref) -NM_AUTO_DEFINE_FCN_VOID0 (GObject *, gs_local_obj_unref, g_object_unref) - -/** - * gs_unref_variant: - * - * Call g_variant_unref() on a variable location when it goes out of - * scope. Note that unlike g_variant_unref(), the variable may be - * %NULL. - */ -#define gs_unref_variant nm_auto(gs_local_variant_unref) -NM_AUTO_DEFINE_FCN0 (GVariant *, gs_local_variant_unref, g_variant_unref) - -/** - * gs_unref_array: - * - * Call g_array_unref() on a variable location when it goes out of - * scope. Note that unlike g_array_unref(), the variable may be - * %NULL. - - */ -#define gs_unref_array nm_auto(gs_local_array_unref) -NM_AUTO_DEFINE_FCN0 (GArray *, gs_local_array_unref, g_array_unref) - -/** - * gs_unref_ptrarray: - * - * Call g_ptr_array_unref() on a variable location when it goes out of - * scope. Note that unlike g_ptr_array_unref(), the variable may be - * %NULL. - - */ -#define gs_unref_ptrarray nm_auto(gs_local_ptrarray_unref) -NM_AUTO_DEFINE_FCN0 (GPtrArray *, gs_local_ptrarray_unref, g_ptr_array_unref) - -/** - * gs_unref_hashtable: - * - * Call g_hash_table_unref() on a variable location when it goes out - * of scope. Note that unlike g_hash_table_unref(), the variable may - * be %NULL. - */ -#define gs_unref_hashtable nm_auto(gs_local_hashtable_unref) -NM_AUTO_DEFINE_FCN0 (GHashTable *, gs_local_hashtable_unref, g_hash_table_unref) - -/** - * gs_free_slist: - * - * Call g_slist_free() on a variable location when it goes out - * of scope. - */ -#define gs_free_slist nm_auto(gs_local_free_slist) -NM_AUTO_DEFINE_FCN (GSList *, gs_local_free_slist, g_slist_free) - -/** - * gs_unref_bytes: - * - * Call g_bytes_unref() on a variable location when it goes out - * of scope. Note that unlike g_bytes_unref(), the variable may - * be %NULL. - */ -#define gs_unref_bytes nm_auto(gs_local_bytes_unref) -NM_AUTO_DEFINE_FCN0 (GBytes *, gs_local_bytes_unref, g_bytes_unref) - -/** - * gs_strfreev: - * - * Call g_strfreev() on a variable location when it goes out of scope. - */ -#define gs_strfreev nm_auto(gs_local_strfreev) -NM_AUTO_DEFINE_FCN (char **, gs_local_strfreev, g_strfreev) - -/** - * gs_free_error: - * - * Call g_error_free() on a variable location when it goes out of scope. - */ -#define gs_free_error nm_auto(gs_local_free_error) -NM_AUTO_DEFINE_FCN0 (GError *, gs_local_free_error, g_error_free) - -/** - * gs_unref_keyfile: - * - * Call g_key_file_unref() on a variable location when it goes out of scope. - */ -#define gs_unref_keyfile nm_auto(gs_local_keyfile_unref) -NM_AUTO_DEFINE_FCN0 (GKeyFile *, gs_local_keyfile_unref, g_key_file_unref) - -/*****************************************************************************/ - #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); @@ -212,49 +71,59 @@ static inline int nm_close (int fd); * nm_auto_free: * * Call free() on a variable location when it goes out of scope. - * This is for pointers that are allocated with malloc() instead of - * g_malloc(). - * - * In practice, since glib 2.45, g_malloc()/g_free() always wraps malloc()/free(). - * See bgo#751592. In that case, it would be safe to free pointers allocated with - * malloc() with gs_free or g_free(). - * - * However, let's never mix them. To free malloc'ed memory, always use - * free() or nm_auto_free. */ -NM_AUTO_DEFINE_FCN_VOID (void *, _nm_auto_free_impl, free) #define nm_auto_free nm_auto(_nm_auto_free_impl) +GS_DEFINE_CLEANUP_FUNCTION(void*, _nm_auto_free_impl, free) -NM_AUTO_DEFINE_FCN0 (GVariantIter *, _nm_auto_free_variant_iter, g_variant_iter_free) -#define nm_auto_free_variant_iter nm_auto(_nm_auto_free_variant_iter) - -NM_AUTO_DEFINE_FCN0 (GVariantBuilder *, _nm_auto_unref_variant_builder, g_variant_builder_unref) -#define nm_auto_unref_variant_builder nm_auto(_nm_auto_unref_variant_builder) +static inline void +nm_free_secret (char *secret) +{ + if (secret) { + memset (secret, 0, strlen (secret)); + g_free (secret); + } +} -NM_AUTO_DEFINE_FCN (GList *, _nm_auto_free_list, g_list_free) -#define nm_auto_free_list nm_auto(_nm_auto_free_list) +static inline void +_nm_auto_free_secret_impl (char **v) +{ + nm_free_secret (*v); +} -NM_AUTO_DEFINE_FCN0 (GChecksum *, _nm_auto_checksum_free, g_checksum_free) -#define nm_auto_free_checksum nm_auto(_nm_auto_checksum_free) +/** + * 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) -#define nm_auto_unset_gvalue nm_auto(g_value_unset) +static inline void +_nm_auto_unset_gvalue_impl (GValue *v) +{ + g_value_unset (v); +} +#define nm_auto_unset_gvalue nm_auto(_nm_auto_unset_gvalue_impl) -NM_AUTO_DEFINE_FCN_VOID0 (void *, _nm_auto_unref_gtypeclass, g_type_class_unref) +static inline void +_nm_auto_unref_gtypeclass (gpointer v) +{ + if (v && *((gpointer *) v)) + g_type_class_unref (*((gpointer *) v)); +} #define nm_auto_unref_gtypeclass nm_auto(_nm_auto_unref_gtypeclass) -NM_AUTO_DEFINE_FCN0 (GByteArray *, _nm_auto_unref_bytearray, g_byte_array_unref) -#define nm_auto_unref_bytearray nm_auto(_nm_auto_unref_bytearray) - static inline void -_nm_auto_free_gstring (GString **str) +_nm_auto_free_gstring_impl (GString **str) { if (*str) g_string_free (*str, TRUE); } -#define nm_auto_free_gstring nm_auto(_nm_auto_free_gstring) +#define nm_auto_free_gstring nm_auto(_nm_auto_free_gstring_impl) static inline void -_nm_auto_close (int *pfd) +_nm_auto_close_impl (int *pfd) { if (*pfd >= 0) { int errsv = errno; @@ -263,10 +132,10 @@ _nm_auto_close (int *pfd) errno = errsv; } } -#define nm_auto_close nm_auto(_nm_auto_close) +#define nm_auto_close nm_auto(_nm_auto_close_impl) static inline void -_nm_auto_fclose (FILE **pfd) +_nm_auto_fclose_impl (FILE **pfd) { if (*pfd) { int errsv = errno; @@ -275,7 +144,7 @@ _nm_auto_fclose (FILE **pfd) errno = errsv; } } -#define nm_auto_fclose nm_auto(_nm_auto_fclose) +#define nm_auto_fclose nm_auto(_nm_auto_fclose_impl) static inline void _nm_auto_protect_errno (int *p_saved_errno) @@ -284,25 +153,13 @@ _nm_auto_protect_errno (int *p_saved_errno) } #define NM_AUTO_PROTECT_ERRNO(errsv_saved) nm_auto(_nm_auto_protect_errno) _nm_unused const int errsv_saved = (errno) -NM_AUTO_DEFINE_FCN0 (GSource *, _nm_auto_unref_gsource, g_source_unref); -#define nm_auto_unref_gsource nm_auto(_nm_auto_unref_gsource) - static inline void -_nm_auto_freev (gpointer ptr) +_nm_auto_unref_gsource (GSource **ptr) { - gpointer **p = ptr; - gpointer *_ptr; - - if (*p) { - for (_ptr = *p; *_ptr; _ptr++) - g_free (*_ptr); - g_free (*p); - } + if (*ptr) + g_source_unref (g_steal_pointer (ptr)); } -/* g_free a NULL terminated array of pointers, with also freeing each - * pointer with g_free(). It essentially does the same as - * gs_strfreev / g_strfreev(), but not restricted to strv arrays. */ -#define nm_auto_freev nm_auto(_nm_auto_freev) +#define nm_auto_unref_gsource nm_auto(_nm_auto_unref_gsource) /*****************************************************************************/ @@ -327,16 +184,13 @@ _nm_auto_freev (gpointer ptr) /*****************************************************************************/ -/* http://stackoverflow.com/a/2124385/354393 - * https://stackoverflow.com/questions/11317474/macro-to-count-number-of-arguments - */ +/* http://stackoverflow.com/a/2124385/354393 */ #define NM_NARG(...) \ - _NM_NARG(, ##__VA_ARGS__, _NM_NARG_RSEQ_N()) + _NM_NARG(__VA_ARGS__,_NM_NARG_RSEQ_N()) #define _NM_NARG(...) \ _NM_NARG_ARG_N(__VA_ARGS__) #define _NM_NARG_ARG_N( \ - _0, \ _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \ _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \ _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \ @@ -407,7 +261,7 @@ _nm_auto_freev (gpointer ptr) static inline const char * NM_G_ERROR_MSG (GError *error) { - return error ? (error->message ?: "(null)") : "(no-error)"; \ + return error ? (error->message ? : "(null)") : "(no-error)"; \ } /*****************************************************************************/ @@ -900,7 +754,7 @@ nm_str_realloc (char *str) #define NM_GOBJECT_PROPERTIES_DEFINE_BASE(...) \ typedef enum { \ - PROP_0, \ + _PROPERTY_ENUMS_0, \ __VA_ARGS__ \ _PROPERTY_ENUMS_LAST, \ } _PropertyEnums; \ @@ -909,39 +763,12 @@ static GParamSpec *obj_properties[_PROPERTY_ENUMS_LAST] = { NULL, } #define NM_GOBJECT_PROPERTIES_DEFINE(obj_type, ...) \ NM_GOBJECT_PROPERTIES_DEFINE_BASE (__VA_ARGS__); \ static inline void \ -_nm_gobject_notify_together_impl (obj_type *obj, guint n, const _PropertyEnums *props) \ -{ \ - const gboolean freeze_thaw = (n > 1); \ - \ - nm_assert (G_IS_OBJECT (obj)); \ - nm_assert (n > 0); \ - \ - if (freeze_thaw) \ - g_object_freeze_notify ((GObject *) obj); \ - while (n-- > 0) { \ - const _PropertyEnums prop = *props++; \ - \ - if (prop != PROP_0) { \ - nm_assert ((gsize) prop < G_N_ELEMENTS (obj_properties)); \ - nm_assert (obj_properties[prop]); \ - g_object_notify_by_pspec ((GObject *) obj, obj_properties[prop]); \ - } \ - } \ - if (freeze_thaw) \ - g_object_thaw_notify ((GObject *) obj); \ -} \ -\ -static inline void \ _notify (obj_type *obj, _PropertyEnums prop) \ { \ - _nm_gobject_notify_together_impl (obj, 1, &prop); \ -} \ - -/* invokes _notify() for all arguments (of type _PropertyEnums). Note, that if - * there are more than one prop arguments, this will involve a freeze/thaw - * of GObject property notifications. */ -#define nm_gobject_notify_together(obj, ...) \ - _nm_gobject_notify_together_impl (obj, NM_NARG (__VA_ARGS__), (const _PropertyEnums[]) { __VA_ARGS__ }) + nm_assert (G_IS_OBJECT (obj)); \ + nm_assert ((gsize) prop < G_N_ELEMENTS (obj_properties)); \ + g_object_notify_by_pspec ((GObject *) obj, obj_properties[prop]); \ +} /*****************************************************************************/ @@ -1116,14 +943,6 @@ nm_clear_g_cancellable (GCancellable **cancellable) && ((__x & (__x - (((typeof(__x)) 1)))) == ((typeof(__x)) 0))); \ }) -#define NM_DIV_ROUND_UP(x, y) \ - ({ \ - const typeof(x) _x = (x); \ - const typeof(y) _y = (y); \ - \ - (_x / _y + !!(_x % _y)); \ - }) - /*****************************************************************************/ #define NM_UTILS_LOOKUP_DEFAULT(v) return (v) @@ -1442,7 +1261,7 @@ nm_decode_version (guint version, guint *major, guint *minor, guint *micro) * Using _Bool has advantages over gboolean: * * - commonly _Bool is one byte large, instead of gboolean's 4 bytes (because gboolean - * is a typedef for int). Especially when having boolean fields in a struct, we can + * is a typedef for gint). Especially when having boolean fields in a struct, we can * thereby easily save some space. * * - _Bool type guarantees that two "true" expressions compare equal. E.g. the follwing diff --git a/shared/nm-utils/nm-secret-utils.c b/shared/nm-utils/nm-secret-utils.c deleted file mode 100644 index 65f99c65..00000000 --- a/shared/nm-utils/nm-secret-utils.c +++ /dev/null @@ -1,134 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - * (C) Copyright 2018 Red Hat, Inc. - */ - -#include "nm-default.h" - -#include "nm-secret-utils.h" - -/*****************************************************************************/ - -void -nm_explicit_bzero (void *s, gsize n) -{ - /* gracefully handle n == 0. This is important, callers rely on it. */ - if (n > 0) { - nm_assert (s); -#if defined (HAVE_DECL_EXPLICIT_BZERO) && HAVE_DECL_EXPLICIT_BZERO - explicit_bzero (s, n); -#else - /* don't bother with a workaround. Use a reasonable glibc. */ - memset (s, 0, n); -#endif - } -} - -/*****************************************************************************/ - -char * -nm_secret_strchomp (char *secret) -{ - gsize len; - - g_return_val_if_fail (secret, NULL); - - /* it's actually identical to g_strchomp(). However, - * the glib function does not document, that it clears the - * memory. For @secret, we don't only want to truncate trailing - * spaces, we want to overwrite them with NUL. */ - - len = strlen (secret); - while (len--) { - if (g_ascii_isspace ((guchar) secret[len])) - secret[len] = '\0'; - else - break; - } - - return secret; -} - -/*****************************************************************************/ - -GBytes * -nm_secret_copy_to_gbytes (gconstpointer mem, gsize mem_len) -{ - NMSecretBuf *b; - - if (mem_len == 0) - return g_bytes_new_static ("", 0); - - nm_assert (mem); - - /* NUL terminate the buffer. - * - * The entire buffer is already malloc'ed and likely has some room for padding. - * Thus, in many situations, this additional byte will cause no overhead in - * practice. - * - * Even if it causes an overhead, do it just for safety. Yes, the returned - * bytes is not a NUL terminated string and no user must rely on this. Do - * not treat binary data as NUL terminated strings, unless you know what - * you are doing. Anyway, defensive FTW. - */ - - b = nm_secret_buf_new (mem_len + 1); - memcpy (b->bin, mem, mem_len); - b->bin[mem_len] = 0; - return nm_secret_buf_to_gbytes_take (b, mem_len); -} - -/*****************************************************************************/ - -NMSecretBuf * -nm_secret_buf_new (gsize len) -{ - NMSecretBuf *secret; - - nm_assert (len > 0); - - secret = g_malloc (sizeof (NMSecretBuf) + len); - *((gsize *) &(secret->len)) = len; - return secret; -} - -static void -_secret_buf_free (gpointer user_data) -{ - NMSecretBuf *secret = user_data; - - nm_assert (secret); - nm_assert (secret->len > 0); - - nm_explicit_bzero (secret->bin, secret->len); - g_free (user_data); -} - -GBytes * -nm_secret_buf_to_gbytes_take (NMSecretBuf *secret, gssize actual_len) -{ - nm_assert (secret); - nm_assert (secret->len > 0); - nm_assert (actual_len == -1 || (actual_len >= 0 && actual_len <= secret->len)); - return g_bytes_new_with_free_func (secret->bin, - actual_len >= 0 ? (gsize) actual_len : secret->len, - _secret_buf_free, - secret); -} diff --git a/shared/nm-utils/nm-secret-utils.h b/shared/nm-utils/nm-secret-utils.h deleted file mode 100644 index 21a3c1ba..00000000 --- a/shared/nm-utils/nm-secret-utils.h +++ /dev/null @@ -1,151 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - * (C) Copyright 2018 Red Hat, Inc. - */ - -#ifndef __NM_SECRET_UTILS_H__ -#define __NM_SECRET_UTILS_H__ - -#include "nm-macros-internal.h" - -/*****************************************************************************/ - -void nm_explicit_bzero (void *s, gsize n); - -/*****************************************************************************/ - -char *nm_secret_strchomp (char *secret); - -/*****************************************************************************/ - -static inline void -nm_free_secret (char *secret) -{ - if (secret) { - nm_explicit_bzero (secret, strlen (secret)); - g_free (secret); - } -} - -NM_AUTO_DEFINE_FCN (char *, _nm_auto_free_secret, nm_free_secret) -/** - * 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) - -/*****************************************************************************/ - -GBytes *nm_secret_copy_to_gbytes (gconstpointer mem, gsize mem_len); - -/*****************************************************************************/ - -/* NMSecretPtr is a pair of malloc'ed data pointer and the length of the - * data. The purpose is to use it in combination with nm_auto_clear_secret_ptr - * which ensures that the data pointer (with all len bytes) is cleared upon - * cleanup. */ -typedef struct { - gsize len; - - /* the data pointer. This pointer must be allocated with malloc (at least - * when used with nm_secret_ptr_clear()). */ - union { - char *str; - void *ptr; - guint8 *bin; - }; -} NMSecretPtr; - -static inline void -nm_secret_ptr_clear (NMSecretPtr *secret) -{ - if (secret) { - if (secret->len > 0) { - if (secret->ptr) - nm_explicit_bzero (secret->ptr, secret->len); - secret->len = 0; - } - nm_clear_g_free (&secret->ptr); - } -} - -#define nm_auto_clear_secret_ptr nm_auto(nm_secret_ptr_clear) - -#define NM_SECRET_PTR_STATIC(_len) \ - ((const NMSecretPtr) { \ - .len = _len, \ - .ptr = ((guint8 [_len]) { }), \ - }) - -static inline void -nm_secret_ptr_clear_static (const NMSecretPtr *secret) -{ - if (secret) { - if (secret->len > 0) { - nm_assert (secret->ptr); - nm_explicit_bzero (secret->ptr, secret->len); - } - } -} - -#define nm_auto_clear_static_secret_ptr nm_auto(nm_secret_ptr_clear_static) - -static inline void -nm_secret_ptr_move (NMSecretPtr *dst, NMSecretPtr *src) -{ - if (dst && dst != src) { - *dst = *src; - src->len = 0; - src->ptr = NULL; - } -} - -/*****************************************************************************/ - -typedef struct { - const gsize len; - union { - char str[0]; - guint8 bin[0]; - }; -} NMSecretBuf; - -static inline void -_nm_auto_free_secret_buf (NMSecretBuf **ptr) -{ - NMSecretBuf *b = *ptr; - - if (b) { - nm_assert (b->len > 0); - nm_explicit_bzero (b->bin, b->len); - g_free (b); - } -} -#define nm_auto_free_secret_buf nm_auto(_nm_auto_free_secret_buf) - -NMSecretBuf *nm_secret_buf_new (gsize len); - -GBytes *nm_secret_buf_to_gbytes_take (NMSecretBuf *secret, gssize actual_len); - -/*****************************************************************************/ - -#endif /* __NM_SECRET_UTILS_H__ */ diff --git a/shared/nm-utils/nm-shared-utils.c b/shared/nm-utils/nm-shared-utils.c index 022c0652..d0019c11 100644 --- a/shared/nm-utils/nm-shared-utils.c +++ b/shared/nm-utils/nm-shared-utils.c @@ -97,7 +97,7 @@ nm_utils_strbuf_append (char **buf, gsize *len, const char *format, ...) { char *p = *buf; va_list args; - int retval; + gint retval; if (*len == 0) return; @@ -106,7 +106,7 @@ nm_utils_strbuf_append (char **buf, gsize *len, const char *format, ...) retval = g_vsnprintf (p, *len, format, args); va_end (args); - if ((gsize) retval >= *len) { + if (retval >= *len) { *buf = &p[*len]; *len = 0; } else { @@ -115,131 +115,6 @@ nm_utils_strbuf_append (char **buf, gsize *len, const char *format, ...) } } -/** - * nm_utils_strbuf_seek_end: - * @buf: the input/output buffer - * @len: the input/output lenght of the buffer. - * - * Commonly, one uses nm_utils_strbuf_append*(), to incrementally - * append strings to the buffer. However, sometimes we need to use - * existing API to write to the buffer. - * After doing so, we want to adjust the buffer counter. - * Essentially, - * - * g_snprintf (buf, len, ...); - * nm_utils_strbuf_seek_end (&buf, &len); - * - * is almost the same as - * - * nm_utils_strbuf_append (&buf, &len, ...); - * - * The only difference is the behavior when the string got truncated: - * nm_utils_strbuf_append() will recognize that and set the remaining - * length to zero. - * - * In general, the behavior is: - * - * - if *len is zero, do nothing - * - if the buffer contains a NUL byte within the first *len characters, - * the buffer is pointed to the NUL byte and len is adjusted. In this - * case, the remaining *len is always >= 1. - * In particular, that is also the case if the NUL byte is at the very last - * position ((*buf)[*len -1]). That happens, when the previous operation - * either fit the string exactly into the buffer or the string was truncated - * by g_snprintf(). The difference cannot be determined. - * - if the buffer contains no NUL bytes within the first *len characters, - * write NUL at the last position, set *len to zero, and point *buf past - * the NUL byte. This would happen with - * - * strncpy (buf, long_str, len); - * nm_utils_strbuf_seek_end (&buf, &len). - * - * where strncpy() does truncate the string and not NUL terminate it. - * nm_utils_strbuf_seek_end() would then NUL terminate it. - */ -void -nm_utils_strbuf_seek_end (char **buf, gsize *len) -{ - gsize l; - char *end; - - nm_assert (len); - nm_assert (buf && *buf); - - if (*len <= 1) { - if ( *len == 1 - && (*buf)[0]) - goto truncate; - return; - } - - end = memchr (*buf, 0, *len); - if (end) { - l = end - *buf; - nm_assert (l < *len); - - *buf = end; - *len -= l; - return; - } - -truncate: - /* hm, no NUL character within len bytes. - * Just NUL terminate the array and consume them - * all. */ - *buf += *len; - (*buf)[-1] = '\0'; - *len = 0; - return; -} - -/*****************************************************************************/ - -/** - * nm_utils_gbytes_equals: - * @bytes: (allow-none): a #GBytes array to compare. Note that - * %NULL is treated like an #GBytes array of length zero. - * @mem_data: the data pointer with @mem_len bytes - * @mem_len: the length of the data pointer - * - * Returns: %TRUE if @bytes contains the same data as @mem_data. As a - * special case, a %NULL @bytes is treated like an empty array. - */ -gboolean -nm_utils_gbytes_equal_mem (GBytes *bytes, - gconstpointer mem_data, - gsize mem_len) -{ - gconstpointer p; - gsize l; - - if (!bytes) { - /* as a special case, let %NULL GBytes compare idential - * to an empty array. */ - return (mem_len == 0); - } - - p = g_bytes_get_data (bytes, &l); - return l == mem_len - && ( mem_len == 0 /* allow @mem_data to be %NULL */ - || memcmp (p, mem_data, mem_len) == 0); -} - -GVariant * -nm_utils_gbytes_to_variant_ay (GBytes *bytes) -{ - const guint8 *p; - gsize l; - - if (!bytes) { - /* for convenience, accept NULL to return an empty variant */ - return g_variant_new_array (G_VARIANT_TYPE_BYTE, NULL, 0); - } - - p = g_bytes_get_data (bytes, &l); - return g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, p, l, 1); -} - /*****************************************************************************/ /** @@ -781,7 +656,6 @@ comp_l: * @str: the string to split. * @delimiters: the set of delimiters. If %NULL, defaults to " \t\n", * like bash's $IFS. - * @allow_escaping: whether delimiters can be escaped by a backslash * * This is a replacement for g_strsplit_set() which avoids copying * each word once (the entire strv array), but instead copies it once @@ -790,10 +664,6 @@ comp_l: * Another difference from g_strsplit_set() is that this never returns * empty words. Multiple delimiters are combined and treated as one. * - * If @allow_escaping is %TRUE, delimiters prefixed by a backslash are - * not treated as a separator. Such delimiters and their escape - * character are copied to the current word without unescaping them. - * * 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 @@ -803,7 +673,7 @@ comp_l: * but free everything with g_free(). */ const char ** -nm_utils_strsplit_set (const char *str, const char *delimiters, gboolean allow_escaping) +nm_utils_strsplit_set (const char *str, const char *delimiters) { const char **ptr, **ptr0; gsize alloc_size, plen, i; @@ -811,7 +681,6 @@ nm_utils_strsplit_set (const char *str, const char *delimiters, gboolean allow_e char *s0; char *s; guint8 delimiters_table[256]; - gboolean escaped = FALSE; if (!str) return NULL; @@ -823,23 +692,13 @@ nm_utils_strsplit_set (const char *str, const char *delimiters, gboolean allow_e for (i = 0; delimiters[i]; i++) delimiters_table[(guint8) delimiters[i]] = 1; -#define _is_delimiter(ch, delimiters_table, allow_esc, esc) \ - ((delimiters_table)[(guint8) (ch)] != 0 && (!allow_esc || !esc)) - -#define next_char(p, esc) \ - G_STMT_START { \ - if (esc) \ - esc = FALSE; \ - else \ - esc = p[0] == '\\'; \ - p++; \ - } G_STMT_END +#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, allow_escaping, escaped)) - next_char (str, escaped); - + while (_is_delimiter (str[0], delimiters_table)) + str++; if (!str[0]) return NULL; @@ -871,20 +730,20 @@ nm_utils_strsplit_set (const char *str, const char *delimiters, gboolean allow_e ptr[plen++] = s; - nm_assert (s[0] && !_is_delimiter (s[0], delimiters_table, allow_escaping, escaped)); + nm_assert (s[0] && !_is_delimiter (s[0], delimiters_table)); while (TRUE) { - next_char (s, escaped); - if (_is_delimiter (s[0], delimiters_table, allow_escaping, escaped)) + s++; + if (_is_delimiter (s[0], delimiters_table)) break; if (s[0] == '\0') goto done; } s[0] = '\0'; - next_char (s, escaped); - while (_is_delimiter (s[0], delimiters_table, allow_escaping, escaped)) - next_char (s, escaped); + s++; + while (_is_delimiter (s[0], delimiters_table)) + s++; if (s[0] == '\0') break; } @@ -981,9 +840,9 @@ _nm_utils_strv_cleanup (char **strv, /*****************************************************************************/ -int +gint _nm_utils_ascii_str_to_bool (const char *str, - int default_value) + gint default_value) { gsize len; char *s = NULL; @@ -1065,7 +924,7 @@ nm_utils_error_is_cancelled (GError *error, */ gboolean nm_g_object_set_property (GObject *object, - const char *property_name, + const gchar *property_name, const GValue *value, GError **error) { @@ -1140,7 +999,7 @@ nm_g_object_set_property (GObject *object, gboolean nm_g_object_set_property_boolean (GObject *object, - const char *property_name, + const gchar *property_name, gboolean value, GError **error) { @@ -1153,7 +1012,7 @@ nm_g_object_set_property_boolean (GObject *object, gboolean nm_g_object_set_property_uint (GObject *object, - const char *property_name, + const gchar *property_name, guint value, GError **error) { @@ -1185,112 +1044,20 @@ _str_append_escape (GString *s, char ch) g_string_append_c (s, '0' + ( ((guchar) ch) & 07)); } -gconstpointer -nm_utils_buf_utf8safe_unescape (const char *str, gsize *out_len, gpointer *to_free) -{ - GString *gstr; - gsize len; - const char *s; - - g_return_val_if_fail (to_free, NULL); - g_return_val_if_fail (out_len, NULL); - - if (!str) { - *out_len = 0; - *to_free = NULL; - return NULL; - } - - len = strlen (str); - - s = memchr (str, '\\', len); - if (!s) { - *out_len = len; - *to_free = NULL; - return str; - } - - gstr = g_string_new_len (NULL, len); - - g_string_append_len (gstr, str, s - str); - str = s; - - for (;;) { - char ch; - guint v; - - nm_assert (str[0] == '\\'); - - ch = (++str)[0]; - - if (ch == '\0') { - // error. Trailing '\\' - break; - } - - if (ch >= '0' && ch <= '9') { - v = ch - '0'; - ch = (++str)[0]; - if (ch >= '0' && ch <= '7') { - v = v * 8 + (ch - '0'); - ch = (++str)[0]; - if (ch >= '0' && ch <= '7') { - v = v * 8 + (ch - '0'); - ch = (++str)[0]; - } - } - ch = v; - } else { - switch (ch) { - case 'b': ch = '\b'; break; - case 'f': ch = '\f'; break; - case 'n': ch = '\n'; break; - case 'r': ch = '\r'; break; - case 't': ch = '\t'; break; - case 'v': ch = '\v'; break; - default: - /* Here we handle "\\\\", but all other unexpected escape sequences are really a bug. - * Take them literally, after removing the escape character */ - break; - } - str++; - } - - g_string_append_c (gstr, ch); - - s = strchr (str, '\\'); - if (!s) { - g_string_append (gstr, str); - break; - } - - g_string_append_len (gstr, str, s - str); - str = s; - } - - *out_len = gstr->len; - *to_free = gstr->str; - return g_string_free (gstr, FALSE); -} - /** - * nm_utils_buf_utf8safe_escape: - * @buf: byte array, possibly in utf-8 encoding, may have NUL characters. - * @buflen: the length of @buf in bytes, or -1 if @buf is a NUL terminated - * string. + * nm_utils_str_utf8safe_escape: + * @str: NUL terminated input string, possibly in utf-8 encoding * @flags: #NMUtilsStrUtf8SafeFlags flags * @to_free: (out): return the pointer location of the string * if a copying was necessary. * - * Based on the assumption, that @buf contains UTF-8 encoded bytes, - * this will return valid UTF-8 sequence, and invalid sequences - * will be escaped with backslash (C escaping, like g_strescape()). - * This is sanitize non UTF-8 characters. The result is valid + * Returns the possible non-UTF-8 NUL terminated string @str + * and uses backslash escaping (C escaping, like g_strescape()) + * to sanitize non UTF-8 characters. The result is valid * UTF-8. * - * The operation can be reverted with nm_utils_buf_utf8safe_unescape(). - * Note that if, and only if @buf contains no NUL bytes, the operation - * can also be reverted with g_strcompress(). + * The operation can be reverted with g_strcompress() or + * nm_utils_str_utf8safe_unescape(). * * Depending on @flags, valid UTF-8 characters are not escaped at all * (except the escape character '\\'). This is the difference to g_strescape(), @@ -1299,106 +1066,62 @@ nm_utils_buf_utf8safe_unescape (const char *str, gsize *out_len, gpointer *to_fr * as UTF-8 -- with exception of the backslash escape character, * invalid UTF-8 sequences, and other (depending on @flags). * - * Returns: the escaped input buffer, as valid UTF-8. If no escaping - * is necessary, it returns the input @buf. Otherwise, an allocated + * Returns: the escaped input string, as valid UTF-8. If no escaping + * is necessary, it returns the input @str. Otherwise, an allocated * string @to_free is returned which must be freed by the caller * with g_free. The escaping can be reverted by g_strcompress(). **/ const char * -nm_utils_buf_utf8safe_escape (gconstpointer buf, gssize buflen, NMUtilsStrUtf8SafeFlags flags, char **to_free) +nm_utils_str_utf8safe_escape (const char *str, NMUtilsStrUtf8SafeFlags flags, char **to_free) { - const char *const str = buf; const char *p = NULL; - const char *s; - gboolean nul_terminated = FALSE; - GString *gstr; + GString *s; g_return_val_if_fail (to_free, NULL); *to_free = NULL; + if (!str || !str[0]) + return str; - if (buflen == 0) - return NULL; - - if (buflen < 0) { - if (!str) - return NULL; - buflen = strlen (str); - if (buflen == 0) - return str; - nul_terminated = TRUE; - } - - if ( g_utf8_validate (str, buflen, &p) - && nul_terminated) { - /* note that g_utf8_validate() does not allow NUL character inside @str. Good. - * We can treat @str like a NUL terminated string. */ - if (!NM_STRCHAR_ANY (str, ch, - ( ch == '\\' \ - || ( NM_FLAGS_HAS (flags, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL) \ - && ch < ' ') \ - || ( NM_FLAGS_HAS (flags, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_NON_ASCII) \ - && ((guchar) ch) >= 127)))) - return str; - } + if ( g_utf8_validate (str, -1, &p) + && !NM_STRCHAR_ANY (str, ch, + ( ch == '\\' \ + || ( NM_FLAGS_HAS (flags, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL) \ + && ch < ' ') \ + || ( NM_FLAGS_HAS (flags, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_NON_ASCII) \ + && ((guchar) ch) >= 127)))) + return str; - gstr = g_string_sized_new (buflen + 5); + s = g_string_sized_new ((p - str) + strlen (p) + 5); - s = str; do { - buflen -= p - s; - nm_assert (buflen >= 0); - - for (; s < p; s++) { - char ch = s[0]; + for (; str < p; str++) { + char ch = str[0]; if (ch == '\\') - g_string_append (gstr, "\\\\"); + g_string_append (s, "\\\\"); else if ( ( NM_FLAGS_HAS (flags, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL) \ && ch < ' ') \ || ( NM_FLAGS_HAS (flags, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_NON_ASCII) \ && ((guchar) ch) >= 127)) - _str_append_escape (gstr, ch); + _str_append_escape (s, ch); else - g_string_append_c (gstr, ch); + g_string_append_c (s, ch); } - if (buflen <= 0) - break; - - _str_append_escape (gstr, p[0]); - - buflen--; - if (buflen == 0) + if (p[0] == '\0') break; + _str_append_escape (s, p[0]); - s = &p[1]; - g_utf8_validate (s, buflen, &p); + str = &p[1]; + g_utf8_validate (str, -1, &p); } while (TRUE); - *to_free = g_string_free (gstr, FALSE); + *to_free = g_string_free (s, FALSE); return *to_free; } const char * -nm_utils_buf_utf8safe_escape_bytes (GBytes *bytes, NMUtilsStrUtf8SafeFlags flags, char **to_free) -{ - gconstpointer p; - gsize l; - - if (bytes) - p = g_bytes_get_data (bytes, &l); - else { - p = NULL; - l = 0; - } - - return nm_utils_buf_utf8safe_escape (p, l, flags, to_free); -} - -/*****************************************************************************/ - -const char * nm_utils_str_utf8safe_unescape (const char *str, char **to_free) { g_return_val_if_fail (to_free, NULL); @@ -1411,39 +1134,6 @@ nm_utils_str_utf8safe_unescape (const char *str, char **to_free) } /** - * nm_utils_str_utf8safe_escape: - * @str: NUL terminated input string, possibly in utf-8 encoding - * @flags: #NMUtilsStrUtf8SafeFlags flags - * @to_free: (out): return the pointer location of the string - * if a copying was necessary. - * - * Returns the possible non-UTF-8 NUL terminated string @str - * and uses backslash escaping (C escaping, like g_strescape()) - * to sanitize non UTF-8 characters. The result is valid - * UTF-8. - * - * The operation can be reverted with g_strcompress() or - * nm_utils_str_utf8safe_unescape(). - * - * Depending on @flags, valid UTF-8 characters are not escaped at all - * (except the escape character '\\'). This is the difference to g_strescape(), - * which escapes all non-ASCII characters. This allows to pass on - * valid UTF-8 characters as-is and can be directly shown to the user - * as UTF-8 -- with exception of the backslash escape character, - * invalid UTF-8 sequences, and other (depending on @flags). - * - * Returns: the escaped input string, as valid UTF-8. If no escaping - * is necessary, it returns the input @str. Otherwise, an allocated - * string @to_free is returned which must be freed by the caller - * with g_free. The escaping can be reverted by g_strcompress(). - **/ -const char * -nm_utils_str_utf8safe_escape (const char *str, NMUtilsStrUtf8SafeFlags flags, char **to_free) -{ - return nm_utils_buf_utf8safe_escape (str, -1, flags, to_free); -} - -/** * nm_utils_str_utf8safe_escape_cp: * @str: NUL terminated input string, possibly in utf-8 encoding * @flags: #NMUtilsStrUtf8SafeFlags flags @@ -1660,209 +1350,6 @@ nm_utils_strv_make_deep_copied (const char **strv) /*****************************************************************************/ -gssize -nm_utils_ptrarray_find_binary_search (gconstpointer *list, - gsize len, - gconstpointer needle, - GCompareDataFunc cmpfcn, - gpointer user_data, - gssize *out_idx_first, - gssize *out_idx_last) -{ - gssize imin, imax, imid, i2min, i2max, i2mid; - int cmp; - - g_return_val_if_fail (list || !len, ~((gssize) 0)); - g_return_val_if_fail (cmpfcn, ~((gssize) 0)); - - imin = 0; - if (len > 0) { - imax = len - 1; - - while (imin <= imax) { - imid = imin + (imax - imin) / 2; - - cmp = cmpfcn (list[imid], needle, user_data); - if (cmp == 0) { - /* we found a matching entry at index imid. - * - * Does the caller request the first/last index as well (in case that - * there are multiple entries which compare equal). */ - - if (out_idx_first) { - i2min = imin; - i2max = imid + 1; - while (i2min <= i2max) { - i2mid = i2min + (i2max - i2min) / 2; - - cmp = cmpfcn (list[i2mid], needle, user_data); - if (cmp == 0) - i2max = i2mid -1; - else { - nm_assert (cmp < 0); - i2min = i2mid + 1; - } - } - *out_idx_first = i2min; - } - if (out_idx_last) { - i2min = imid + 1; - i2max = imax; - while (i2min <= i2max) { - i2mid = i2min + (i2max - i2min) / 2; - - cmp = cmpfcn (list[i2mid], needle, user_data); - if (cmp == 0) - i2min = i2mid + 1; - else { - nm_assert (cmp > 0); - i2max = i2mid - 1; - } - } - *out_idx_last = i2min - 1; - } - return imid; - } - - if (cmp < 0) - imin = imid + 1; - else - imax = imid - 1; - } - } - - /* return the inverse of @imin. This is a negative number, but - * also is ~imin the position where the value should be inserted. */ - imin = ~imin; - NM_SET_OUT (out_idx_first, imin); - NM_SET_OUT (out_idx_last, imin); - return imin; -} - -/*****************************************************************************/ - -/** - * nm_utils_array_find_binary_search: - * @list: the list to search. It must be sorted according to @cmpfcn ordering. - * @elem_size: the size in bytes of each element in the list - * @len: the number of elements in @list - * @needle: the value that is searched - * @cmpfcn: the compare function. The elements @list are passed as first - * argument to @cmpfcn, while @needle is passed as second. Usually, the - * needle is the same data type as inside the list, however, that is - * not necessary, as long as @cmpfcn takes care to cast the two arguments - * accordingly. - * @user_data: optional argument passed to @cmpfcn - * - * Performs binary search for @needle in @list. On success, returns the - * (non-negative) index where the compare function found the searched element. - * On success, it returns a negative value. Note that the return negative value - * is the bitwise inverse of the position where the element should be inserted. - * - * If the list contains multiple matching elements, an arbitrary index is - * returned. - * - * Returns: the index to the element in the list, or the (negative, bitwise inverted) - * position where it should be. - */ -gssize -nm_utils_array_find_binary_search (gconstpointer list, - gsize elem_size, - gsize len, - gconstpointer needle, - GCompareDataFunc cmpfcn, - gpointer user_data) -{ - gssize imin, imax, imid; - int cmp; - - g_return_val_if_fail (list || !len, ~((gssize) 0)); - g_return_val_if_fail (cmpfcn, ~((gssize) 0)); - g_return_val_if_fail (elem_size > 0, ~((gssize) 0)); - - imin = 0; - if (len == 0) - return ~imin; - - imax = len - 1; - - while (imin <= imax) { - imid = imin + (imax - imin) / 2; - - cmp = cmpfcn (&((const char *) list)[elem_size * imid], needle, user_data); - if (cmp == 0) - return imid; - - if (cmp < 0) - imin = imid + 1; - else - imax = imid - 1; - } - - /* return the inverse of @imin. This is a negative number, but - * also is ~imin the position where the value should be inserted. */ - return ~imin; -} - -/*****************************************************************************/ - -/** - * nm_utils_hash_table_equal: - * @a: one #GHashTable - * @b: other #GHashTable - * @treat_null_as_empty: if %TRUE, when either @a or @b is %NULL, it is - * treated like an empty hash. It means, a %NULL hash will compare equal - * to an empty hash. - * @equal_func: the equality function, for comparing the values. - * If %NULL, the values are not compared. In that case, the function - * only checks, if both dictionaries have the same keys -- according - * to @b's key equality function. - * Note that the values of @a will be passed as first argument - * to @equal_func. - * - * Compares two hash tables, whether they have equal content. - * This only makes sense, if @a and @b have the same key types and - * the same key compare-function. - * - * Returns: %TRUE, if both dictionaries have the same content. - */ -gboolean -nm_utils_hash_table_equal (const GHashTable *a, - const GHashTable *b, - gboolean treat_null_as_empty, - NMUtilsHashTableEqualFunc equal_func) -{ - guint n; - GHashTableIter iter; - gconstpointer key, v_a, v_b; - - if (a == b) - return TRUE; - if (!treat_null_as_empty) { - if (!a || !b) - return FALSE; - } - - n = a ? g_hash_table_size ((GHashTable *) a) : 0; - if (n != (b ? g_hash_table_size ((GHashTable *) b) : 0)) - return FALSE; - - if (n > 0) { - g_hash_table_iter_init (&iter, (GHashTable *) a); - while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &v_a)) { - if (!g_hash_table_lookup_extended ((GHashTable *) b, key, NULL, (gpointer *) &v_b)) - return FALSE; - if ( equal_func - && !equal_func (v_a, v_b)) - return FALSE; - } - } - - return TRUE; -} - -/*****************************************************************************/ - /** * nm_utils_get_start_time_for_pid: * @pid: the process identifier @@ -1882,10 +1369,10 @@ nm_utils_get_start_time_for_pid (pid_t pid, char *out_state, pid_t *out_ppid) { guint64 start_time; char filename[256]; - gs_free char *contents = NULL; + gs_free gchar *contents = NULL; size_t length; gs_free const char **tokens = NULL; - char *p; + gchar *p; char state = ' '; gint64 ppid = 0; @@ -1912,7 +1399,7 @@ nm_utils_get_start_time_for_pid (pid_t pid, char *out_state, pid_t *out_ppid) state = p[0]; - tokens = nm_utils_strsplit_set (p, " ", FALSE); + tokens = nm_utils_strsplit_set (p, " "); if (NM_PTRARRAY_LEN (tokens) < 20) goto fail; @@ -2012,60 +1499,3 @@ _nm_utils_user_data_unpack (gpointer user_data, int nargs, ...) g_slice_free1 (((gsize) nargs) * sizeof (gconstpointer), user_data); } - -/*****************************************************************************/ - -#define IS_SPACE(c) NM_IN_SET ((c), ' ', '\t') - -const char * -_nm_utils_escape_spaces (const char *str, char **to_free) -{ - const char *ptr = str; - char *ret, *r; - - *to_free = NULL; - - if (!str) - return NULL; - - while (TRUE) { - if (!*ptr) - return str; - if (IS_SPACE (*ptr)) - break; - ptr++; - } - - ptr = str; - ret = g_new (char, strlen (str) * 2 + 1); - r = ret; - *to_free = ret; - while (*ptr) { - if (IS_SPACE (*ptr)) - *r++ = '\\'; - *r++ = *ptr++; - } - *r = '\0'; - - return ret; -} - -char * -_nm_utils_unescape_spaces (char *str) -{ - guint i, j = 0; - - if (!str) - return NULL; - - for (i = 0; str[i]; i++) { - if (str[i] == '\\' && IS_SPACE (str[i+1])) - i++; - str[j++] = str[i]; - } - str[j] = '\0'; - - return str; -} - -#undef IS_SPACE diff --git a/shared/nm-utils/nm-shared-utils.h b/shared/nm-utils/nm-shared-utils.h index 5125bd3d..d983cfcd 100644 --- a/shared/nm-utils/nm-shared-utils.h +++ b/shared/nm-utils/nm-shared-utils.h @@ -26,25 +26,6 @@ /*****************************************************************************/ -static inline gboolean -_NM_INT_NOT_NEGATIVE (gssize val) -{ - /* whether an enum (without negative values) is a signed int, depends on compiler options - * and compiler implementation. - * - * When using such an enum for accessing an array, one naturally wants to check - * that the enum is not negative. However, the compiler doesn't like a plain - * comparisong "enum_val >= 0", because (if the enum is unsigned), it will warn - * that the expression is always true *duh*. Not even a cast to a signed - * type helps to avoid the compiler warning in any case. - * - * The sole purpose of this function is to avoid a compiler warning, when checking - * that an enum is not negative. */ - return val >= 0; -} - -/*****************************************************************************/ - static inline char nm_utils_addr_family_to_char (int addr_family) { @@ -190,53 +171,6 @@ nm_ip_addr_set (int addr_family, gpointer dst, const NMIPAddr *src) /*****************************************************************************/ -static inline gboolean -nm_utils_mem_all_zero (gconstpointer mem, gsize len) -{ - const guint8 *p; - - for (p = mem; len-- > 0; p++) { - if (*p != 0) - return FALSE; - } - - /* incidentally, a buffer with len==0, is also *all-zero*. */ - return TRUE; -} - -/*****************************************************************************/ - -/* like g_memdup(). The difference is that the @size argument is of type - * gsize, while g_memdup() has type guint. Since, the size of container types - * like GArray is guint as well, this means trying to g_memdup() an - * array, - * g_memdup (array->data, array->len * sizeof (ElementType)) - * will lead to integer overflow, if there are more than G_MAXUINT/sizeof(ElementType) - * bytes. That seems unnecessarily dangerous to me. - * nm_memdup() avoids that, because its size argument is always large enough - * to contain all data that a GArray can hold. - * - * Another minor difference to g_memdup() is that the glib version also - * returns %NULL if @data is %NULL. E.g. g_memdup(NULL, 1) - * gives %NULL, but nm_memdup(NULL, 1) crashes. I think that - * is desirable, because @size MUST be correct at all times. @size - * may be zero, but one must not claim to have non-zero bytes when - * passing a %NULL @data pointer. - */ -static inline gpointer -nm_memdup (gconstpointer data, gsize size) -{ - gpointer p; - - if (size == 0) - return NULL; - p = g_malloc (size); - memcpy (p, data, size); - return p; -} - -/*****************************************************************************/ - extern const void *const _NM_PTRARRAY_EMPTY[1]; #define NM_PTRARRAY_EMPTY(type) ((type const*) _NM_PTRARRAY_EMPTY) @@ -257,7 +191,6 @@ _nm_utils_strbuf_init (char *buf, gsize len, char **p_buf_ptr, gsize *p_buf_len) 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); -void nm_utils_strbuf_seek_end (char **buf, gsize *len); const char *nm_strquote (char *buf, gsize buf_len, const char *str); @@ -269,48 +202,13 @@ nm_utils_is_separator (const char c) /*****************************************************************************/ -static inline gboolean -nm_gbytes_equal0 (GBytes *a, GBytes *b) -{ - return a == b || (a && b && g_bytes_equal (a, b)); -} - -gboolean nm_utils_gbytes_equal_mem (GBytes *bytes, - gconstpointer mem_data, - gsize mem_len); - -GVariant *nm_utils_gbytes_to_variant_ay (GBytes *bytes); - -/*****************************************************************************/ - -static inline int -nm_utils_hexchar_to_int (char ch) -{ - G_STATIC_ASSERT_EXPR ('0' < 'A'); - G_STATIC_ASSERT_EXPR ('A' < 'a'); - - if (ch >= '0') { - if (ch <= '9') - return ch - '0'; - if (ch >= 'A') { - if (ch <= 'F') - return ((int) ch) + (10 - (int) 'A'); - if (ch >= 'a' && ch <= 'f') - return ((int) ch) + (10 - (int) 'a'); - } - } - return -1; -} - -/*****************************************************************************/ - const char *nm_utils_dbus_path_get_last_component (const char *dbus_path); int nm_utils_dbus_path_cmp (const char *dbus_path_a, const char *dbus_path_b); /*****************************************************************************/ -const char **nm_utils_strsplit_set (const char *str, const char *delimiters, gboolean allow_escaping); +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); @@ -349,8 +247,8 @@ gboolean nm_utils_parse_inaddr_prefix (int addr_family, gint64 _nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 max, gint64 fallback); -int _nm_utils_ascii_str_to_bool (const char *str, - int default_value); +gint _nm_utils_ascii_str_to_bool (const char *str, + gint default_value); /*****************************************************************************/ @@ -480,19 +378,6 @@ _nm_g_slice_free_fcn_define (16) /*****************************************************************************/ -static inline int -nm_errno (int errsv) -{ - /* several API returns negative errno values as errors. Normalize - * negative values to positive values. - * - * As a special case, map G_MININT to G_MAXINT. If you care about the - * distinction, then check for G_MININT before. */ - return errsv >= 0 - ? errsv - : ((errsv == G_MININT) ? G_MAXINT : -errsv); -} - /** * NMUtilsError: * @NM_UTILS_ERROR_UNKNOWN: unknown or unclassified error @@ -501,40 +386,12 @@ nm_errno (int errsv) * error reason. Depending on the usage, this might indicate a bug because * usually the target object should stay alive as long as there are pending * operations. - * - * @NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE: used for a very particular - * purpose during nm_device_check_connection_compatible() to indicate that - * the profile does not match the device already because their type differs. - * That is, there is a fundamental reason of trying to check a profile that - * cannot possibly match on this device. - * @NM_UTILS_ERROR_CONNECTION_AVAILABLE_UNMANAGED_DEVICE: used for a very particular - * purpose during nm_device_check_connection_available(), to indicate that the - * device is not available because it is unmanaged. - * @NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY: the profile is currently not - * available/compatible with the device, but this may be only temporary. - * * @NM_UTILS_ERROR_INVALID_ARGUMENT: invalid argument. */ typedef enum { NM_UTILS_ERROR_UNKNOWN = 0, /*< nick=Unknown >*/ NM_UTILS_ERROR_CANCELLED_DISPOSING, /*< nick=CancelledDisposing >*/ NM_UTILS_ERROR_INVALID_ARGUMENT, /*< nick=InvalidArgument >*/ - - /* the following codes have a special meaning and are exactly used for - * nm_device_check_connection_compatible() and nm_device_check_connection_available(). - * - * Actually, their meaning is not very important (so, don't think too - * hard about the name of these error codes). What is important, is their - * relative order (i.e. the integer value of the codes). When manager - * searches for a suitable device, it will check all devices whether - * a profile can be activated. If they all fail, it will pick the error - * message from the device that returned the *highest* error code, - * in the hope that this message makes the most sense for the caller. - * */ - NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE, - NM_UTILS_ERROR_CONNECTION_AVAILABLE_UNMANAGED_DEVICE, - NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - } NMUtilsError; #define NM_UTILS_ERROR (nm_utils_error_quark ()) @@ -546,37 +403,20 @@ void nm_utils_error_set_cancelled (GError **error, gboolean nm_utils_error_is_cancelled (GError *error, gboolean consider_is_disposing); -static inline void -nm_utils_error_set_literal (GError **error, int error_code, const char *literal) -{ - g_set_error_literal (error, NM_UTILS_ERROR, error_code, literal); -} - -#define nm_utils_error_set(error, error_code, ...) \ - g_set_error ((error), NM_UTILS_ERROR, error_code, __VA_ARGS__) - -#define nm_utils_error_set_errno(error, errsv, fmt, ...) \ - g_set_error ((error), \ - NM_UTILS_ERROR, \ - NM_UTILS_ERROR_UNKNOWN, \ - fmt, \ - ##__VA_ARGS__, \ - g_strerror (nm_errno (errsv))) - /*****************************************************************************/ gboolean nm_g_object_set_property (GObject *object, - const char *property_name, + const gchar *property_name, const GValue *value, GError **error); gboolean nm_g_object_set_property_boolean (GObject *object, - const char *property_name, + const gchar *property_name, gboolean value, GError **error); gboolean nm_g_object_set_property_uint (GObject *object, - const char *property_name, + const gchar *property_name, guint value, GError **error); @@ -591,10 +431,6 @@ typedef enum { NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_NON_ASCII = 0x0002, } NMUtilsStrUtf8SafeFlags; -const char *nm_utils_buf_utf8safe_escape (gconstpointer buf, gssize buflen, NMUtilsStrUtf8SafeFlags flags, char **to_free); -const char *nm_utils_buf_utf8safe_escape_bytes (GBytes *bytes, NMUtilsStrUtf8SafeFlags flags, char **to_free); -gconstpointer nm_utils_buf_utf8safe_unescape (const char *str, gsize *out_len, gpointer *to_free); - const char *nm_utils_str_utf8safe_escape (const char *str, NMUtilsStrUtf8SafeFlags flags, char **to_free); const char *nm_utils_str_utf8safe_unescape (const char *str, char **to_free); @@ -682,35 +518,6 @@ nm_utils_strv_make_deep_copied_nonnull (const char **strv) return nm_utils_strv_make_deep_copied (strv) ?: g_new0 (char *, 1); } -/*****************************************************************************/ - -gssize nm_utils_ptrarray_find_binary_search (gconstpointer *list, - gsize len, - gconstpointer needle, - GCompareDataFunc cmpfcn, - gpointer user_data, - gssize *out_idx_first, - gssize *out_idx_last); - -gssize nm_utils_array_find_binary_search (gconstpointer list, - gsize elem_size, - gsize len, - gconstpointer needle, - GCompareDataFunc cmpfcn, - gpointer user_data); - -/*****************************************************************************/ - -typedef gboolean (*NMUtilsHashTableEqualFunc) (gconstpointer a, - gconstpointer b); - -gboolean nm_utils_hash_table_equal (const GHashTable *a, - const GHashTable *b, - gboolean treat_null_as_empty, - NMUtilsHashTableEqualFunc equal_func); - -/*****************************************************************************/ - void _nm_utils_strv_sort (const char **strv, gssize len); #define nm_utils_strv_sort(strv, len) _nm_utils_strv_sort (NM_CAST_STRV_MC (strv), len) @@ -845,7 +652,4 @@ void _nm_utils_user_data_unpack (gpointer user_data, int nargs, ...); /*****************************************************************************/ -const char *_nm_utils_escape_spaces (const char *str, char **to_free); -char *_nm_utils_unescape_spaces (char *str); - #endif /* __NM_SHARED_UTILS_H__ */ diff --git a/shared/nm-utils/nm-test-utils.h b/shared/nm-utils/nm-test-utils.h index b575382e..d29e9ae7 100644 --- a/shared/nm-utils/nm-test-utils.h +++ b/shared/nm-utils/nm-test-utils.h @@ -300,9 +300,9 @@ nmtst_free (void) } static inline void -_nmtst_log_handler (const char *log_domain, +_nmtst_log_handler (const gchar *log_domain, GLogLevelFlags log_level, - const char *message, + const gchar *message, gpointer user_data) { g_print ("%s\n", message); @@ -345,8 +345,6 @@ __nmtst_init (int *argc, char ***argv, gboolean assert_logging, const char *log_ __nmtst_internal.assert_logging = !!assert_logging; - nm_g_type_init (); - is_debug = g_test_verbose (); nmtst_debug = g_getenv ("NMTST_DEBUG"); @@ -553,13 +551,8 @@ __nmtst_init (int *argc, char ***argv, gboolean assert_logging, const char *log_ *out_set_logging = TRUE; #endif g_assert (success); -#if GLIB_CHECK_VERSION(2,34,0) if (__nmtst_internal.no_expect_message) g_log_set_always_fatal (G_LOG_FATAL_MASK); -#else - /* g_test_expect_message() is a NOP, so allow any messages */ - g_log_set_always_fatal (G_LOG_FATAL_MASK); -#endif } else if (__nmtst_internal.no_expect_message) { /* We have a test that would be assert_logging, but the user specified no_expect_message. * This transforms g_test_expect_message() into a NOP, but we also have to relax @@ -579,15 +572,10 @@ __nmtst_init (int *argc, char ***argv, gboolean assert_logging, const char *log_ } #endif } else { -#if GLIB_CHECK_VERSION(2,34,0) /* We were called not to set logging levels. This means, that the user * expects to assert against (all) messages. * Any uncaught message on >debug level is fatal. */ g_log_set_always_fatal (G_LOG_LEVEL_MASK & ~G_LOG_LEVEL_DEBUG); -#else - /* g_test_expect_message() is a NOP, so allow any messages */ - g_log_set_always_fatal (G_LOG_FATAL_MASK); -#endif } if ((!__nmtst_internal.assert_logging || (__nmtst_internal.assert_logging && __nmtst_internal.no_expect_message)) && @@ -654,7 +642,6 @@ nmtst_test_quick (void) return __nmtst_internal.test_quick; } -#if GLIB_CHECK_VERSION(2,34,0) #undef g_test_expect_message #define g_test_expect_message(...) \ G_STMT_START { \ @@ -662,9 +649,7 @@ nmtst_test_quick (void) if (__nmtst_internal.assert_logging && __nmtst_internal.no_expect_message) { \ g_debug ("nmtst: assert-logging: g_test_expect_message %s", G_STRINGIFY ((__VA_ARGS__))); \ } else { \ - G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ g_test_expect_message (__VA_ARGS__); \ - G_GNUC_END_IGNORE_DEPRECATIONS \ } \ } G_STMT_END #undef g_test_assert_expected_messages_internal @@ -678,11 +663,8 @@ nmtst_test_quick (void) if (__nmtst_internal.assert_logging && __nmtst_internal.no_expect_message) \ g_debug ("nmtst: assert-logging: g_test_assert_expected_messages(%s, %s:%d, %s)", _domain?:"", _file?:"", _line, _func?:""); \ \ - G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ g_test_assert_expected_messages_internal (_domain, _file, _line, _func); \ - G_GNUC_END_IGNORE_DEPRECATIONS \ } G_STMT_END -#endif #define NMTST_EXPECT(domain, level, msg) g_test_expect_message (domain, level, msg) @@ -824,7 +806,7 @@ nmtst_get_rand (void) g_rand_set_seed (__nmtst_internal.rand, seed); } else { /* NMTST_SEED_RAND is set. Use it as a seed. */ - char *s; + gchar *s; gint64 i; i = g_ascii_strtoll (str, &s, 0); @@ -1189,12 +1171,12 @@ _nmtst_assert_ip6_address (const char *file, int line, const struct in6_addr *ad #define nmtst_spawn_sync(working_directory, standard_out, standard_err, assert_exit_status, ...) \ __nmtst_spawn_sync (working_directory, standard_out, standard_err, assert_exit_status, ##__VA_ARGS__, NULL) -static inline int +static inline gint __nmtst_spawn_sync (const char *working_directory, char **standard_out, char **standard_err, int assert_exit_status, ...) G_GNUC_NULL_TERMINATED; -static inline int +static inline gint __nmtst_spawn_sync (const char *working_directory, char **standard_out, char **standard_err, int assert_exit_status, ...) { - int exit_status = 0; + gint exit_status = 0; GError *error = NULL; char *arg; va_list va_args; @@ -1677,7 +1659,7 @@ nmtst_assert_connection_verifies_and_normalizable (NMConnection *con) static inline void nmtst_assert_connection_verifies_after_normalization (NMConnection *con, GQuark expect_error_domain, - int expect_error_code) + gint expect_error_code) { /* assert that the connection does not verify, but normalization does fix it */ GError *error = NULL; @@ -1704,7 +1686,7 @@ nmtst_assert_connection_verifies_after_normalization (NMConnection *con, static inline void nmtst_assert_connection_unnormalizable (NMConnection *con, GQuark expect_error_domain, - int expect_error_code) + gint expect_error_code) { /* assert that the connection does not verify, and it cannot be fixed by normalization */ @@ -1761,7 +1743,7 @@ _nmtst_assert_connection_has_settings (NMConnection *connection, gboolean has_at va_start (ap, has_at_most); while ((name = va_arg (ap, const char *))) { - if (!nm_g_hash_table_add (names, (gpointer) name)) + if (!g_hash_table_add (names, (gpointer) name)) g_assert_not_reached (); g_ptr_array_add (names_arr, (gpointer) name); } @@ -1802,7 +1784,7 @@ _nmtst_assert_connection_has_settings (NMConnection *connection, gboolean has_at static inline void nmtst_assert_setting_verify_fails (NMSetting *setting, GQuark expect_error_domain, - int expect_error_code) + gint expect_error_code) { /* assert that the setting verification fails */ diff --git a/shared/nm-utils/unaligned.h b/shared/nm-utils/unaligned.h index e62188d1..965a5fe9 100644 --- a/shared/nm-utils/unaligned.h +++ b/shared/nm-utils/unaligned.h @@ -1,6 +1,10 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once +/*** + Copyright © 2014 Tom Gundersen +***/ + #include <endian.h> #include <stdint.h> |