X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=libudev%2Flibudev-device.c;h=16bee19dff4cca9463aab0b24e44fd593d1d12e0;hb=c54b43e2c233e724f840c4f6a0a81bdd549e40bb;hp=8698d98e1c6871ee7ea3c2ddf88f95c75fe2fa95;hpb=cad40a5fe75d876af22f68b688494b9cd98cc899;p=elogind.git diff --git a/libudev/libudev-device.c b/libudev/libudev-device.c index 8698d98e1..16bee19df 100644 --- a/libudev/libudev-device.c +++ b/libudev/libudev-device.c @@ -63,6 +63,7 @@ struct udev_device { struct udev_list_node sysattr_list; struct udev_list_node tags_list; unsigned long long int seqnum; + unsigned long long int usec_initialized; int event_timeout; int timeout; int devlink_priority; @@ -81,6 +82,7 @@ struct udev_device { bool info_loaded; bool db_loaded; bool uevent_loaded; + bool is_initialized; }; struct udev_list_entry *udev_device_add_property(struct udev_device *udev_device, const char *key, const char *value) @@ -249,6 +251,7 @@ int udev_device_read_db(struct udev_device *udev_device) info(udev_device->udev, "no db file to read %s: %m\n", filename); return -1; } + udev_device->is_initialized = true; while (fgets(line, sizeof(line), f)) { ssize_t len; @@ -282,6 +285,9 @@ int udev_device_read_db(struct udev_device *udev_device) case 'W': udev_device_set_watch_handle(udev_device, atoi(val)); break; + case 'I': + udev_device_set_usec_initialized(udev_device, strtoull(val, NULL, 10)); + break; } } fclose(f); @@ -1092,6 +1098,44 @@ unsigned long long int udev_device_get_seqnum(struct udev_device *udev_device) return udev_device->seqnum; } +/** + * udev_device_get_usec_since_initialized: + * @udev_device: udev device + * + * Return the number of microseconds passed since udev set up the + * device for the first time. + * + * This is only implemented for devices with need to store properties + * in the udev database. All other devices return 0 here. + * + * Returns: the number of microseconds since the device was first seen. + **/ +unsigned long long int udev_device_get_usec_since_initialized(struct udev_device *udev_device) +{ + unsigned long long now; + + if (udev_device == NULL) + return 0; + if (!udev_device->info_loaded) + udev_device_read_db(udev_device); + if (udev_device->usec_initialized == 0) + return 0; + now = usec_monotonic(); + if (now == 0) + return 0; + return now - udev_device->usec_initialized; +} + +unsigned long long udev_device_get_usec_initialized(struct udev_device *udev_device) +{ + return udev_device->usec_initialized; +} + +void udev_device_set_usec_initialized(struct udev_device *udev_device, unsigned long long usec_initialized) +{ + udev_device->usec_initialized = usec_initialized; +} + /** * udev_device_get_sysattr_value: * @udev_device: udev device @@ -1287,7 +1331,7 @@ const char *udev_device_get_id_filename(struct udev_device *udev_device) major(udev_device_get_devnum(udev_device)), minor(udev_device_get_devnum(udev_device))) < 0) udev_device->id_filename = NULL; - } else if (strcmp(udev_device_get_subsystem(udev_device), "net") == 0) { + } else if (udev_device_get_ifindex(udev_device) > 0) { /* use netdev ifindex -- n3 */ if (asprintf(&udev_device->id_filename, "n%u", udev_device_get_ifindex(udev_device)) < 0) udev_device->id_filename = NULL; @@ -1308,6 +1352,31 @@ const char *udev_device_get_id_filename(struct udev_device *udev_device) return udev_device->id_filename; } +/** + * udev_device_get_is_initialized: + * @udev_device: udev device + * + * Check if udev has already handled the device and has set up + * device node permissions and context, or has renamed a network + * device. + * + * This is only implemented for devices with a device node + * or network interfaces. All other devices return 1 here. + * + * Returns: 1 if the device is set up. 0 otherwise. + **/ +int udev_device_get_is_initialized(struct udev_device *udev_device) +{ + if (!udev_device->info_loaded) + udev_device_read_db(udev_device); + return udev_device->is_initialized; +} + +void udev_device_set_is_initialized(struct udev_device *udev_device) +{ + udev_device->is_initialized = true; +} + int udev_device_add_tag(struct udev_device *udev_device, const char *tag) { if (strchr(tag, ':') != NULL || strchr(tag, ' ') != NULL) @@ -1582,6 +1651,8 @@ int udev_device_set_watch_handle(struct udev_device *udev_device, int handle) int udev_device_get_ifindex(struct udev_device *udev_device) { + if (!udev_device->info_loaded) + udev_device_read_uevent_file(udev_device); return udev_device->ifindex; }