Clang 3.4.2-9.el7 on CentOS7.6 complains about missing generic type match:
../dispatcher/nm-dispatcher.c:243:2: error: controlling expression type 'const Request *const' (aka 'const struct Request *const') not compatible with any generic association type
_LOG_R_D (request, "start running ordered scripts...");
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Fixes: 17dc6a9da6 ('shared: add _NM_ENSURE_TYPE_CONST()')
The sole purpose of this is more type-safe macros.
An alternative solution would be to define a function instead of a
macro. But if the function is unused (currently!) you get a compiler
warning (on some compilers even when marking the function as "static
inline", if it's in the source file). A workaround for that would be
to mark the function as _nm_unused, or to use a macro instead.
_NM_ENSURE_TYPE_CONST() is to aid the macro solution.
NMTeamLinkWatcher is immutable, meaning there is no way to change an
existing instance (aside increasing/decreasing the ref-count).
Hence, all API is implicitly const.
Still, mark the arguments as const.
"nm-value-type.h" is a header-only file, as it contains only small
accessors that should be inlined.
As such, the implementation of these functions is guarded by "#ifdef
NM_VALUE_TYPE_DEFINE_FUNCTIONS", so that one can use this header (and
NMValueType enum) with less overhead (at compile time).
Glib has GValue which used for boxing value.
Add NMValueType enum, which has a similar purpose, but it's much more
limited.
- contrary to GValue, the type must be tracked separately from the
user-data. That is, the "user-data" is only a pointer of appropriate
type, and the knowledge of the actual NMValueType is kept separately.
This will be used to have a static list of meta-data that knows the
value types, but keeping the values independent of this type
information. With GValue this would not be possible.
- the use case is much more limited. Just support basic integers,
boolean and strings. Nothing fancy.
Note that we already do something similar at muliple places. See for
example NMVariantAttributeSpec and nm_utils_team_link_watcher_to_string().
These could/should instead use NMValueType.
The type of the "data" pointer may not be compatible with the type of
the "to_free" / output pointer. This is due to constness, and that we
are unable in C to remove constness from a type.
For example,
{
const char *const *data = ...;
gs_free const char **cpy_to_free = NULL;
const char **cpy;
cpy = nm_memdup_maybe_a (300, data, NM_PTRARRAY_LEN (data) + 1, &cpy_to_free);
}
is prefectly valid , but would not have compiled.
It shows that "data" is not of type "*(&cpy_to_free)", but rather
it might be a non-const pointer of the same type.
Fixes: d0e1d0e626 ('shared: propagate types in nm_malloc_maybe_a(), nm_malloc0_maybe_a(), nm_memdup_maybe_a()')
Since we can easily lookup the vtable for a NMSetting8021xSchemeType,
it is convenient to also easily get the scheme_type for a given
NMSetting8021xSchemeVtable.
On my x86_64, this change is basically for free as it does not increase
the size of NMSetting8021xSchemeVtable, because the scheme_type fits in a
previously unused part of the NMSetting8021xSchemeVtable struct.
We want the the hash-seed array is alined so it can be used both as
guint, guint32, and guint64 directly. Don't use _nm_alignas() but
instead just add the fields to the union so we get proper alignment.
While at at, also let the seed argument to c_siphash_init() be aligned
to 64 integers. c_siphash_init() does not require that, but it tries to
read the seed as (unaligned) LE 64 bit integers. So, it doesn't hurt.
We want to log pointer values to indicate the related parties of a
log message. But we should not, because plain pointer values can be
used to defeat ASLR.
Instead, we have nm_hash_obfuscate_ptr() to managle a pointer and give
a distinct (albeit not 100% unique) 64 bit integer for logging.
But for the logging messages to be meaning-full, all related parties
must use the same static-seed.
Add a macro NM_HASH_OBFUSCATE_PTR() that uses a particular seed.
... and nm_dbus_connection_call_get_name_owner().
We are going to use GDBusConnection more instead of GDBusProxy. Hence,
these two functions are the standard repertoire and used over and over.
Their arguments are complicated enough to warrant a small helper.
It will be used for "/var/lib/NetworkManager/seen-bssids" and
"/var/lib/NetworkManager/timestamps" which currently is implemented
in NMSettingConnection.
The vlanid and missed-max values have non-zero default values.
That is what nm_utils_team_link_watcher_from_string() honors.
Note that nm_utils_team_link_watcher_to_string() must omit printing
the value only if it's the default value too.
Otherwise, these values are not preserved during a to string conversion
and back.
Maybe a better fix would be to always print the values, regardless of
the default value. But arguably, that is quite ugly because in most
cases we don't want to cluter the string output with values that are
left at the default.
These tests cannot (easily) be under "shared/nm-libnm-core-aux/tests"
because libnm/libnm-core requires code under shared while
"nm-libnm-core-aux" requires libnm/libnm-core. With autotools that is
not problem, but with meson we include sub directories in a particular
order and there is no way to foward declare stuff (AFAIK). To avoid
the circular dependency, add the tests to "clients/common/tests", which
is always built last.
to/from string functions are useful. We should be able to reuse them.
Move them to their own location.
Also, it moves independent code out of "clients/common/nm-meta-setting-desc.c"
which is already one of the largest source files we have.
Also, it makes the code unit-testable, which is obviously required
as the code has bugs.
"libnm-core" implements common functionality for "NetworkManager" and
"libnm".
Note that clients like "nmcli" cannot access the internal API provided
by "libnm-core". So, if nmcli wants to do something that is also done by
"libnm-core", , "libnm", or "NetworkManager", the code would have to be
duplicated.
Instead, such code can be in "libnm-libnm-core-{intern|aux}.la".
Note that:
0) "libnm-libnm-core-intern.la" is used by libnm-core itsself.
On the other hand, "libnm-libnm-core-aux.la" is not used by
libnm-core, but provides utilities on top of it.
1) they both extend "libnm-core" with utlities that are not public
API of libnm itself. Maybe part of the code should one day become
public API of libnm. On the other hand, this is code for which
we may not want to commit to a stable interface or which we
don't want to provide as part of the API.
2) "libnm-libnm-core-intern.la" is statically linked by "libnm-core"
and thus directly available to "libnm" and "NetworkManager".
On the other hand, "libnm-libnm-core-aux.la" may be used by "libnm"
and "NetworkManager".
Both libraries may be statically linked by libnm clients (like
nmcli).
3) it must only use glib, libnm-glib-aux.la, and the public API
of libnm-core.
This is important: it must not use "libnm-core/nm-core-internal.h"
nor "libnm-core/nm-utils-private.h" so the static library is usable
by nmcli which couldn't access these.
Note that "shared/nm-meta-setting.c" is an entirely different case,
because it behaves differently depending on whether linking against
"libnm-core" or the client programs. As such, this file must be compiled
twice.