SD_DEV..._PARENT(3)
π SD_DEV..._PARENT(3) π
okay bestie, sit down, hydrate, because today we're talking about device enumeration and it is lowkey the most useful thing ever. This page covers a whole squad of sd_device_enumerator filter functions. Every single one of them is out here adding a filter to your device enumerator. it's giving β¨curated vibesβ¨.
β¨ NAME β¨
sd_device_enumerator_add_match_parent, sd_device_enumerator_add_match_property, sd_device_enumerator_add_match_property_required, sd_device_enumerator_add_match_subsystem, sd_device_enumerator_add_match_sysattr, sd_device_enumerator_add_match_sysname, sd_device_enumerator_add_nomatch_sysname, sd_device_enumerator_add_match_tag, sd_device_enumerator_allow_uninitialized, sd_device_enumerator_add_all_parents β they all add a filter to the device enumerator. that's it, that's the job. π«Ά
π SYNOPSIS π
#include <systemd/sd-device.h>
int sd_device_enumerator_add_match_parent(sd_device_enumerator *enumerator,
sd_device *parent);
int sd_device_enumerator_add_match_property(sd_device_enumerator *enumerator,
const char *property,
const char *value);
int sd_device_enumerator_add_match_property_required(sd_device_enumerator *enumerator,
const char *property,
const char *value);
int sd_device_enumerator_add_match_subsystem(sd_device_enumerator *enumerator,
const char *subsystem,
int match);
int sd_device_enumerator_add_match_sysattr(sd_device_enumerator *enumerator,
const char *sysattr,
const char *value,
int match);
int sd_device_enumerator_add_match_sysname(sd_device_enumerator *enumerator,
const char *sysname);
int sd_device_enumerator_add_nomatch_sysname(sd_device_enumerator *enumerator,
const char *sysname);
int sd_device_enumerator_add_match_tag(sd_device_enumerator *enumerator,
const char *tag);
int sd_device_enumerator_allow_uninitialized(sd_device_enumerator *enumerator);
int sd_device_enumerator_add_all_parents(sd_device_enumerator *enumerator);
πΈ DESCRIPTION πΈ
so here's the tea on each one, bestie, in order, no skips:
sd_device_enumerator_add_match_parent()β drops a filter in so that only devices under the tree of theparentdevice you specify get enumerated. call it multiple times and the previously set parent device gets cleared, so only the last call takes effect. no stacking, only the final answer. πsd_device_enumerator_add_match_property()β filters so only devices whose specifiedpropertyequalsvalueget enumerated. bothpropertyandvaluecan be a glob pattern β¨. call it multiple times and you get devices that have at least one of the specified properties with matching values. that means the filters are ORed. periodt.sd_device_enumerator_add_match_property_required()β the stricter sibling of the one above. same "only devices wherepropertyequalsvalue" energy, but call it multiple times and only devices that have all the specified properties with matching values get enumerated. the filters are ANDed, no exceptions. πsd_device_enumerator_add_match_subsystem()β whenmatchis true, all devices in the specifiedsubsystemget enumerated. whenmatchis false, every device except the ones in that subsystem gets enumerated. called multiple times? positive filters are ORed, negative ones are ANDed. iykyk. π¦sd_device_enumerator_add_match_sysattr()β adds a filter on the sysfs attributesysattrmatchingvalue.valuecan be a glob pattern. ifvalueisNULL, devices that either have (whenmatchis true) or do not have (whenmatchis false) the specifiedsysattrare included, regardless of its value β soNULLis mostly equivalent to"*". call it multiple times and only devices that match all the specified sysattr filters get enumerated. these filters are ANDed.sd_device_enumerator_add_match_sysname()β filters so only devices whosesysnameequalssysnameget enumerated.sysnamecan be a glob pattern. called multiple times, the filters are ORed.sd_device_enumerator_add_nomatch_sysname()β adds a filter so that devices whosesysnameequalssysnameare excluded from the enumeration. perfect for yeeting specific devices out of the enumeration process. called multiple times, filters are ANDed. π«sd_device_enumerator_add_match_tag()β filters so only devices tagged withtagget enumerated. called multiple times, filters are ORed. π·οΈsd_device_enumerator_allow_uninitialized()β lets devices that udev hasn't initialized yet be included in the enumeration. letting the babies in early, love that. πsd_device_enumerator_add_all_parents()β enumerates all parent devices of the matching devices. iconic for when you want the entire device tree leading up to a specific device. π³
π₯ RETURN VALUE π₯
all of these functions return 0 or a positive integer on success, or a negative errno-style error code on failure. π
π«§ Errors π«§
the errors that come back may mean these things:
-ENOMEMβ memory allocation failed. the allocator said no. π-EINVALβ one of the arguments is invalid. double-check those args bestie. π
π» EXAMPLES π»
Example 1. Detect Removable USB Devices (Using Match and Exclude)
look at this little program, it's so clean:
/* SPDX-License-Identifier: MIT-0 */
#include <stdbool.h>
#include <stdio.h>
#include <systemd/sd-device.h>
int main(void) {
__attribute__((cleanup(sd_device_enumerator_unrefp))) sd_device_enumerator *enumerator = NULL;
sd_device *device;
int r;
/* Create a new device enumerator */
r = sd_device_enumerator_new(&enumerator);
if (r < 0) {
fprintf(stderr, "Failed to create device enumerator: %s\n", strerror(-r));
return 1;
}
/* Include only devices from the "usb" subsystem */
r = sd_device_enumerator_add_match_subsystem(enumerator, "usb", true);
if (r < 0) {
fprintf(stderr, "Failed to add subsystem match: %s\n", strerror(-r));
return 1;
}
/*
* Exclude devices where the "removable" sysattr is "0"
* These are typically non-removable devices like built-in USB interfaces
*/
r = sd_device_enumerator_add_match_sysattr(enumerator, "removable", "0", false);
if (r < 0) {
fprintf(stderr, "Failed to add sysattr match: %s\n", strerror(-r));
return 1;
}
/* Begin enumerating matching devices */
for (device = sd_device_enumerator_get_device_first(enumerator);
device;
device = sd_device_enumerator_get_device_next(enumerator)) {
const char *syspath;
/* Get syspath for the device */
if (sd_device_get_syspath(device, &syspath) >= 0)
printf("Removable USB device found: %s\n", syspath);
}
return 0;
}
π°οΈ HISTORY π°οΈ
a little lore for you, because knowing when things dropped is a flex:
sd_device_enumerator_add_match_parent(),sd_device_enumerator_add_match_property(),sd_device_enumerator_add_match_subsystem(),sd_device_enumerator_add_match_sysattr(),sd_device_enumerator_add_match_sysname(),sd_device_enumerator_add_match_tag(), andsd_device_enumerator_allow_uninitialized()were added in version 240. πsd_device_enumerator_add_nomatch_sysname()was added in version 251.sd_device_enumerator_add_match_property_required()was added in version 255.sd_device_enumerator_add_all_parents()was added in version 258. π
π SEE ALSO π
go read these next, they're the friends of this page:
bestie reminder: every filter you add is a vibe you're setting for your enumeration. add them on purpose, not by accident. π
and that's the whole page!! mwah π this one comes to you from systemd 262.1, shipped under SD_DEV..._PARENT(3), so go forth and enumerate responsibly. slay. πβ¨
π¦ where this page comes from
- arch rolling: systemd-libs 262.1-1 Β· LGPL-2.1-or-later AND CC0-1.0 AND GPL-2.0-or-later WITH Linux-syscall-note
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms