Add macros that cast away the constness of a pointer, but
ensure that the type of the pointer is as expected.
Unfortunately, there is no way (AFAIK) to remove the constness of
a variable, without explicitly passing @type to the macro.
GCC 8.0's -Wcast-function-type objects casting function pointers to ones
with incompatible prototypes. Sometimes we do that on purpose though.
Notably, the g_source_set_callback()'s func argument can point to functions
of various prototypes. Also, libnm-glib/nm-remote-connection is perhaps
just not worth reworking, that would just be a waste of time.
A cast to void(*)(void) avoids the GCC warning, let's use it.
This makes its prototype compatible with GDestroyNotify so that GCC 8.0
won't warn.
The return value is not used anywhere and the unref() functions typically
don't return any.
When pushing a warning disable with clang, always disable
-Wunknown-warning-option first -- it might be that clang wouldn't warn
of what we're trying to disable because it doesn't recognize it in the
first place. That is entierely okay.
With clang-5.0.0:
CC libnm/tests/libnm_tests_test_secret_agent-test-secret-agent.o
In file included from libnm/tests/test-secret-agent.c:29:
In file included from ./shared/nm-test-libnm-utils.h:23:
./shared/nm-utils/nm-test-utils.h:432:3: error: unknown warning group '-Wunused-but-set-variable', ignored [-Werror,-Wunknown-warning-option]
NM_PRAGMA_WARNING_DISABLE("-Wunused-but-set-variable")
^
./shared/nm-utils/nm-macros-internal.h:223:9: note: expanded from macro 'NM_PRAGMA_WARNING_DISABLE'
_Pragma(_NM_PRAGMA_WARNING_DO(warning))
^
<scratch space>:204:25: note: expanded from here
GCC diagnostic ignored "-Wunused-but-set-variable"
^
1 error generated.
A cmp() implementation, for sorting an array with pointers, where each
pointer is an inteter according to GPOINTER_TO_INT().
That cames for example handy, if you have a GHashTable with keys
GINT_TO_POINTER(). Then you get the list of keys via
g_hash_table_get_keys_as_array() and want to sort them.
Sometimes, we want to use CList to track a simple data item. But contrary
to GList/GSList, we need to define a structure to hold the data pointer
and the CList member.
Add a generic NMCListElem type that can be used for such simple uses.
Before you ask: why not use GList/GSList? Because even simple operations
like g_list_append() is O(n), which kinda defeats the purpose of having
a doubly linked list.
This code is added to a new header file nm-c-list.h, the reason is that
there is no other good place:
- "nm-utils/c-list.h" is a clone of upstream, it should not deviate.
- "nm-utils/c-list-util.h" contains our utils functions for c-list.h
but should be plain C, independent of glib.
- "nm-utils/nm-shared-utils.h" contains our glib related utilities,
but it should not drag in "c-list.h".
So, "nm-c-list.h" is a utility libray that extends "c-list.h" and
requires glib.
Note that:
- we compile some source files multiple times. Most notably those
under "shared/".
- we include a default header "shared/nm-default.h" in every source
file. This header is supposed to setup a common environment by defining
and including parts that are commonly used. As we always include the
same header, the header must behave differently depending
one whether the compilation is for libnm-core, NetworkManager or
libnm-glib. E.g. it must include <glib/gi18n.h> or <glib/gi18n-lib.h>
depending on whether we compile a library or an application.
For that, the source files need the NETWORKMANAGER_COMPILATION #define
to behave accordingly.
Extend the define to be composed of flags. These flags are all named
NM_NETWORKMANAGER_COMPILATION_WITH_*, they indicate which part of the
build are available. E.g. when building libnm-core.la itself, then
WITH_LIBNM_CORE, WITH_LIBNM_CORE_INTERNAL, and WITH_LIBNM_CORE_PRIVATE
are available. When building NetworkManager, WITH_LIBNM_CORE_PRIVATE
is not available but the internal parts are still accessible. When
building nmcli, only WITH_LIBNM_CORE (the public part) is available.
This granularily controls the build.
This is still the very same approach (in the way the array is split
and how elements are compared). The only difference is that the
recursive implementation is replaced by a non-recursive one.
It's (still) stable, top-down merge-sort.
The non-recursive implementation better, because it avoids the overhead
of the function call to recurse.
The compat implementations return a (transfer none) strv instead of a
(transfer container) one. This has caused double frees in nm-applet:
https://bugs.archlinux.org/task/56772
Don't copy the keys and don't free the container later.
[thaller@redhat.com: patch adjusted to avoid compiler warning]
Fixes: 272439cb20
At several places we create strv arrays where the
strings themself are not deep-copied.
This helper function iterates over such an "const char **"
array, clones the strings, and updates the strv array
inplace to be a "char **" strv array.
This helper function is to reduce code duplication.
At various places we get the (string) keys of a GHashTable.
Add a helper function that does that, including an argument
for optional sorting.
The helper function is there to get reduce code duplication.
Systemd instroduces a macro _fallthrough_, see
https://github.com/systemd/systemd/pull/7389.
However, it does not yet seem conclusive how to
handle this properly in ever situation.
While shared/nm-utils/siphash24.c makes use of
the new macro, don't do that in our fork. siphash24.h
does not include all systemd headers, hence _fallthrough_
is not defined. We could re-implement it as _nm_fallthrough,
but given the open questions, that doesn't seem the
Systemd introduced a _fallthrough_ macro in
https://github.com/systemd/systemd/pull/7389.
There might still be some issue with it, but as
I am going to re-import the latest systemd code,
we get them too.
We need it, because "shared/nm-utils/siphash24.c"
will use it too, and that source file does not include
the other systemd macros. So, we will need to re-define
it.
NMUtilsNamedValue's purpose is precisely to create
a list and sort by entires.
Add nm_utils_named_values_from_str_dict() as helper
function to do that.
It is common to have some data indexed by a name.
If you want to sort a list of such data, you would
have to re-implement your own compare function each time.
Instead, add NMUtilsNamedEntry which as first field has
the name. So, you can create your own struct:
struct my_data {
const char *name;
... other fields
}
and compare them with with nm_utils_named_entry_cmp().
For convenience, add another struct NMUtilsNamedValue, which
has only one data field, a pointer.
This allows the compiler to inline the siphash24*() functions
for nm_hash_ptr() and nm_hash_str() (even without LTO).
This of course only applies to nm_hash_ptr() and nm_hash_str(),
which are implemented in "nm-hash-utils.c" itself. All other
nm_hash_*() functions are inline functions in "nm-hash-utils.h",
and thus these functions can be inlined instead. That is, in
other cases, the nm_hash_*() function instead can be inlined.
For nm_hash_ptr() and nm_hash_str() instead we want to inline the
siphash24*() functions.
So, no longer compile "siphash24.c" directly. Instead, only
build "nm-hash-utils.c" which internally #include "siphash24.c".
siphash24() mixes the bits much better then our naive xor.
Don't bypass siphash24(). We supposedly use it for the
better hashing properties, so use it also for pointers.
When using siphash24(), the hash value depends on the hashed input
and the key from _get_hash_key(). If the input is static, so is also
the result of siphash24(), albeit the bits are scrabbled more.
Add a nm_hash_static() to get such a static key, but without actually
doing siphash24(). The static key is also xored with a static_seed.
For that, also mangle the first byte of the hash key using siphash24()
itself. That is, because nm_hash_static() only uses the first guint of the
random key. Hence, we want that this first guint has all the entropy
of the entire key. We use siphash24() itself, to mangle all bits
of the 16 byte key into the first guint.
The nm_close() wrapper should behave exactly the same as calling
close() directly. This is well known, documented behavior.
The only addition on top of that, should be the nm_assert() to catch
double-closing.
Prevously, when passing a negative file descriptor, we wouldn't properly
set errno. Also, the call would not show up in strace, which it should
(at least, if libc's close actually makes the syscall).
I would argue, that passing a negative file descriptor is a bug already
and we should never do that. Maybe we should even assert non-negative
fds. I don't do that now, because I am not sufficiently confident.
Anyway, the change should have not practical effect, because we
shouldn't actually pass negative fds already.
There is still a fallback detection in "shared/nm-utils/nm-macros-internal.h",
so that VPN-plugins and applet don't need to bother about adding these
configure checks.
The _NM_GET_PRIVATE() macro already preserved and propagated
the constness of @self to the resulting private pointer.
_NM_GET_PRIVATE_PTR() didn't do that. Extend the macro,
to make that possible.