UDEV_DEVI...M_SYSPATH(3)

πŸ’– UDEV_DEVI...M_SYSPATH(3) πŸ’–

okay bestie, so this is the manual page for the UDEV_DEVI...M_SYSPATH(3) family of functions β€” yes that name is a whole mood (it's the truncated one, the real squad is udev_device_new_from_syspath, udev_device_new_from_devnum, udev_device_new_from_subsystem_sysname, udev_device_new_from_device_id, udev_device_new_from_environment, udev_device_ref and udev_device_unref) β€” and it's page 3 of the libudev manuals. it's literally about creating, grabbing and yeeting udev device objects. let's get into it 🫢


✨ NAME ✨

udev_device_new_from_syspath, udev_device_new_from_devnum, udev_device_new_from_subsystem_sysname, udev_device_new_from_device_id, udev_device_new_from_environment, udev_device_ref, udev_device_unref β€” create, acquire and release a udev device object πŸ’…


🌸 SYNOPSIS 🌸

#include <libudev.h>

struct udev_device *udev_device_new_from_syspath(struct udev *udev,
                                                 const char *syspath);

struct udev_device *udev_device_new_from_devnum(struct udev *udev,
                                                char type,
                                                dev_t devnum);

struct udev_device *udev_device_new_from_subsystem_sysname(struct udev *udev,
                                                           const char *subsystem,
                                                           const char *sysname);

struct udev_device *udev_device_new_from_device_id(struct udev *udev,
                                                   const char *id);

struct udev_device *udev_device_new_from_environment(struct udev *udev);

struct udev_device *udev_device_ref(struct udev_device *udev_device);

struct udev_device *udev_device_unref(struct udev_device *udev_device);

πŸ¦‹ DESCRIPTION πŸ¦‹

so. udev_device_new_from_syspath(), udev_device_new_from_devnum(), udev_device_new_from_subsystem_sysname(), udev_device_new_from_device_id(), and udev_device_new_from_environment() all allocate a brand new udev device object and hand you back a pointer to it. ✨

this object is opaque, and that's not a vibe suggestion, it's a rule: you must not poke at it by any means other than the functions libudev gives you. no sneaky peeking, no cap. πŸ™ˆ

when it's born, the reference count of the device is 1. you can pick up more references, and drop the ones you grabbed, with udev_device_ref() and udev_device_unref(). once the reference count hits 0, the device object is destroyed and freed. periodt. πŸ’€


πŸŽ€ the four "look it up in /sys/" makers πŸŽ€

udev_device_new_from_syspath(), udev_device_new_from_devnum(), udev_device_new_from_subsystem_sysname(), and udev_device_new_from_device_id() create the device object based on info they find in /sys/, annotated with properties from the udev-internal device database. πŸ‘‘

a syspath is any subdirectory of /sys/, with the restriction that a subdirectory of /sys/devices (or a symlink pointing to one) represents a real device and as such must contain a uevent file. yes, mandatory. it's giving strict. πŸ’…

udev_device_new_from_devnum() takes a device type β€” which can be b for block devices or c for character devices β€” plus a devnum (see makedev(3)).

udev_device_new_from_subsystem_sysname() looks up devices based on the provided subsystem and sysname (see udev_device_get_subsystem(3) and udev_device_get_sysname(3)) 🧚

and udev_device_new_from_device_id() looks up devices based on the provided device ID, which is a special string in one of the following four forms:

ngl this was a table in the original, so here it is as a glow-up list instead β€” same facts, more sparkle:
  • b8:2 β€” block device major:minor
  • c128:1 β€” char device major:minor
  • n3 β€” network device ifindex
  • +sound:card29 β€” kernel driver core subsystem:device name

🌈 the environment one 🌈

udev_device_new_from_environment() creates a device from the current environment (see environ(7)). every key-value pair is interpreted the exact same way as if it had been received in a uevent (see udev_monitor_receive_device(3)).

the keys DEVPATH, SUBSYSTEM, ACTION, and SEQNUM are mandatory. not optional, not "if you feel like it" β€” mandatory fr fr. πŸ”₯


🌟 RETURN VALUE 🌟

on success, udev_device_new_from_syspath(), udev_device_new_from_devnum(), udev_device_new_from_subsystem_sysname(), udev_device_new_from_device_id() and udev_device_new_from_environment() return a pointer to the allocated udev device. slay. πŸ’–

on failure, NULL is returned, and errno is set appropriately. 😭

udev_device_ref() returns the argument that it was passed, unmodified β€” like, it literally just hands you back what you gave it. iconic.

udev_device_unref() always returns NULL. always. every single time. don't ask questions. πŸ‘‘


⭐ HISTORY ⭐

udev_device_new_from_syspath(), udev_device_new_from_devnum(), udev_device_new_from_subsystem_sysname(), udev_device_new_from_device_id(), udev_device_new_from_environment(), udev_device_ref(), and udev_device_unref() were added in version 221. vintage but make it fresh πŸŽ€


πŸ’œ SEE ALSO πŸ’œ

udev_new(3), udev_device_get_syspath(3), udev_device_has_tag(3), udev_enumerate_new(3), udev_monitor_new_from_netlink(3), udev_list_entry(3), systemd(1)

go read those next, bestie, they're all part of the same friend group 🫢


and that's the whole page!! this one came from systemd 261.3 β€” mwah, see you in the next man page πŸ’‹βœ¨

πŸ“¦ where this page comes from