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.
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.
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.
We need to pass more alias-types. Instead of having numbered
versions, use variadic number of macro arguments.
Also, fix build failure with old compiler:
In file included from src/nm-ip6-config.c:24:
./src/nm-ip6-config.h:44:29: error: controlling expression type 'typeof (ipconf_iter->current->obj)' (aka 'const void *const') not compatible with any generic association type
*out_address = has_next ? NMP_OBJECT_CAST_IP6_ADDRESS (ipconf_iter->current->obj) : NULL;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Fixes: b1810d7a68
_NM_GET_PRIVATE() used typeof() to propagate constness of the @self
pointer. However, that means, it could only be used with a self pointer
of the exact type. That means, you explicitly had to cast from (GObject *)
or from (void *).
The requirement is cumbersome, and often led us to either create @self
pointer we didn't need:
NMDeviceVlan *self = NM_DEVICE_VLAN (device);
NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self);
or casting:
NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE ((NMDevice *) device);
In both cases we forcefully cast the source variable, loosing help from
the compiler to detect a bug.
For "nm-linux-platform.c", instead we commonly have a pointer of type
NMPlatform. Hence, we always forcefully cast the type via _NM_GET_PRIVATE_VOID().
Rework the macro to use _Generic(). If compiler supports _Generic(), then we
will get all compile time checks as desired. If the compiler doesn't support
_Generic(), it will still work. You don't get the compile-time checking of course,
but you'd notice that something is wrong once you build with a suitable
compiler.
nm_close() is like close(), but throws an assertion if the input fd is
>=0 and invalid. Passing an invalid (i.e. already closed) fd to
close() is a programming error with potentially catastrophic effects,
as another thread may reuse the closed fd.
Introduce a NM_HASH_INIT() function. It makes the places
where we initialize a hash with a certain seed visually clear.
Also, move them from "shared/nm-utils/nm-shared-utils.h" to
"shared/nm-utils/nm-macros-internal.h". We might want to
have NM_HASH_INIT() non-inline (hence, define it in the
source file).
- nm_clear_g_object() is like g_clear_object() but:
- it returns a boolean value, indicating that something was cleared.
- it includes an nm_assert() to check that the pointer is still
valid.
- it uses typeof() instead of blindly casting the argument.
- nm_g_object_ref_set() combines nm_clear_g_object() and resetting
the pointer to a new object, including taking a reference.
- also returns a boolean, indicating whether something changed.
- it gets the order of operations right: first it increses the
ref-count, before unrefing the old object.
- like nm_clear_g_object() and nm_clear_g_free() it first sets
the destination to NULL, instead of leaving a dangling pointer
for the duraction of the unref/free call.
- fix nm_clear_g_free() not to use a possibly dangling pointer.
Striclty speaking, that is undefined behavior.
And relax the type for nm_auto_unref_gtypeclass macro. Like
g_type_class_unref() itself, you usually don't use it with a GTypeClass
base class, but some subtype like GObjectClass.
Compiler wouldn't recognize that the @route/@address argument is always
initialized. The right workaround seems to let the next() functions always
set the value.
In file included from src/nm-ip6-config.c:24:0:
src/nm-ip6-config.c: In function ‘nm_ip6_config_create_setting’:
src/nm-ip6-config.c:734:62: error: the address of ‘address’ will always evaluate as ‘true’ [-Werror=address]
nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, self, &address) {
^
src/nm-ip6-config.h:60:17: note: in definition of macro ‘nm_ip_config_iter_ip6_address_for_each’
for (({ if (address) { *(((const NMPlatformIP6Address **) address)) = NULL; } }), nm_ip_config_iter_ip6_address_init ((iter), (self)); \
^
Fixes: 6e9aa9402a
Returning TRUE for zero makes no sense. Obviously, zero is not a power
of two.
Also, the function is used to check whether a number has only one bit
(flag) set, so, an alternative name would be "has-one-bit-set", which
also should return FALSE for zero. All callers didn't really care for
the previous meaning "has-at-most-one-bit-set".
This also avoids the issue of checking (x >= 0), which causes
-Wtype-limits warnings for unsigned types. Which was avoided
by doing (x == 0 || x > 0), which caused -Wlogical-op warning,
which then was avoided (x == 0 || (x > 0 && 1)). Just don't.
We recently added -Wlogical-op in our build process
(commit #41e7fca59762dc928c9d67b555b1409c3477b2b0).
Seems that old versions of gcc (4.8.x) will hit that warning with our
implementation of our "nm_utils_is_power_of_two" and
"test_nm_utils_is_power_of_two_do" macros.
Fool it just adding an always TRUE check.
I used to use g_strv_length ((char **) p) instead, but that feels
ugly because it g_strv_length() is not designed to operate on
arbitrary pointer arrays.
_NM_GET_PRIVATE() macro is used to implement a standard private-getter, but it
requires that "self" is a pointer of either "const type *" or "type *". That
is great in most cases, but sometimes we have predominatly self pointers of
different type, so it would require a lot of casts.
Add a different form _NM_GET_PRIVATE_VOID() where self pointer can be any
non-const pointer and returns a non-const private pointer after casting.
NM_CACHED_QUARK_FCN() is a replacement for G_DEFINE_QUARK().
G_DEFINE_QUARK() is mostly used to define GError quarks. As
such, it always appends _quark() to the function name, which
is unfavorable because it makes it harder to grep for the
definition of the function.
In general I think that macros that defined symbols by concatenating
something should be avoided because that makes it harder to locate
where the symbol was defined.
Similar to systemd's PROTECT_ERRNO. The difference it, that it doesn't
treat the auto-variable as internal, so it is allowed to use it. E.g.
if (!(fd = open (...)) {
NM_AUTO_PROTECT_ERRNO (errno_saved);
printf ("error: %s", g_strerror (errno_saved));
return FALSE;
}
We already have gs_fd_close, which however doesn't preserve
errno and only checks for fd != -1. Add our own define.
Downside is, we have to include stdio.h and errno.h,
which effectively ends up to be included *everywhere*.