SD_DEV...E_FIRST(3)
π sd_device_enumerator_get_device_first, sd_device_enumerator_get_device_next, sd_device_enumerator_get_subsystem_first, sd_device_enumerator_get_subsystem_next β (section 3 of the manuals, bestie) π
okay so picture this: you're deep in /sys, everything is symlinks, nothing makes sense, and you just want to β¨enumerateβ¨ some devices. That's literally what these four functions are for. They walk the device tree and hand you pointers one at a time. Let's get into it. π¦
β¨ SYNOPSIS β¨
#include <systemd/sd-device.h>
sd_device *sd_device_enumerator_get_device_first(sd_device_enumerator *enumerator);
sd_device *sd_device_enumerator_get_device_next(sd_device_enumerator *enumerator);
sd_device *sd_device_enumerator_get_subsystem_first(sd_device_enumerator *enumerator);
sd_device *sd_device_enumerator_get_subsystem_next(sd_device_enumerator *enumerator);
πΈ DESCRIPTION πΈ
π the device ones (the classic main-character duo)
sd_device_enumerator_get_device_first() goes and enumerates every single matching device under /sys/bus/SUBSYSTEM/devices/ and /sys/class/SUBSYSTEM/devices/, then hands you back a pointer to the first sd_device object. And if there are, like, no devices found? It returns NULL. No devices, no drama, no pointer. π«Ά
sd_device_enumerator_get_device_next() returns the pointer to the next sd_device from the enumerator. Important: you call this after sd_device_enumerator_get_device_first(), or after a previous call to this same function β it does not start the party by itself. And when there are no more devices available, it returns NULL. That's your lil signal that the list is done. π
π§ the subsystem ones (yes they're different, no they are not the same thing)
sd_device_enumerator_get_subsystem_first() enumerates all matching subsystem devices in /sys/module/, /sys/bus/, and /sys/bus/SUBSYSTEM/drivers/ (so, like, for example /sys/bus/pci/drivers/). It returns a pointer to the first sd_device object, and if no devices are found, NULL is returned.
β οΈ IMPORTANT, bestie, do not skip this one: this does not enumerate the devices thatsd_device_enumerator_get_device_first/next()give you. Those are two totally different worlds. So, for example,/sys/bus/pci/,/sys/bus/pci/drivers/ahci/and so on are enumerated, but/sys/bus/pci/devices/0000:00:00.0/and so on are not. iykyk. π
sd_device_enumerator_get_subsystem_next() returns the next subsystem device from the enumerator. Call it after sd_device_enumerator_get_subsystem_first(), or after a previous call to this function. And if no more subsystem devices are available, NULL is returned. Same energy as the device one, different list. β
π RETURN VALUE π
On success, these functions return a pointer to an sd_device object. That's the slay. β¨
On failure, or when there are no more devices available, NULL is returned. π
And listen β the returned pointers are owned by the enumerator. So do not free them yourself, okay? Not your pointer, not your problem. The caller should not free them. periodt. π
π HISTORY π
sd_device_enumerator_get_device_first(), sd_device_enumerator_get_device_next(), sd_device_enumerator_get_subsystem_first(), and sd_device_enumerator_get_subsystem_next() were introduced in systemd version 240. So they've been iconic for a minute. π₯
π SEE ALSO π
and that's the whole page!! π this was the SD_DEV...E_FIRST(3) manual, coming at you from systemd 262.1. go forth and enumerate responsibly, bestie π«Άππ¦πΈ
π¦ 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