diff options
Diffstat (limited to 'src/libudev/libudev-hwdb.c')
-rw-r--r-- | src/libudev/libudev-hwdb.c | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/src/libudev/libudev-hwdb.c b/src/libudev/libudev-hwdb.c new file mode 100644 index 0000000..8e9ea97 --- /dev/null +++ b/src/libudev/libudev-hwdb.c @@ -0,0 +1,123 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include <errno.h> + +#include "sd-hwdb.h" + +#include "alloc-util.h" +#include "hwdb-util.h" +#include "libudev-list-internal.h" + +/** + * SECTION:libudev-hwdb + * @short_description: retrieve properties from the hardware database + * + * Libudev hardware database interface. + */ + +/** + * udev_hwdb: + * + * Opaque object representing the hardware database. + */ +struct udev_hwdb { + unsigned n_ref; + sd_hwdb *hwdb; + struct udev_list *properties_list; +}; + +/** + * udev_hwdb_new: + * @udev: udev library context (unused) + * + * Create a hardware database context to query properties for devices. + * + * Returns: a hwdb context. + **/ +_public_ struct udev_hwdb *udev_hwdb_new(struct udev *udev) { + _cleanup_(udev_list_freep) struct udev_list *list = NULL; + _cleanup_(sd_hwdb_unrefp) sd_hwdb *hwdb_internal = NULL; + struct udev_hwdb *hwdb; + int r; + + r = sd_hwdb_new(&hwdb_internal); + if (r < 0) + return_with_errno(NULL, r); + + list = udev_list_new(true); + if (!list) + return_with_errno(NULL, ENOMEM); + + hwdb = new(struct udev_hwdb, 1); + if (!hwdb) + return_with_errno(NULL, ENOMEM); + + *hwdb = (struct udev_hwdb) { + .n_ref = 1, + .hwdb = TAKE_PTR(hwdb_internal), + .properties_list = TAKE_PTR(list), + }; + + return hwdb; +} + +static struct udev_hwdb *udev_hwdb_free(struct udev_hwdb *hwdb) { + assert(hwdb); + + sd_hwdb_unref(hwdb->hwdb); + udev_list_free(hwdb->properties_list); + return mfree(hwdb); +} + +/** + * udev_hwdb_ref: + * @hwdb: context + * + * Take a reference of a hwdb context. + * + * Returns: the passed enumeration context + **/ + +/** + * udev_hwdb_unref: + * @hwdb: context + * + * Drop a reference of a hwdb context. If the refcount reaches zero, + * all resources of the hwdb context will be released. + * + * Returns: #NULL + **/ +DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(struct udev_hwdb, udev_hwdb, udev_hwdb_free); + +/** + * udev_hwdb_get_properties_list_entry: + * @hwdb: context + * @modalias: modalias string + * @flags: (unused) + * + * Lookup a matching device in the hardware database. The lookup key is a + * modalias string, whose formats are defined for the Linux kernel modules. + * Examples are: pci:v00008086d00001C2D*, usb:v04F2pB221*. The first entry + * of a list of retrieved properties is returned. + * + * Returns: a udev_list_entry. + */ +_public_ struct udev_list_entry *udev_hwdb_get_properties_list_entry(struct udev_hwdb *hwdb, const char *modalias, unsigned flags) { + const char *key, *value; + struct udev_list_entry *e; + + assert_return_errno(hwdb, NULL, EINVAL); + assert_return_errno(modalias, NULL, EINVAL); + + udev_list_cleanup(hwdb->properties_list); + + SD_HWDB_FOREACH_PROPERTY(hwdb->hwdb, modalias, key, value) + if (!udev_list_entry_add(hwdb->properties_list, key, value)) + return_with_errno(NULL, ENOMEM); + + e = udev_list_get_entry(hwdb->properties_list); + if (!e) + return_with_errno(NULL, ENODATA); + + return e; +} |