summaryrefslogtreecommitdiffstats
path: root/src/shared/bus-util.c (follow)
Commit message (Collapse)AuthorAgeFilesLines
* tree-wide: get rid of strappend()Lennart Poettering2019-07-121-1/+1
| | | | | It's a special case of strjoin(), so no need to keep both. In particular as typing strjoin() is even shoert than strappend().
* tree-wide: replace strjoin() with path_join()Yu Watanabe2019-06-201-1/+2
|
* logind: add SetBrightness() bus call for setting brightness of ↵Lennart Poettering2019-05-241-0/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | leds/backlight devices associated with a seat This augments the drm/input device management by adding a single method call for setting the brightness of an "leds" or "backlight" kernel class device. This method call requires no privileges to call, but a caller can only change the brightness on sessions that are currently active, and they must own the session. This does not do enumeration of such class devices, feature or range probing, chnage notification; it doesn't help associating graphics or input devices with their backlight or leds devices. For all that clients should go directly to udev/sysfs. The SetBrightness() call is just for executing the actual change operation, that is otherwise privileged. Example line: busctl call org.freedesktop.login1 /org/freedesktop/login1/session/self org.freedesktop.login1.Session SetBrightness ssu "backlight" "intel_backlight" 200 The parameter the SetBrightness() call takes are the kernel subsystem (i.e. "leds" or "backlight"), the device name, and the brightness value. On some hw setting the brightness is slow, and implementation and write access to the sysfs knobs exposes this slowness. Due to this we'll fork off a writer process in the background so that logind doesn't have to block. Moreover, write requestes are coalesced: when a write request is enqueued while one is already being executed it is queued. When another write reques is then enqueued the earlier one is replaced by the newer one, so that only one queued write request per device remains at any time. Method replies are sent as soon as the first write request that happens after the request was received is completed. It is recommended that bus clients turn off the "expect_reply" flag on the dbus messages they send though, that relieves logind from sending completion notification and is particularly a good idea if clients implement reactive UI sliders that send a quick secession of write requests. Replaces: #12413
* cgroup: Readd some plumbing for DefaultMemoryMinChris Down2019-05-081-1/+1
| | | | | Somehow these got lost in the previous PR, rendering DefaultMemoryMin not very useful.
* cgroup: Implement default propagation of MemoryLow with DefaultMemoryLowChris Down2019-04-121-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In cgroup v2 we have protection tunables -- currently MemoryLow and MemoryMin (there will be more in future for other resources, too). The design of these protection tunables requires not only intermediate cgroups to propagate protections, but also the units at the leaf of that resource's operation to accept it (by setting MemoryLow or MemoryMin). This makes sense from an low-level API design perspective, but it's a good idea to also have a higher-level abstraction that can, by default, propagate these resources to children recursively. In this patch, this happens by having descendants set memory.low to N if their ancestor has DefaultMemoryLow=N -- assuming they don't set a separate MemoryLow value. Any affected unit can opt out of this propagation by manually setting `MemoryLow` to some value in its unit configuration. A unit can also stop further propagation by setting `DefaultMemoryLow=` with no argument. This removes further propagation in the subtree, but has no effect on the unit itself (for that, use `MemoryLow=0`). Our use case in production is simplifying the configuration of machines which heavily rely on memory protection tunables, but currently require tweaking a huge number of unit files to make that a reality. This directive makes that significantly less fragile, and decreases the risk of misconfiguration. After this patch is merged, I will implement DefaultMemoryMin= using the same principles.
* bus-util: treat org.freedesktop.DBus.Error.ServiceUnknown nicely when polkit ↵Yu Watanabe2019-04-041-2/+2
| | | | | | does not exist Fixes #12209.
* util-lib: use FLAGS_SET() where appropriateLennart Poettering2019-04-021-1/+1
|
* systemctl: format IPIngressBytes= or friends nicelyYu Watanabe2019-03-041-0/+2
|
* bus-util: drop unnecessary re-formattingYu Watanabe2019-03-041-20/+34
|
* tree-wide: whenever we allocate a new bus object, close it before dropping ↵Lennart Poettering2019-01-171-4/+4
| | | | | | | | | | | | | | | final ref This doesn't really change much, but feels more correct to do, as it ensures that all messages currently queued in the bus connections are definitely unreffed and thus destryoing of the connection object will follow immediately. Strictly speaking this change is entirely unnecessary, since nothing else could have acquired a ref to the connection and queued a message in, however, now that we have the new sd_bus_close_unref() helper it makes a lot of sense to use it here, to ensure that whatever happens nothing that might have been queued fucks with us.
* tree-wide: remove various unused functionsLennart Poettering2018-12-021-38/+0
| | | | All found with "cppcheck --enable=unusedFunction".
* Split out part of mount-util.c into mountpoint-util.cZbigniew Jędrzejewski-Szmek2018-11-291-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The idea is that anything which is related to actually manipulating mounts is in mount-util.c, but functions for mountpoint introspection are moved to the new file. Anything which requires libmount must be in mount-util.c. This was supposed to be a preparation for further changes, with no functional difference, but it results in a significant change in linkage: $ ldd build/libnss_*.so.2 (before) build/libnss_myhostname.so.2: linux-vdso.so.1 (0x00007fff77bf5000) librt.so.1 => /lib64/librt.so.1 (0x00007f4bbb7b2000) libmount.so.1 => /lib64/libmount.so.1 (0x00007f4bbb755000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f4bbb734000) libc.so.6 => /lib64/libc.so.6 (0x00007f4bbb56e000) /lib64/ld-linux-x86-64.so.2 (0x00007f4bbb8c1000) libblkid.so.1 => /lib64/libblkid.so.1 (0x00007f4bbb51b000) libuuid.so.1 => /lib64/libuuid.so.1 (0x00007f4bbb512000) libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f4bbb4e3000) libpcre2-8.so.0 => /lib64/libpcre2-8.so.0 (0x00007f4bbb45e000) libdl.so.2 => /lib64/libdl.so.2 (0x00007f4bbb458000) build/libnss_mymachines.so.2: linux-vdso.so.1 (0x00007ffc19cc0000) librt.so.1 => /lib64/librt.so.1 (0x00007fdecb74b000) libcap.so.2 => /lib64/libcap.so.2 (0x00007fdecb744000) libmount.so.1 => /lib64/libmount.so.1 (0x00007fdecb6e7000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fdecb6c6000) libc.so.6 => /lib64/libc.so.6 (0x00007fdecb500000) /lib64/ld-linux-x86-64.so.2 (0x00007fdecb8a9000) libblkid.so.1 => /lib64/libblkid.so.1 (0x00007fdecb4ad000) libuuid.so.1 => /lib64/libuuid.so.1 (0x00007fdecb4a2000) libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fdecb475000) libpcre2-8.so.0 => /lib64/libpcre2-8.so.0 (0x00007fdecb3f0000) libdl.so.2 => /lib64/libdl.so.2 (0x00007fdecb3ea000) build/libnss_resolve.so.2: linux-vdso.so.1 (0x00007ffe8ef8e000) librt.so.1 => /lib64/librt.so.1 (0x00007fcf314bd000) libcap.so.2 => /lib64/libcap.so.2 (0x00007fcf314b6000) libmount.so.1 => /lib64/libmount.so.1 (0x00007fcf31459000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fcf31438000) libc.so.6 => /lib64/libc.so.6 (0x00007fcf31272000) /lib64/ld-linux-x86-64.so.2 (0x00007fcf31615000) libblkid.so.1 => /lib64/libblkid.so.1 (0x00007fcf3121f000) libuuid.so.1 => /lib64/libuuid.so.1 (0x00007fcf31214000) libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fcf311e7000) libpcre2-8.so.0 => /lib64/libpcre2-8.so.0 (0x00007fcf31162000) libdl.so.2 => /lib64/libdl.so.2 (0x00007fcf3115c000) build/libnss_systemd.so.2: linux-vdso.so.1 (0x00007ffda6d17000) librt.so.1 => /lib64/librt.so.1 (0x00007f610b83c000) libcap.so.2 => /lib64/libcap.so.2 (0x00007f610b835000) libmount.so.1 => /lib64/libmount.so.1 (0x00007f610b7d8000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f610b7b7000) libc.so.6 => /lib64/libc.so.6 (0x00007f610b5f1000) /lib64/ld-linux-x86-64.so.2 (0x00007f610b995000) libblkid.so.1 => /lib64/libblkid.so.1 (0x00007f610b59e000) libuuid.so.1 => /lib64/libuuid.so.1 (0x00007f610b593000) libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f610b566000) libpcre2-8.so.0 => /lib64/libpcre2-8.so.0 (0x00007f610b4e1000) libdl.so.2 => /lib64/libdl.so.2 (0x00007f610b4db000) (after) build/libnss_myhostname.so.2: linux-vdso.so.1 (0x00007fff0b5e2000) librt.so.1 => /lib64/librt.so.1 (0x00007fde0c328000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fde0c307000) libc.so.6 => /lib64/libc.so.6 (0x00007fde0c141000) /lib64/ld-linux-x86-64.so.2 (0x00007fde0c435000) build/libnss_mymachines.so.2: linux-vdso.so.1 (0x00007ffdc30a7000) librt.so.1 => /lib64/librt.so.1 (0x00007f06ecabb000) libcap.so.2 => /lib64/libcap.so.2 (0x00007f06ecab4000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f06eca93000) libc.so.6 => /lib64/libc.so.6 (0x00007f06ec8cd000) /lib64/ld-linux-x86-64.so.2 (0x00007f06ecc15000) build/libnss_resolve.so.2: linux-vdso.so.1 (0x00007ffe95747000) librt.so.1 => /lib64/librt.so.1 (0x00007fa56a80f000) libcap.so.2 => /lib64/libcap.so.2 (0x00007fa56a808000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fa56a7e7000) libc.so.6 => /lib64/libc.so.6 (0x00007fa56a621000) /lib64/ld-linux-x86-64.so.2 (0x00007fa56a964000) build/libnss_systemd.so.2: linux-vdso.so.1 (0x00007ffe67b51000) librt.so.1 => /lib64/librt.so.1 (0x00007ffb32113000) libcap.so.2 => /lib64/libcap.so.2 (0x00007ffb3210c000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007ffb320eb000) libc.so.6 => /lib64/libc.so.6 (0x00007ffb31f25000) /lib64/ld-linux-x86-64.so.2 (0x00007ffb3226a000) I don't quite understand what is going on here, but let's not be too picky.
* coccinelle: make use of SYNTHETIC_ERRNOZbigniew Jędrzejewski-Szmek2018-11-221-5/+3
| | | | | | | | | | | Ideally, coccinelle would strip unnecessary braces too. But I do not see any option in coccinelle for this, so instead, I edited the patch text using search&replace to remove the braces. Unfortunately this is not fully automatic, in particular it didn't deal well with if-else-if-else blocks and ifdefs, so there is an increased likelikehood be some bugs in such spots. I also removed part of the patch that coccinelle generated for udev, where we returns -1 for failure. This should be fixed independently.
* tree-wide: replace 'unsigned int' with 'unsigned'Yu Watanabe2018-10-191-2/+2
|
* bus-util: drop now-unused functionsZbigniew Jędrzejewski-Szmek2018-09-201-162/+0
|
* bus-util: make --property= optionally take valueYu Watanabe2018-09-121-35/+72
|
* bus-util: update commentYu Watanabe2018-06-291-5/+4
| | | | | Originally, request_name_handler_may_reload_dbus() was written for timesyncd. But now it is also called by networkd or resolved.
* bus-util: drop unnecessary !!Yu Watanabe2018-06-291-1/+1
|
* bus-util: make log level lower in request_name_destroy_callback()Yu Watanabe2018-06-271-1/+1
| | | | Fixes #9442.
* bus-util: fix error handlingYu Watanabe2018-06-251-1/+1
|
* tree-wide: remove Lennart's copyright linesLennart Poettering2018-06-141-3/+0
| | | | | | | | | | | These lines are generally out-of-date, incomplete and unnecessary. With SPDX and git repository much more accurate and fine grained information about licensing and authorship is available, hence let's drop the per-file copyright notice. Of course, removing copyright lines of others is problematic, hence this commit only removes my own lines and leaves all others untouched. It might be nicer if sooner or later those could go away too, making git the only and accurate source of authorship information.
* tree-wide: drop 'This file is part of systemd' blurbLennart Poettering2018-06-141-2/+0
| | | | | | | | | | | | | | | | This part of the copyright blurb stems from the GPL use recommendations: https://www.gnu.org/licenses/gpl-howto.en.html The concept appears to originate in times where version control was per file, instead of per tree, and was a way to glue the files together. Ultimately, we nowadays don't live in that world anymore, and this information is entirely useless anyway, as people are very welcome to copy these files into any projects they like, and they shouldn't have to change bits that are part of our copyright header for that. hence, let's just get rid of this old cruft, and shorten our codebase a bit.
* timedatectl: add 'show' command to display machine-readable outputYu Watanabe2018-06-141-1/+2
| | | | Closes #9249.
* tree-wide: drop !! casts to booleansZbigniew Jędrzejewski-Szmek2018-06-131-3/+3
| | | | | | | | | | | They are not needed, because anything that is non-zero is converted to true. C11: > 6.3.1.2: When any scalar value is converted to _Bool, the result is 0 if the > value compares equal to 0; otherwise, the result is 1. https://stackoverflow.com/questions/31551888/casting-int-to-bool-in-c-c
* shared/bus-util: use the new cleanup functionality to avoid a memleakZbigniew Jędrzejewski-Szmek2018-06-061-11/+51
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If the async callbacks didn't get a chance to finish properly, we'd leak memory. The output from test-bus-util with additional log line in the callbacks to show what is happening: $ build/test-bus-util /* test_name_async (0) */ Bus test-bus: changing state UNSET → OPENING Bus test-bus: changing state OPENING → AUTHENTICATING Bus test-bus: changing state AUTHENTICATING → HELLO Sent message type=method_call sender=n/a destination=org.freedesktop.DBus path=/org/freedesktop/DBus interface=org.freedesktop.DBus member=Hello cookie=1 reply_cookie=0 signature=n/a error-name=n/a error-message=n/a Sent message type=method_call sender=n/a destination=org.freedesktop.DBus path=/org/freedesktop/DBus interface=org.freedesktop.DBus member=RequestName cookie=2 reply_cookie=0 signature=su error-name=n/a error-message=n/a Got message type=method_return sender=org.freedesktop.DBus destination=:1.732 path=n/a interface=n/a member=n/a cookie=4294967295 reply_cookie=1 signature=s error-name=n/a error-message=n/a Bus test-bus: changing state HELLO → RUNNING Bus test-bus: changing state RUNNING → CLOSED request_name_destroy_callback n_ref=1 /* test_name_async (20) */ Bus test-bus: changing state UNSET → OPENING Bus test-bus: changing state OPENING → AUTHENTICATING Bus test-bus: changing state AUTHENTICATING → HELLO stage 0: sd_bus_process returned 1 Sent message type=method_call sender=n/a destination=org.freedesktop.DBus path=/org/freedesktop/DBus interface=org.freedesktop.DBus member=Hello cookie=1 reply_cookie=0 signature=n/a error-name=n/a error-message=n/a Sent message type=method_call sender=n/a destination=org.freedesktop.DBus path=/org/freedesktop/DBus interface=org.freedesktop.DBus member=RequestName cookie=2 reply_cookie=0 signature=su error-name=n/a error-message=n/a stage 1: sd_bus_process returned 1 Got message type=method_return sender=org.freedesktop.DBus destination=:1.733 path=n/a interface=n/a member=n/a cookie=4294967295 reply_cookie=1 signature=s error-name=n/a error-message=n/a Bus test-bus: changing state HELLO → RUNNING stage 2: sd_bus_process returned 1 Got message type=signal sender=org.freedesktop.DBus.Local destination=n/a path=/org/freedesktop/DBus/Local interface=org.freedesktop.DBus.Local member=Connected cookie=4294967295 reply_cookie=0 signature=n/a error-name=n/a error-message=n/a stage 3: sd_bus_process returned 1 Got message type=signal sender=org.freedesktop.DBus destination=:1.733 path=/org/freedesktop/DBus interface=org.freedesktop.DBus member=NameAcquired cookie=4294967295 reply_cookie=0 signature=s error-name=n/a error-message=n/a stage 4: sd_bus_process returned 1 Got message type=error sender=org.freedesktop.DBus destination=:1.733 path=n/a interface=n/a member=n/a cookie=4294967295 reply_cookie=2 signature=s error-name=org.freedesktop.DBus.Error.AccessDenied error-message=Request to own name refused by policy Unable to request name, will retry after reloading DBus configuration: Request to own name refused by policy Sent message type=method_call sender=n/a destination=org.freedesktop.DBus path=/org/freedesktop/DBus interface=org.freedesktop.DBus member=ReloadConfig cookie=3 reply_cookie=0 signature=n/a error-name=n/a error-message=n/a request_name_destroy_callback n_ref=2 stage 5: sd_bus_process returned 1 Got message type=method_return sender=org.freedesktop.DBus destination=:1.733 path=n/a interface=n/a member=n/a cookie=4294967295 reply_cookie=3 signature= error-name=n/a error-message=n/a Sent message type=method_call sender=n/a destination=org.freedesktop.DBus path=/org/freedesktop/DBus interface=org.freedesktop.DBus member=RequestName cookie=4 reply_cookie=0 signature=su error-name=n/a error-message=n/a request_name_destroy_callback n_ref=1 stage 6: sd_bus_process returned 1 Got message type=error sender=org.freedesktop.DBus destination=:1.733 path=n/a interface=n/a member=n/a cookie=4294967295 reply_cookie=4 signature=s error-name=org.freedesktop.DBus.Error.AccessDenied error-message=Request to own name refused by policy Unable to request name, failing connection: Request to own name refused by policy Bus test-bus: changing state RUNNING → CLOSING stage 7: sd_bus_process returned 1 Bus test-bus: changing state CLOSING → CLOSED stage 8: sd_bus_process returned 1 stage 9: sd_bus_process returned -104 Processing failed: Connection reset by peer
* bus-util: avoid unneeded initalization to zeroZbigniew Jędrzejewski-Szmek2018-06-061-4/+6
|
* Use const char* for timestamp strings which we don't plan to modifyZbigniew Jędrzejewski-Szmek2018-05-311-1/+2
| | | | Makes the intent a bit clearer.
* tree-wide: fix typo in comments and NEWSYu Watanabe2018-05-291-1/+1
|
* machined: move bus_reply_pair_array() into generic utilitiesLennart Poettering2018-05-241-0/+31
| | | | This way, we can reuse it in portabled.
* Merge pull request #8817 from yuwata/cleanup-nsflagsLennart Poettering2018-05-241-1/+1
|\ | | | | core: allow to specify RestrictNamespaces= multiple times
| * nsflsgs: drop namespace_flag_{from,to}_string()Yu Watanabe2018-05-051-1/+1
| | | | | | | | | | | | This also drops namespace_flag_to_string_many_with_check(), and renames namespace_flag_{from,to}_string_many() to namespace_flags_{from,to}_string().
* | timesync,shared: move logic requesting bus name to sharedYu Watanabe2018-05-221-0/+121
| | | | | | | | | | Preparation for setting DynamicUser= to other services which request bus names.
* | rlimit-util: rework rlimit_{from|to}_string() to work without "Limit" prefixLennart Poettering2018-05-171-7/+11
| | | | | | | | | | let's make the call more generic, so that we can also easily use it for parsing "RLIMIT_xyz" style constants.
* | tree-wide: use strv_free_and_replace() macroYu Watanabe2018-05-091-3/+1
| |
* | bus-util: print a friendly message when PID1 is not systemdYu Watanabe2018-05-091-4/+16
|/ | | | | | Follow-up for 861f16d2679eeda79e8185057cef24653913e300. Fixes #8913.
* bus-util: introduce bus_open_system_watch_bind_with_description()Yu Watanabe2018-04-171-1/+7
| | | | | | Similar to 56fbd7187a5af44a90c258fbeb1f17114f226bb3, this adds bus_open_system_watch_bind_with_description() to set description for busses.
* tree-wide: drop license boilerplateZbigniew Jędrzejewski-Szmek2018-04-061-13/+0
| | | | | | | | | | Files which are installed as-is (any .service and other unit files, .conf files, .policy files, etc), are left as is. My assumption is that SPDX identifiers are not yet that well known, so it's better to retain the extended header to avoid any doubt. I also kept any copyright lines. We can probably remove them, but it'd nice to obtain explicit acks from all involved authors before doing that.
* tree-wide: use TAKE_PTR() and TAKE_FD() macrosYu Watanabe2018-04-051-8/+4
|
* bus-util: add flags for bus_map_all_properties() (#8546)Yu Watanabe2018-03-281-10/+15
| | | | | | | | | This adds flags BUS_MAP_STRDUP and BUS_MAP_BOOLEAN_AS_BOOL. If BUS_MAP_STRDUP is set, then each "s" message is duplicated. If BUS_MAP_BOOLEAN_AS_BOOL is set, then each "b" message is written to a bool pointer. Follow-up for #8488. See https://github.com/systemd/systemd/pull/8488#discussion_r175816270.
* macro: introduce TAKE_PTR() macroLennart Poettering2018-03-221-2/+1
| | | | | | | | | | | | | | | | This macro will read a pointer of any type, return it, and set the pointer to NULL. This is useful as an explicit concept of passing ownership of a memory area between pointers. This takes inspiration from Rust: https://doc.rust-lang.org/std/option/enum.Option.html#method.take and was suggested by Alan Jenkins (@sourcejedi). It drops ~160 lines of code from our codebase, which makes me like it. Also, I think it clarifies passing of ownership, and thus helps readability a bit (at least for the initiated who know the new macro)
* bus-util: introduce bus_message_print_all_properties()Yu Watanabe2018-03-191-42/+79
| | | | Then, use it where applicable.
* bus-util: make bus_map_all_properties() not copy stringYu Watanabe2018-03-191-6/+20
|
* bus-util: store boolean message to boolYu Watanabe2018-03-191-2/+2
|
* bus-util: fix format of NextElapseUSecRealtime= and LastTriggerUSec=Yu Watanabe2018-01-251-1/+1
| | | | | | | | | | | | | Before this, `systemctl show` for calendar type timer unit outputs something like below. ``` NextElapseUSecRealtime=48y 3w 3d 15h NextElapseUSecMonotonic=0 LastTriggerUSec=48y 3w 3d 3h 41min 44.093095s LastTriggerUSecMonotonic=0 ``` As both NextElapseUSecRealtime= and LastTriggerUSec= are not timespan but timestamp, this makes format these values by `format_timestamp()`.
* bus-util: add bool property setterJan Klötzke2018-01-221-0/+19
|
* networkd,resolved: make use of watch_bind feature to connect to the busLennart Poettering2018-01-051-0/+51
| | | | | | | | | | The changes both networkd and resolved to make use of the watch_bind feature of sd-bus to connect to the system bus. This way, both daemons can be started during early boot, and automatically and instantly connect to the system bus as it becomes available. This replaces prior code that used a time-based retry logic to connect to the bus.
* tree-wide: install matches asynchronouslyLennart Poettering2018-01-051-15/+13
| | | | | | | | | Let's remove a number of synchronization points from our service startups: let's drop synchronous match installation, and let's opt for asynchronous instead. Also, let's use sd_bus_match_signal() instead of sd_bus_add_match() where we can.
* sd-bus: port one use of SO_PEERCRED by getpeercred()Lennart Poettering2018-01-041-8/+4
|
* *: fix some inconsistent control statement styleVito Caputo2017-12-021-1/+1
|
* Add set/hashmap helpers for non-trivial freeing and use where straighforwardZbigniew Jędrzejewski-Szmek2017-11-281-6/+1
| | | | | | A macro is needed because otherwise we couldn't ensure type safety. Some simple tests are included. No functional change intended.