Commit Graph

21088 Commits

Author SHA1 Message Date
Thomas Haller
cf472f00a1 libnm/keyfile: merge branch 'th/keyfile-cert-parser' (#71)
https://github.com/NetworkManager/NetworkManager/pull/71
2018-03-03 17:00:12 +01:00
Thomas Haller
2aebb343d9 libnm/keyfile: refactor cert_parser() by merge helper functions
The parsing of the certificate consists of a series of checks, and if a
check matches, we determine the type and are done.

Moving these checks to different functions (that are only called once)
makes it more complicated to understand what really happens. Merge them
all together.
2018-03-03 16:57:42 +01:00
Thomas Haller
cf774a1bfc libnm/keyfile: refactor error paths for cert_parser()
Refactor cert_parser() to return early.

Also, rework handle_as_scheme() and handle_as_path() to check for
success first and return early. This in the next step will allow
to merge the functions.
2018-03-03 16:57:42 +01:00
Thomas Haller
3d6a2b8d6b libnm/keyfile/trivial: rename local variables in preparation of refactoring 2018-03-03 16:57:42 +01:00
Thomas Haller
608dfacb0b core: fix leaking connection in impl_settings_add_connection_helper()
Fixes: 0f6baeef35
2018-02-28 12:13:39 +01:00
Thomas Haller
19a78f8954 core: fix typo for parameter as "paramter" 2018-02-28 12:13:39 +01:00
Francesco Giudici
ff1884a219 ifcfg: don't skip ipv4 properties when method is shared
Always read and load ipv4 property values when method is shared also if
they will not be used: instead of dropping them at connection update,
keep their values in the ifcfg file.
Exceptions: ipv4.dns and ipv4.dns-search. They will be not read, otherwise
they may trigger a failure in nm-setting-ip4-config.c:verify() on load.

https://bugzilla.redhat.com/show_bug.cgi?id=1519299
2018-02-28 11:11:10 +01:00
Thomas Haller
6292851248 dhcp: fix uninitialized pointer in DHCP listener's _method_call_handle()
Fixes: f67269b49d
2018-02-28 06:41:40 +01:00
Thomas Haller
65049f6736 libnm/tests: fix compilation of test-general
../libnm/tests/test-general.c: In function ‘test_fixup_vendor_string’:
    ../libnm/tests/test-general.c:70:3: error: initializer element is not constant
       T_DATA ("3Com", "3Com"),
       ^
    ../libnm/tests/test-general.c:70:3: error: (near initialization for ‘data[0]’)
    ../libnm/tests/test-general.c: In function ‘test_fixup_product_string’:
    ../libnm/tests/test-general.c:365:3: error: initializer element is not constant
       T_DATA  ("10/100BaseTX [RTL81xx]", "RTL81xx"),
    ...

Fixes: 817fce917b
2018-02-26 14:42:09 +01:00
Thomas Haller
817fce917b libnm/tests: avoid compiler message about -fvar-tracking-assignments in test-general.c
CC       libnm/tests/libnm_tests_test_general-test-general.o
    libnm/tests/test-general.c: In function ‘test_fixup_product_string’:
    libnm/tests/test-general.c:328:1: note: variable tracking size limit exceeded with -fvar-tracking-assignments, retrying without
     test_fixup_product_string (void)
     ^~~~~~~~~~~~~~~~~~~~~~~~~

Fixes: 8e32d8fc23
2018-02-26 13:14:40 +01:00
Thomas Haller
fd166783e7 platform/wifi: don't pass ownership of message to nl80211_send_and_recv()
Passing ownership with a function call is confusing. Don't do that.

Since we have the cleanup attribute, it doesn't significantly
complicate the callers, as all they need to do is marking the
@msg variable to free the message when going out of scope.
That results in the function that allocates the message also being
responsible to free it.
2018-02-24 12:35:28 +01:00
Thomas Haller
a79e6b3b45 platform/wifi: fix memleak in _nl80211_send_and_recv()
The callers expect _nl80211_send_and_recv() to free @msg.

This was broken by the previous commit, which wrongly removed
the nm_auto_nlmsg cleanup attribute.

Fix the compiler warning differently.

Fixes: d7108d9362
2018-02-24 12:34:11 +01:00
Lubomir Rintel
d7108d9362 platform/wifi: drop an unused variable
src/platform/wifi/wifi-utils-nl80211.c:192:31: error: unused variable 'msg_free' [-Werror,-Wunused-variable]
          nm_auto_nlmsg struct nl_msg *msg_free = msg;

Fixes: a7bda2ed12
2018-02-23 22:04:11 +01:00
Lubomir Rintel
8b003e6d06 merge: branch 'lr/ugly-descriptions'
https://bugzilla.gnome.org/show_bug.cgi?id=791292
2018-02-23 19:47:44 +01:00
Lubomir Rintel
e4430e0969 libnm/device: use the type name for description if the product is empty
It's very likely that the product said something that was filtered out
by the fixup, such as "PCI Ethernet" or "Wi-Fi Adapter". Use a generic
type name in place of it.
2018-02-23 19:47:19 +01:00
Lubomir Rintel
c17155b1b9 libnm/device: (trivial) move some function upwards 2018-02-23 19:47:19 +01:00
Lubomir Rintel
22b76f4c58 libnm/device: prefer FROM_DATABASE udev properties
The database has a chance to fix up over garbage strings from the device
properties and we're now known to be reasonably good at fixing up crap
there.
2018-02-23 19:47:19 +01:00
Lubomir Rintel
4c963d719c libnm/utils: drop part after a dash in product name
It's always garbage.

At this point we seem to reasonably handle all product names that come
from hwdb.
2018-02-23 19:47:19 +01:00
Lubomir Rintel
0c151ae39d libnm/utils: extend the product fixup phrase list
The product names are generally of rather poor quality. The product name
is no place to enumerate product capabilities, the bus it's attached on
and similar nonsense.
2018-02-23 19:47:19 +01:00
Lubomir Rintel
e22b1c1d94 libnm/utils: ignore parts of vendor name after a slash
At this point the test suite also contains all network vendor names
known to hwdb.
2018-02-23 19:47:19 +01:00
Lubomir Rintel
f7805ab602 libnm/utils: deal with the square brackets on producr/vendor fixup
If there's a [<string>] that survived the substitution, then the string
is supposed to be a short form that is generally preferrable.

That's great in theory, but actually it's rather often pure garbage for
product names. Let's prefer it just for vendors and provide an option to
drop it (will be useful for fixing up product names).
2018-02-23 19:47:19 +01:00
Lubomir Rintel
280d095fdf libnm/utils: ignore stuff in parentheses for vendor/product fixups
It's always useless.
2018-02-23 19:47:19 +01:00
Lubomir Rintel
e974261e89 libnm/utils: add more phrases to vendor fixup list
Along with known correctly fixed up vendor names.
2018-02-23 19:47:19 +01:00
Lubomir Rintel
8e32d8fc23 libnm/utils: split out vendor fixup
The hwdb generally contains the strings of rather poor quality,
especially when it comes to sensibly presenting them to the user and
they need various cleanups.

While the following patches add fixups, this one splits out vendor
fixups, because it turns out that a different set of fixups is needed
than for products.
2018-02-23 19:47:19 +01:00
Beniamino Galvani
823839e933 systemd: merge branch systemd into master 2018-02-23 14:13:43 +01:00
Beniamino Galvani
f5b8b37eaf libsystemd-network: fix endianness in ARP BPF filter
systemd commit f11cba7479fe ("libsystemd-network: fix unaligned loads
(issue #7654)") changed the way in which the MAC address is read to
use native endiannes:

 htobe32(*((uint32_t *)x)  ->  unaligned_read_ne32(x)

This is wrong because loads done with BPF_LD + BPF_ABS are big-endian, as it
can be seen for the ethertype and arp-operation loads above in the
filter.  Also, the same commit changed:

 htobe32(*((unsigned int *)x) -> unaligned_read_be32(x)

in _bind_raw_socket(), which is the correct form.

The commit broke IPv4LL in presence of loops, as the sender now considers its
own packets as conflicting.

systemd commit: 6afe9046d570fd86dbc04526b5685c64d7958086
2018-02-23 14:11:27 +01:00
Beniamino Galvani
adced1a22b systemd: update code from upstream (2018-02-23)
This is a direct dump from systemd git on 2018-02-23, git commit
6084c4efa8dcc99659f62c7abc70f69a70220eb2

======

SYSTEMD_DIR=../systemd
COMMIT=6084c4efa8dcc99659f62c7abc70f69a70220eb2

(
  cd "$SYSTEMD_DIR"
  git checkout "$COMMIT"
  git reset --hard
  git clean -fdx
)

git ls-files :/src/systemd/src/ \
             :/shared/nm-utils/siphash24.c \
             :/shared/nm-utils/siphash24.h \
             :/shared/nm-utils/unaligned.h | \
  xargs -d '\n' rm -f

nm_copy_sd() {
    mkdir -p "./src/systemd/$(dirname "$1")"
    cp "$SYSTEMD_DIR/$1" "./src/systemd/$1"
}

nm_copy_sd_shared() {
    mkdir -p "./shared/nm-utils/"
    cp "$SYSTEMD_DIR/$1" "./shared/nm-utils/${1##*/}"
}

nm_copy_sd "src/basic/alloc-util.c"
nm_copy_sd "src/basic/alloc-util.h"
nm_copy_sd "src/basic/async.h"
nm_copy_sd "src/basic/escape.c"
nm_copy_sd "src/basic/escape.h"
nm_copy_sd "src/basic/ether-addr-util.c"
nm_copy_sd "src/basic/ether-addr-util.h"
nm_copy_sd "src/basic/extract-word.c"
nm_copy_sd "src/basic/extract-word.h"
nm_copy_sd "src/basic/fileio.c"
nm_copy_sd "src/basic/fileio.h"
nm_copy_sd "src/basic/fd-util.c"
nm_copy_sd "src/basic/fd-util.h"
nm_copy_sd "src/basic/fs-util.c"
nm_copy_sd "src/basic/fs-util.h"
nm_copy_sd "src/basic/hash-funcs.c"
nm_copy_sd "src/basic/hash-funcs.h"
nm_copy_sd "src/basic/hashmap.c"
nm_copy_sd "src/basic/hashmap.h"
nm_copy_sd "src/basic/hexdecoct.c"
nm_copy_sd "src/basic/hexdecoct.h"
nm_copy_sd "src/basic/hostname-util.c"
nm_copy_sd "src/basic/hostname-util.h"
nm_copy_sd "src/basic/in-addr-util.c"
nm_copy_sd "src/basic/in-addr-util.h"
nm_copy_sd "src/basic/io-util.c"
nm_copy_sd "src/basic/io-util.h"
nm_copy_sd "src/basic/list.h"
nm_copy_sd "src/basic/log.h"
nm_copy_sd "src/basic/macro.h"
nm_copy_sd "src/basic/mempool.h"
nm_copy_sd "src/basic/mempool.c"
nm_copy_sd "src/basic/parse-util.c"
nm_copy_sd "src/basic/parse-util.h"
nm_copy_sd "src/basic/path-util.c"
nm_copy_sd "src/basic/path-util.h"
nm_copy_sd "src/basic/prioq.h"
nm_copy_sd "src/basic/prioq.c"
nm_copy_sd "src/basic/process-util.h"
nm_copy_sd "src/basic/process-util.c"
nm_copy_sd "src/basic/random-util.c"
nm_copy_sd "src/basic/random-util.h"
nm_copy_sd "src/basic/refcnt.h"
nm_copy_sd "src/basic/set.h"
nm_copy_sd "src/basic/signal-util.h"
nm_copy_sd_shared "src/basic/siphash24.c"
nm_copy_sd_shared "src/basic/siphash24.h"
nm_copy_sd "src/basic/socket-util.c"
nm_copy_sd "src/basic/socket-util.h"
nm_copy_sd "src/basic/sparse-endian.h"
nm_copy_sd "src/basic/stdio-util.h"
nm_copy_sd "src/basic/string-table.c"
nm_copy_sd "src/basic/string-table.h"
nm_copy_sd "src/basic/string-util.c"
nm_copy_sd "src/basic/string-util.h"
nm_copy_sd "src/basic/strv.c"
nm_copy_sd "src/basic/strv.h"
nm_copy_sd "src/basic/time-util.c"
nm_copy_sd "src/basic/time-util.h"
nm_copy_sd "src/basic/umask-util.h"
nm_copy_sd_shared "src/basic/unaligned.h"
nm_copy_sd "src/basic/utf8.c"
nm_copy_sd "src/basic/utf8.h"
nm_copy_sd "src/basic/util.c"
nm_copy_sd "src/basic/util.h"
nm_copy_sd "src/libsystemd-network/arp-util.c"
nm_copy_sd "src/libsystemd-network/arp-util.h"
nm_copy_sd "src/libsystemd-network/dhcp6-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp6-lease-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp6-network.c"
nm_copy_sd "src/libsystemd-network/dhcp6-option.c"
nm_copy_sd "src/libsystemd-network/dhcp6-protocol.h"
nm_copy_sd "src/libsystemd-network/dhcp-identifier.c"
nm_copy_sd "src/libsystemd-network/dhcp-identifier.h"
nm_copy_sd "src/libsystemd-network/dhcp-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp-lease-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp-network.c"
nm_copy_sd "src/libsystemd-network/dhcp-option.c"
nm_copy_sd "src/libsystemd-network/dhcp-packet.c"
nm_copy_sd "src/libsystemd-network/dhcp-protocol.h"
nm_copy_sd "src/libsystemd-network/lldp-internal.h"
nm_copy_sd "src/libsystemd-network/lldp-neighbor.c"
nm_copy_sd "src/libsystemd-network/lldp-neighbor.h"
nm_copy_sd "src/libsystemd-network/lldp-network.c"
nm_copy_sd "src/libsystemd-network/lldp-network.h"
nm_copy_sd "src/libsystemd-network/network-internal.c"
nm_copy_sd "src/libsystemd-network/network-internal.h"
nm_copy_sd "src/libsystemd-network/sd-dhcp6-client.c"
nm_copy_sd "src/libsystemd-network/sd-dhcp6-lease.c"
nm_copy_sd "src/libsystemd-network/sd-dhcp-client.c"
nm_copy_sd "src/libsystemd-network/sd-dhcp-lease.c"
nm_copy_sd "src/libsystemd-network/sd-ipv4ll.c"
nm_copy_sd "src/libsystemd-network/sd-ipv4acd.c"
nm_copy_sd "src/libsystemd-network/sd-lldp.c"
nm_copy_sd "src/libsystemd/sd-event/sd-event.c"
nm_copy_sd "src/libsystemd/sd-id128/id128-util.c"
nm_copy_sd "src/libsystemd/sd-id128/id128-util.h"
nm_copy_sd "src/libsystemd/sd-id128/sd-id128.c"
nm_copy_sd "src/shared/dns-domain.c"
nm_copy_sd "src/shared/dns-domain.h"
nm_copy_sd "src/systemd/_sd-common.h"
nm_copy_sd "src/systemd/sd-dhcp6-client.h"
nm_copy_sd "src/systemd/sd-dhcp6-lease.h"
nm_copy_sd "src/systemd/sd-dhcp-client.h"
nm_copy_sd "src/systemd/sd-dhcp-lease.h"
nm_copy_sd "src/systemd/sd-event.h"
nm_copy_sd "src/systemd/sd-ndisc.h"
nm_copy_sd "src/systemd/sd-id128.h"
nm_copy_sd "src/systemd/sd-ipv4acd.h"
nm_copy_sd "src/systemd/sd-ipv4ll.h"
nm_copy_sd "src/systemd/sd-lldp.h"
2018-02-23 14:10:24 +01:00
Thomas Haller
0b25e30238 wwan: merge branch 'th/modem-ip-iface'
https://github.com/NetworkManager/NetworkManager/pull/55
2018-02-22 11:45:32 +01:00
Thomas Haller
de16ef91cf wwan: drop nm_modem_get_data_port() function
It was only used by bluetooth's component_added()
check. It should compare rfcomm_iface only against
the control-port, not the data-port.
2018-02-21 20:28:46 +01:00
Thomas Haller
78ca2a70c7 device: don't set invalid ip-iface
Now that every call to nm_device_set_ip_iface() and nm_device_set_ip_ifindex()
is checked, and setting an interface that does not exist causes the device
state to fail, we no longer need to allow setting an ip-iface if we are
unable to retrieve the ip-ifindex.
2018-02-21 20:28:46 +01:00
Thomas Haller
c7b3586b9d wwan: rework setting modem's data-port
Depending on the bearer's configuration method, the data-port is
either a networking interface, or an tty for ppp.

Let's treat them strictily separate.

Also, rework how NM_MODEM_DATA_PORT was used in both contexts.
Instead, use the that we actually care about.

Also, when nm_device_set_ip_ifindex() fails, fail activation
right away.

Also, we early try to resolve the network interface's name to
an ifindex. If that fails, the device is already gone and we
fail early.
2018-02-21 20:28:46 +01:00
Thomas Haller
2ea8e1029f bluetooth: fail activation when setting unknown ip-iface 2018-02-21 20:28:46 +01:00
Thomas Haller
a169d689ba wwan: avoid dangling pointer for error variable in connect_ready() 2018-02-21 20:28:46 +01:00
Thomas Haller
0ef23b139d device: don't set NMDeviceModem's ip-iface right after constuction
nm_device_modem_new() is only called with a newly created
NMModemBroadband or NMModemOfono instance.
See the callers
  - NMModemManager:handle_new_modem()
    - NMWwanFactory:modem_added_cb()
      - NMDeviceModem:nm_device_modem_new()

Hence, at that point, the modem cannot yet have a data-port
or ip-iface set, because that is only obtained later.
2018-02-21 20:28:46 +01:00
Thomas Haller
bfe38c1bf3 wwan: make NM_MODEM_DATA_PORT not a construct property
The property was never set at construct time. Don't make
it a construct property.
2018-02-21 20:28:46 +01:00
Thomas Haller
8209e42106 wwan: notify change of modem:data-port when clearing ip-iface
data-port returns ip-iface, if set. Clearing it,
most likely causes the property to change. Emit
a notification.
2018-02-21 20:28:46 +01:00
Thomas Haller
4fbea56b54 wwan: add modem:ip-ifindex property
Will be used later to replace ip-iface.
2018-02-21 20:28:46 +01:00
Thomas Haller
ab4578302d device: refactor nm_device_set_ip_ifindex() and set_ip_iface()
- don't even bother to look into the platform cache, but use
  if_indextoname() / if_nametoindex(). In most cases, we obtained
  the ifindex/ifname not from the platform cache in the first
  place. Hence, there is a race, where the interface might not
  exist.
  However, try to process events of the platform cache, hoping
  that the cache contains an interface for the given ifindex/ifname.

- let set_ip_ifindex() and set_ip_iface() both return a boolean
  value to indicate whether a ip-interface is set or not. That is,
  whether we have a positive ip_ifindex. That seems more interesting
  information, then to return whether anything changed.

- as before, set_ip_ifindex() can only clear an ifindex/ifname,
  or error out without doing anything. That is different from
  set_ip_iface(), which will also set an ifname if no ifindex
  can be resolved. That is curreently ugly, because then ip-ifindex
  and ip-iface don't agree. That shall be improved in the future
  by:
  - trying to set an interface that cannot be resolved shall
    lead to a disconnect in any case.
  - we shall make less use of the ip-iface and rely more on the
    ifindex.
2018-02-21 20:28:46 +01:00
Thomas Haller
79980536b9 platform: add nm_platform_process_events_ensure_link() function 2018-02-21 20:28:46 +01:00
Thomas Haller
352d063009 wwan/trivial: rename internal variable ppp_iface to ip_iface
This is really the name of the networking device. Whether it
is created by ppp is not that important here. Rename.
2018-02-21 20:28:46 +01:00
Thomas Haller
41e80a02b2 wwan: handle missing data_port in ppp_stage3_ip_config_start() of NMModem
It's not at all clear, that the data_port is set at this point.
Guard against it, and avoid the assertion later.
2018-02-21 20:28:46 +01:00
Thomas Haller
bc3aebbab8 wwan: disconnect signals from ppp-manager before clearing instance 2018-02-21 20:28:46 +01:00
Thomas Haller
19f24574dc wwan: cleanup handling ppp_iface in NMModem 2018-02-21 20:28:46 +01:00
Thomas Haller
66585dc1af wwan: free ppp_iface in NMModem's finalize() 2018-02-21 20:28:46 +01:00
Beniamino Galvani
878a3a4125 ovs: don't consume error in method callback
The error should be freed by callback functions, but only
_monitor_bridges_cb() actually does it. Simplify this by letting the
caller own the error.

Fixes: 830a5a14cb
2018-02-21 14:04:21 +01:00
Thomas Haller
3d987fe2db platform/netlink: merge branch 'th/netlink' (#67)
https://github.com/NetworkManager/NetworkManager/pull/67
2018-02-21 12:12:36 +01:00
Thomas Haller
ad21d54219 iface-helper: fix non-reentrant call to platform for failed IPv6 DAD
Platform invokes change events while reading netlink events. However,
platform code is not re-entrant and calling into platform again is not
allowed (aside operations that do not process the netlink socket, like
lookup of the platform cache).

That basically means, we have to always process events in an idle
handler. That is not a too strong limitation, because we anyway don't
know the call context in which the platform event is emitted and we
should avoid unguarded recursive calls into platform.

Otherwise, we get hit an assertion/crash in nm-iface-helper:

     1  raise()
     2  abort()
     3  g_assertion_message()
     4  g_assertion_message_expr()
     5  do_delete_object()
     6  ip6_address_delete()
 >>> 7  nm_platform_ip6_address_delete()
     8  nm_platform_ip6_address_sync()
     9  nm_ip6_config_commit()
     10 ndisc_config_changed()
     11 ffi_call_unix64()
     12 ffi_call()
     13 g_cclosure_marshal_generic_va()
     14 _g_closure_invoke_va()
     15 g_signal_emit_valist()
     16 g_signal_emit()
 >>> 17 nm_ndisc_dad_failed()
     18 ffi_call_unix64()
     19 ffi_call()
     20 g_cclosure_marshal_generic()
     21 g_closure_invoke()
     22 signal_emit_unlocked_R()
     23 g_signal_emit_valist()
     24 g_signal_emit()
 >>> 25 nm_platform_cache_update_emit_signal()
     26 event_handler_recvmsgs()
     27 event_handler_read_netlink()
     28 delayed_action_handle_one()
     29 delayed_action_handle_all()
     30 do_delete_object()
     31 ip6_address_delete()
     32 nm_platform_ip6_address_delete()
     33 nm_platform_ip6_address_sync()
 >>> 34 nm_ip6_config_commit()
     35 ndisc_config_changed()
     36 ffi_call_unix64()
     37 ffi_call()
     38 g_cclosure_marshal_generic_va()
     39 _g_closure_invoke_va()
     40 g_signal_emit_valist()
     41 g_signal_emit()
     42 check_timestamps()
     43 receive_ra()
     44 ndp_call_eventfd_handler()
     45 ndp_callall_eventfd_handler()
     46 event_ready()
     47 g_main_context_dispatch()
     48 g_main_context_iterate.isra.22()
     49 g_main_loop_run()
 >>> 50 main()

NMPlatform already has a check to assert against recursive calls
in delayed_action_handle_all():

    g_return_val_if_fail (priv->delayed_action.is_handling == 0, FALSE);

    priv->delayed_action.is_handling++;
    ...
    priv->delayed_action.is_handling--;

Fixes: f85728ecff

https://bugzilla.redhat.com/show_bug.cgi?id=1546656
2018-02-21 12:08:46 +01:00
Thomas Haller
d074ffc836 platform: refactor completing netlink responses in event_handler_read_netlink()
- refactor the loop in event_handler_read_netlink() to mark pending
  requests as answered by adding a new helper function
  delayed_action_wait_for_nl_response_complete_check()

- delayed_action_wait_for_nl_response_complete_all() can be implemented
  in terms of delayed_action_wait_for_nl_response_complete_check()

- if nm_platform_netns_push() fails, also complete all pending requests
  with a new error code WAIT_FOR_NL_RESPONSE_RESULT_FAILED_SETNS.
2018-02-21 12:08:46 +01:00
Thomas Haller
b3633a282d platform: cleanup error handling in event_handler_recvmsgs()
Now that we cleaned up nl_recv(), we have full control over which error
variables are returned when. We no longer need to check "errno"
directly, and we no longer need the NLE_USER_* workaround.
2018-02-21 12:08:46 +01:00
Thomas Haller
ba25221236 netlink: various cleanups and use cleanup attribute
- adjust some coding style (space after function name).
- ensure to use g_free(), as we no longer use malloc
  but the g_malloc aliases. Nowadays, glib's malloc
  is identical to malloc from the standard library and
  so this is no issue in practice. Still it's bad
  style to mix g_malloc() with free().
- use cleanup attribute for memory handling.
2018-02-21 12:08:46 +01:00