diff --git a/man/sd_hwdb_new.xml b/man/sd_hwdb_new.xml index c071599a..0584add4 100644 --- a/man/sd_hwdb_new.xml +++ b/man/sd_hwdb_new.xml @@ -16,6 +16,7 @@ sd_hwdb_new + sd_hwdb_new_from_path sd_hwdb_ref sd_hwdb_unref @@ -31,6 +32,12 @@ sd_hwdb **hwdb + + int sd_hwdb_new_from_path + const char *path + sd_hwdb **hwdb + + sd_hwdb* sd_hwdb_ref sd_hwdb *hwdb @@ -50,6 +57,9 @@ database. Upon initialization, the file containing the binary representation of the hardware database is located and opened. The new object is returned in hwdb. + sd_hwdb_new_from_path() may be used to specify the path from which the binary + hardware database should be opened. + The hwdb object is reference counted. sd_hwdb_ref() and sd_hwdb_unref() may be used to get a new reference or destroy an existing reference to an object. The caller must dispose of the reference acquired with sd_hwdb_new() @@ -65,8 +75,8 @@ Return Value - On success, sd_hwdb_new() returns a non-negative integer. On - failure, it returns a negative errno-style error code. + On success, sd_hwdb_new() and sd_hwdb_new_from_path() + return a non-negative integer. On failure, a negative errno-style error code is returned. sd_hwdb_ref() always returns the argument. diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym index ccc321ec..528e86b6 100644 --- a/src/libsystemd/libsystemd.sym +++ b/src/libsystemd/libsystemd.sym @@ -778,3 +778,8 @@ global: sd_device_open; sd_device_enumerator_add_nomatch_sysname; } LIBSYSTEMD_250; + +LIBSYSTEMD_252 { +global: + sd_hwdb_new_from_path; +} LIBSYSTEMD_251; diff --git a/src/libsystemd/sd-hwdb/sd-hwdb.c b/src/libsystemd/sd-hwdb/sd-hwdb.c index 748cf269..f73d1fc2 100644 --- a/src/libsystemd/sd-hwdb/sd-hwdb.c +++ b/src/libsystemd/sd-hwdb/sd-hwdb.c @@ -281,9 +281,9 @@ static int trie_search_f(sd_hwdb *hwdb, const char *search) { return 0; } -_public_ int sd_hwdb_new(sd_hwdb **ret) { +static int hwdb_new(const char *path, sd_hwdb **ret) { _cleanup_(sd_hwdb_unrefp) sd_hwdb *hwdb = NULL; - const char *hwdb_bin_path; + const char *hwdb_bin_path = NULL; const char sig[] = HWDB_SIG; assert_return(ret, -EINVAL); @@ -294,19 +294,26 @@ _public_ int sd_hwdb_new(sd_hwdb **ret) { hwdb->n_ref = 1; - /* find hwdb.bin in hwdb_bin_paths */ - NULSTR_FOREACH(hwdb_bin_path, hwdb_bin_paths) { - log_debug("Trying to open \"%s\"...", hwdb_bin_path); - hwdb->f = fopen(hwdb_bin_path, "re"); - if (hwdb->f) - break; - if (errno != ENOENT) - return log_debug_errno(errno, "Failed to open %s: %m", hwdb_bin_path); - } + /* find hwdb.bin in hwdb_bin_paths, or from an explicit path if provided */ + if (!isempty(path)) { + log_debug("Trying to open \"%s\"...", path); + hwdb->f = fopen(path, "re"); + if (!hwdb->f) + return log_debug_errno(errno, "Failed to open %s: %m", path); + } else { + NULSTR_FOREACH(hwdb_bin_path, hwdb_bin_paths) { + log_debug("Trying to open \"%s\"...", hwdb_bin_path); + hwdb->f = fopen(hwdb_bin_path, "re"); + if (hwdb->f) + break; + if (errno != ENOENT) + return log_debug_errno(errno, "Failed to open %s: %m", hwdb_bin_path); + } - if (!hwdb->f) - return log_debug_errno(SYNTHETIC_ERRNO(ENOENT), - "hwdb.bin does not exist, please run 'systemd-hwdb update'"); + if (!hwdb->f) + return log_debug_errno(SYNTHETIC_ERRNO(ENOENT), + "hwdb.bin does not exist, please run 'systemd-hwdb update'"); + } if (fstat(fileno(hwdb->f), &hwdb->st) < 0) return log_debug_errno(errno, "Failed to stat %s: %m", hwdb_bin_path); @@ -339,6 +346,16 @@ _public_ int sd_hwdb_new(sd_hwdb **ret) { return 0; } +_public_ int sd_hwdb_new_from_path(const char *path, sd_hwdb **ret) { + assert_return(!isempty(path), -EINVAL); + + return hwdb_new(path, ret); +} + +_public_ int sd_hwdb_new(sd_hwdb **ret) { + return hwdb_new(NULL, ret); +} + static sd_hwdb *hwdb_free(sd_hwdb *hwdb) { assert(hwdb); diff --git a/src/systemd/sd-hwdb.h b/src/systemd/sd-hwdb.h index 9380759e..9eee1c19 100644 --- a/src/systemd/sd-hwdb.h +++ b/src/systemd/sd-hwdb.h @@ -27,6 +27,7 @@ sd_hwdb *sd_hwdb_ref(sd_hwdb *hwdb); sd_hwdb *sd_hwdb_unref(sd_hwdb *hwdb); int sd_hwdb_new(sd_hwdb **ret); +int sd_hwdb_new_from_path(const char *path, sd_hwdb **ret); int sd_hwdb_get(sd_hwdb *hwdb, const char *modalias, const char *key, const char **value); diff --git a/src/test/test-sd-hwdb.c b/src/test/test-sd-hwdb.c index 5e139856..f18634cc 100644 --- a/src/test/test-sd-hwdb.c +++ b/src/test/test-sd-hwdb.c @@ -5,6 +5,8 @@ #include "alloc-util.h" #include "errno-util.h" #include "errno.h" +#include "hwdb-internal.h" +#include "nulstr-util.h" #include "tests.h" TEST(failed_enumerate) { @@ -52,6 +54,24 @@ TEST(basic_enumerate) { assert_se(len1 == len2); } +TEST(sd_hwdb_new_from_path) { + _cleanup_(sd_hwdb_unrefp) sd_hwdb *hwdb = NULL; + const char *hwdb_bin_path = NULL; + int r; + + assert_se(sd_hwdb_new_from_path(NULL, &hwdb) == -EINVAL); + assert_se(sd_hwdb_new_from_path("", &hwdb) == -EINVAL); + assert_se(sd_hwdb_new_from_path("/path/that/should/not/exist", &hwdb) < 0); + + NULSTR_FOREACH(hwdb_bin_path, hwdb_bin_paths) { + r = sd_hwdb_new_from_path(hwdb_bin_path, &hwdb); + if (r >= 0) + break; + } + + assert_se(r >= 0); +} + static int intro(void) { _cleanup_(sd_hwdb_unrefp) sd_hwdb *hwdb = NULL; int r;