"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.
From the files under "shared/nm-utils" we build an internal library
that provides glib-based helper utilities.
Move the files of that basic library to a new subdirectory
"shared/nm-glib-aux" and rename the helper library "libnm-core-base.la"
to "libnm-glib-aux.la".
Reasons:
- the name "utils" is overused in our code-base. Everything's an
"utils". Give this thing a more distinct name.
- there were additional files under "shared/nm-utils", which are not
part of this internal library "libnm-utils-base.la". All the files
that are part of this library should be together in the same
directory, but files that are not, should not be there.
- the new name should better convey what this library is and what is isn't:
it's a set of utilities and helper functions that extend glib with
funcitonality that we commonly need.
There are still some files left under "shared/nm-utils". They have less
a unifying propose to be in their own directory, so I leave them there
for now. But at least they are separate from "shared/nm-glib-aux",
which has a very clear purpose.
We built (among others) two libraries from the sources in "shared/nm-utils":
"libnm-utils-base.la" and "libnm-utils-udev.la".
It's confusing. Instead use directories so there is a direct
correspondence between these internal libraries and the source files.
"shared/nm-utils" contains general purpose utility functions that only
depend on glib (and extend glib with some helper functions).
We will also add code that does not use glib, hence it would be good
if the part of "shared/nm-utils" that does not depend on glib, could be
used by these future projects.
Also, we use the term "utils" everywhere. While that covers the purpose
and content well, having everything called "nm-something-utils" is not
great. Instead, call this "nm-std-aux", inspired by "c-util/c-stdaux".
This can be replaced by nm_utils_escaped_tokens_split().
Note that nm_utils_escaped_tokens_split() does not behave exactly
the same. For example, nm_utils_str_simpletokens_extract_next() would
remove all backslashes and leave only the following character.
nm_utils_escaped_tokens_split() instead only strips backslashes
that preceed a delimiter, whitespace or another backslash.
But we should have one preferred way of tokenizing, and I find this
preferable, because it allows for most backslashes to appear verbatim.