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 that sd_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