1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-01-25 06:03:40 +03:00

sd-hwdb: add sd_hwdb_new_from_path

The existing sd_hwdb_new function always initializes the hwdb from the
first successful hwdb.bin it finds from hwdb_bin_paths. This means there
is currently no way to initialize a hwdb from an explicit path, which
would be useful for systemd-hwdb query.

Add sd_hwdb_new_from_path to allow a sd_hwdb to be initialized from a
custom path outside of hwdb_bin_paths.
This commit is contained in:
Nick Rosbrook 2022-05-24 13:08:06 -04:00
parent 9745b51c73
commit 60f0ba7556
5 changed files with 69 additions and 16 deletions

View File

@ -16,6 +16,7 @@
<refnamediv> <refnamediv>
<refname>sd_hwdb_new</refname> <refname>sd_hwdb_new</refname>
<refname>sd_hwdb_new_from_path</refname>
<refname>sd_hwdb_ref</refname> <refname>sd_hwdb_ref</refname>
<refname>sd_hwdb_unref</refname> <refname>sd_hwdb_unref</refname>
@ -31,6 +32,12 @@
<paramdef>sd_hwdb **<parameter>hwdb</parameter></paramdef> <paramdef>sd_hwdb **<parameter>hwdb</parameter></paramdef>
</funcprototype> </funcprototype>
<funcprototype>
<funcdef>int <function>sd_hwdb_new_from_path</function></funcdef>
<paramdef>const char *<parameter>path</parameter></paramdef>
<paramdef>sd_hwdb **<parameter>hwdb</parameter></paramdef>
</funcprototype>
<funcprototype> <funcprototype>
<funcdef>sd_hwdb* <function>sd_hwdb_ref</function></funcdef> <funcdef>sd_hwdb* <function>sd_hwdb_ref</function></funcdef>
<paramdef>sd_hwdb *<parameter>hwdb</parameter></paramdef> <paramdef>sd_hwdb *<parameter>hwdb</parameter></paramdef>
@ -50,6 +57,9 @@
database. Upon initialization, the file containing the binary representation of the hardware database is database. Upon initialization, the file containing the binary representation of the hardware database is
located and opened. The new object is returned in <parameter>hwdb</parameter>.</para> located and opened. The new object is returned in <parameter>hwdb</parameter>.</para>
<para><function>sd_hwdb_new_from_path()</function> may be used to specify the path from which the binary
hardware database should be opened.</para>
<para>The <parameter>hwdb</parameter> object is reference counted. <function>sd_hwdb_ref()</function> and <para>The <parameter>hwdb</parameter> object is reference counted. <function>sd_hwdb_ref()</function> and
<function>sd_hwdb_unref()</function> may be used to get a new reference or destroy an existing reference <function>sd_hwdb_unref()</function> 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 <function>sd_hwdb_new()</function> to an object. The caller must dispose of the reference acquired with <function>sd_hwdb_new()</function>
@ -65,8 +75,8 @@
<refsect1> <refsect1>
<title>Return Value</title> <title>Return Value</title>
<para>On success, <function>sd_hwdb_new()</function> returns a non-negative integer. On <para>On success, <function>sd_hwdb_new()</function> and <function>sd_hwdb_new_from_path()</function>
failure, it returns a negative errno-style error code.</para> return a non-negative integer. On failure, a negative errno-style error code is returned.</para>
<para><function>sd_hwdb_ref()</function> always returns the argument. <para><function>sd_hwdb_ref()</function> always returns the argument.
</para> </para>

View File

@ -778,3 +778,8 @@ global:
sd_device_open; sd_device_open;
sd_device_enumerator_add_nomatch_sysname; sd_device_enumerator_add_nomatch_sysname;
} LIBSYSTEMD_250; } LIBSYSTEMD_250;
LIBSYSTEMD_252 {
global:
sd_hwdb_new_from_path;
} LIBSYSTEMD_251;

View File

@ -281,9 +281,9 @@ static int trie_search_f(sd_hwdb *hwdb, const char *search) {
return 0; 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; _cleanup_(sd_hwdb_unrefp) sd_hwdb *hwdb = NULL;
const char *hwdb_bin_path; const char *hwdb_bin_path = NULL;
const char sig[] = HWDB_SIG; const char sig[] = HWDB_SIG;
assert_return(ret, -EINVAL); assert_return(ret, -EINVAL);
@ -294,19 +294,26 @@ _public_ int sd_hwdb_new(sd_hwdb **ret) {
hwdb->n_ref = 1; hwdb->n_ref = 1;
/* find hwdb.bin in hwdb_bin_paths */ /* find hwdb.bin in hwdb_bin_paths, or from an explicit path if provided */
NULSTR_FOREACH(hwdb_bin_path, hwdb_bin_paths) { if (!isempty(path)) {
log_debug("Trying to open \"%s\"...", hwdb_bin_path); log_debug("Trying to open \"%s\"...", path);
hwdb->f = fopen(hwdb_bin_path, "re"); hwdb->f = fopen(path, "re");
if (hwdb->f) if (!hwdb->f)
break; return log_debug_errno(errno, "Failed to open %s: %m", path);
if (errno != ENOENT) } else {
return log_debug_errno(errno, "Failed to open %s: %m", hwdb_bin_path); 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) if (!hwdb->f)
return log_debug_errno(SYNTHETIC_ERRNO(ENOENT), return log_debug_errno(SYNTHETIC_ERRNO(ENOENT),
"hwdb.bin does not exist, please run 'systemd-hwdb update'"); "hwdb.bin does not exist, please run 'systemd-hwdb update'");
}
if (fstat(fileno(hwdb->f), &hwdb->st) < 0) if (fstat(fileno(hwdb->f), &hwdb->st) < 0)
return log_debug_errno(errno, "Failed to stat %s: %m", hwdb_bin_path); 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; 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) { static sd_hwdb *hwdb_free(sd_hwdb *hwdb) {
assert(hwdb); assert(hwdb);

View File

@ -27,6 +27,7 @@ sd_hwdb *sd_hwdb_ref(sd_hwdb *hwdb);
sd_hwdb *sd_hwdb_unref(sd_hwdb *hwdb); sd_hwdb *sd_hwdb_unref(sd_hwdb *hwdb);
int sd_hwdb_new(sd_hwdb **ret); 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); int sd_hwdb_get(sd_hwdb *hwdb, const char *modalias, const char *key, const char **value);

View File

@ -5,6 +5,8 @@
#include "alloc-util.h" #include "alloc-util.h"
#include "errno-util.h" #include "errno-util.h"
#include "errno.h" #include "errno.h"
#include "hwdb-internal.h"
#include "nulstr-util.h"
#include "tests.h" #include "tests.h"
TEST(failed_enumerate) { TEST(failed_enumerate) {
@ -52,6 +54,24 @@ TEST(basic_enumerate) {
assert_se(len1 == len2); 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) { static int intro(void) {
_cleanup_(sd_hwdb_unrefp) sd_hwdb *hwdb = NULL; _cleanup_(sd_hwdb_unrefp) sd_hwdb *hwdb = NULL;
int r; int r;