1 /* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
3 * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27 #include "gudevdevice.h"
28 #include "gudevprivate.h"
32 * @short_description: Get information about a device
34 * The #GUdevDevice class is used to get information about a specific
35 * device. Note that you cannot instantiate a #GUdevDevice object
36 * yourself. Instead you must use #GUdevClient to obtain #GUdevDevice
39 * To get basic information about a device, use
40 * g_udev_device_get_subsystem(), g_udev_device_get_devtype(),
41 * g_udev_device_get_name(), g_udev_device_get_number(),
42 * g_udev_device_get_sysfs_path(), g_udev_device_get_driver(),
43 * g_udev_device_get_action(), g_udev_device_get_seqnum(),
44 * g_udev_device_get_device_type(), g_udev_device_get_device_number(),
45 * g_udev_device_get_device_file(),
46 * g_udev_device_get_device_file_symlinks().
48 * To navigate the device tree, use g_udev_device_get_parent() and
49 * g_udev_device_get_parent_with_subsystem().
51 * To access udev properties for the device, use
52 * g_udev_device_get_property_keys(),
53 * g_udev_device_has_property(),
54 * g_udev_device_get_property(),
55 * g_udev_device_get_property_as_int(),
56 * g_udev_device_get_property_as_uint64(),
57 * g_udev_device_get_property_as_double(),
58 * g_udev_device_get_property_as_boolean() and
59 * g_udev_device_get_property_as_strv().
61 * To access sysfs attributes for the device, use
62 * g_udev_device_get_sysfs_attr_keys(),
63 * g_udev_device_has_sysfs_attr(),
64 * g_udev_device_get_sysfs_attr(),
65 * g_udev_device_get_sysfs_attr_as_int(),
66 * g_udev_device_get_sysfs_attr_as_uint64(),
67 * g_udev_device_get_sysfs_attr_as_double(),
68 * g_udev_device_get_sysfs_attr_as_boolean() and
69 * g_udev_device_get_sysfs_attr_as_strv().
71 * Note that all getters on #GUdevDevice are non-reffing – returned
72 * values are owned by the object, should not be freed and are only
73 * valid as long as the object is alive.
75 * By design, #GUdevDevice will not react to changes for a device – it
76 * only contains a snapshot of information when the #GUdevDevice
77 * object was created. To work with changes, you typically connect to
78 * the #GUdevClient::uevent signal on a #GUdevClient and get a new
79 * #GUdevDevice whenever an event happens.
82 struct _GUdevDevicePrivate
84 struct udev_device *udevice;
86 /* computed ondemand and cached */
87 gchar **device_file_symlinks;
88 gchar **property_keys;
89 gchar **sysfs_attr_keys;
91 GHashTable *prop_strvs;
92 GHashTable *sysfs_attr_strvs;
95 G_DEFINE_TYPE (GUdevDevice, g_udev_device, G_TYPE_OBJECT)
98 g_udev_device_finalize (GObject *object)
100 GUdevDevice *device = G_UDEV_DEVICE (object);
102 g_strfreev (device->priv->device_file_symlinks);
103 g_strfreev (device->priv->property_keys);
104 g_strfreev (device->priv->sysfs_attr_keys);
105 g_strfreev (device->priv->tags);
107 if (device->priv->udevice != NULL)
108 udev_device_unref (device->priv->udevice);
110 if (device->priv->prop_strvs != NULL)
111 g_hash_table_unref (device->priv->prop_strvs);
113 if (device->priv->sysfs_attr_strvs != NULL)
114 g_hash_table_unref (device->priv->sysfs_attr_strvs);
116 if (G_OBJECT_CLASS (g_udev_device_parent_class)->finalize != NULL)
117 (* G_OBJECT_CLASS (g_udev_device_parent_class)->finalize) (object);
121 g_udev_device_class_init (GUdevDeviceClass *klass)
123 GObjectClass *gobject_class = (GObjectClass *) klass;
125 gobject_class->finalize = g_udev_device_finalize;
127 g_type_class_add_private (klass, sizeof (GUdevDevicePrivate));
131 g_udev_device_init (GUdevDevice *device)
133 device->priv = G_TYPE_INSTANCE_GET_PRIVATE (device,
140 _g_udev_device_new (struct udev_device *udevice)
144 device = G_UDEV_DEVICE (g_object_new (G_UDEV_TYPE_DEVICE, NULL));
145 device->priv->udevice = udev_device_ref (udevice);
151 * g_udev_device_get_subsystem:
152 * @device: A #GUdevDevice.
154 * Gets the subsystem for @device.
156 * Returns: The subsystem for @device.
159 g_udev_device_get_subsystem (GUdevDevice *device)
161 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
162 return udev_device_get_subsystem (device->priv->udevice);
166 * g_udev_device_get_devtype:
167 * @device: A #GUdevDevice.
169 * Gets the device type for @device.
171 * Returns: The devtype for @device.
174 g_udev_device_get_devtype (GUdevDevice *device)
176 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
177 return udev_device_get_devtype (device->priv->udevice);
181 * g_udev_device_get_name:
182 * @device: A #GUdevDevice.
184 * Gets the name of @device, e.g. "sda3".
186 * Returns: The name of @device.
189 g_udev_device_get_name (GUdevDevice *device)
191 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
192 return udev_device_get_sysname (device->priv->udevice);
196 * g_udev_device_get_number:
197 * @device: A #GUdevDevice.
199 * Gets the number of @device, e.g. "3" if g_udev_device_get_name() returns "sda3".
201 * Returns: The number of @device.
204 g_udev_device_get_number (GUdevDevice *device)
206 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
207 return udev_device_get_sysnum (device->priv->udevice);
211 * g_udev_device_get_sysfs_path:
212 * @device: A #GUdevDevice.
214 * Gets the sysfs path for @device.
216 * Returns: The sysfs path for @device.
219 g_udev_device_get_sysfs_path (GUdevDevice *device)
221 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
222 return udev_device_get_syspath (device->priv->udevice);
226 * g_udev_device_get_driver:
227 * @device: A #GUdevDevice.
229 * Gets the name of the driver used for @device.
231 * Returns: The name of the driver for @device or %NULL if unknown.
234 g_udev_device_get_driver (GUdevDevice *device)
236 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
237 return udev_device_get_driver (device->priv->udevice);
241 * g_udev_device_get_action:
242 * @device: A #GUdevDevice.
244 * Gets the most recent action (e.g. "add", "remove", "change", etc.) for @device.
246 * Returns: An action string.
249 g_udev_device_get_action (GUdevDevice *device)
251 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
252 return udev_device_get_action (device->priv->udevice);
256 * g_udev_device_get_seqnum:
257 * @device: A #GUdevDevice.
259 * Gets the most recent sequence number for @device.
261 * Returns: A sequence number.
264 g_udev_device_get_seqnum (GUdevDevice *device)
266 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
267 return udev_device_get_seqnum (device->priv->udevice);
271 * g_udev_device_get_device_type:
272 * @device: A #GUdevDevice.
274 * Gets the type of the device file, if any, for @device.
276 * Returns: The device number for @device or #G_UDEV_DEVICE_TYPE_NONE if the device does not have a device file.
279 g_udev_device_get_device_type (GUdevDevice *device)
281 struct stat stat_buf;
282 const gchar *device_file;
283 GUdevDeviceType type;
285 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), G_UDEV_DEVICE_TYPE_NONE);
287 type = G_UDEV_DEVICE_TYPE_NONE;
289 /* TODO: would be better to have support for this in libudev... */
291 device_file = g_udev_device_get_device_file (device);
292 if (device_file == NULL)
295 if (stat (device_file, &stat_buf) != 0)
298 if (S_ISBLK (stat_buf.st_mode))
299 type = G_UDEV_DEVICE_TYPE_BLOCK;
300 else if (S_ISCHR (stat_buf.st_mode))
301 type = G_UDEV_DEVICE_TYPE_CHAR;
308 * g_udev_device_get_device_number:
309 * @device: A #GUdevDevice.
311 * Gets the device number, if any, for @device.
313 * Returns: The device number for @device or 0 if unknown.
316 g_udev_device_get_device_number (GUdevDevice *device)
318 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
319 return udev_device_get_devnum (device->priv->udevice);
323 * g_udev_device_get_device_file:
324 * @device: A #GUdevDevice.
326 * Gets the device file for @device.
328 * Returns: The device file for @device or %NULL if no device file
332 g_udev_device_get_device_file (GUdevDevice *device)
334 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
335 return udev_device_get_devnode (device->priv->udevice);
339 * g_udev_device_get_device_file_symlinks:
340 * @device: A #GUdevDevice.
342 * Gets a list of symlinks (in <literal>/dev</literal>) that points to
343 * the device file for @device.
345 * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): A %NULL terminated string array of symlinks. This array is owned by @device and should not be freed by the caller.
347 const gchar * const *
348 g_udev_device_get_device_file_symlinks (GUdevDevice *device)
350 struct udev_list_entry *l;
353 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
355 if (device->priv->device_file_symlinks != NULL)
358 p = g_ptr_array_new ();
359 for (l = udev_device_get_devlinks_list_entry (device->priv->udevice); l != NULL; l = udev_list_entry_get_next (l))
361 g_ptr_array_add (p, g_strdup (udev_list_entry_get_name (l)));
363 g_ptr_array_add (p, NULL);
364 device->priv->device_file_symlinks = (gchar **) g_ptr_array_free (p, FALSE);
367 return (const gchar * const *) device->priv->device_file_symlinks;
370 /* ---------------------------------------------------------------------------------------------------- */
373 * g_udev_device_get_parent:
374 * @device: A #GUdevDevice.
376 * Gets the immediate parent of @device, if any.
378 * Returns: (transfer full): A #GUdevDevice or %NULL if @device has no parent. Free with g_object_unref().
381 g_udev_device_get_parent (GUdevDevice *device)
384 struct udev_device *udevice;
386 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
390 udevice = udev_device_get_parent (device->priv->udevice);
394 ret = _g_udev_device_new (udevice);
401 * g_udev_device_get_parent_with_subsystem:
402 * @device: A #GUdevDevice.
403 * @subsystem: The subsystem of the parent to get.
404 * @devtype: (allow-none): The devtype of the parent to get or %NULL.
406 * Walks up the chain of parents of @device and returns the first
407 * device encountered where @subsystem and @devtype matches, if any.
409 * Returns: (transfer full): A #GUdevDevice or %NULL if @device has no parent with @subsystem and @devtype. Free with g_object_unref().
412 g_udev_device_get_parent_with_subsystem (GUdevDevice *device,
413 const gchar *subsystem,
414 const gchar *devtype)
417 struct udev_device *udevice;
419 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
420 g_return_val_if_fail (subsystem != NULL, NULL);
424 udevice = udev_device_get_parent_with_subsystem_devtype (device->priv->udevice,
430 ret = _g_udev_device_new (udevice);
436 /* ---------------------------------------------------------------------------------------------------- */
439 * g_udev_device_get_property_keys:
440 * @device: A #GUdevDevice.
442 * Gets all keys for properties on @device.
444 * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): A %NULL terminated string array of property keys. This array is owned by @device and should not be freed by the caller.
447 g_udev_device_get_property_keys (GUdevDevice *device)
449 struct udev_list_entry *l;
452 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
454 if (device->priv->property_keys != NULL)
457 p = g_ptr_array_new ();
458 for (l = udev_device_get_properties_list_entry (device->priv->udevice); l != NULL; l = udev_list_entry_get_next (l))
460 g_ptr_array_add (p, g_strdup (udev_list_entry_get_name (l)));
462 g_ptr_array_add (p, NULL);
463 device->priv->property_keys = (gchar **) g_ptr_array_free (p, FALSE);
466 return (const gchar * const *) device->priv->property_keys;
471 * g_udev_device_has_property:
472 * @device: A #GUdevDevice.
473 * @key: Name of property.
475 * Check if a the property with the given key exists.
477 * Returns: %TRUE only if the value for @key exist.
480 g_udev_device_has_property (GUdevDevice *device,
483 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
484 g_return_val_if_fail (key != NULL, FALSE);
485 return udev_device_get_property_value (device->priv->udevice, key) != NULL;
489 * g_udev_device_get_property:
490 * @device: A #GUdevDevice.
491 * @key: Name of property.
493 * Look up the value for @key on @device.
495 * Returns: The value for @key or %NULL if @key doesn't exist on @device. Do not free this string, it is owned by @device.
498 g_udev_device_get_property (GUdevDevice *device,
501 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
502 g_return_val_if_fail (key != NULL, NULL);
503 return udev_device_get_property_value (device->priv->udevice, key);
507 * g_udev_device_get_property_as_int:
508 * @device: A #GUdevDevice.
509 * @key: Name of property.
511 * Look up the value for @key on @device and convert it to an integer
514 * Returns: The value for @key or 0 if @key doesn't exist or
518 g_udev_device_get_property_as_int (GUdevDevice *device,
524 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
525 g_return_val_if_fail (key != NULL, 0);
528 s = g_udev_device_get_property (device, key);
532 result = strtol (s, NULL, 0);
538 * g_udev_device_get_property_as_uint64:
539 * @device: A #GUdevDevice.
540 * @key: Name of property.
542 * Look up the value for @key on @device and convert it to an unsigned
543 * 64-bit integer using g_ascii_strtoull().
545 * Returns: The value for @key or 0 if @key doesn't exist or isn't a
549 g_udev_device_get_property_as_uint64 (GUdevDevice *device,
555 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
556 g_return_val_if_fail (key != NULL, 0);
559 s = g_udev_device_get_property (device, key);
563 result = g_ascii_strtoull (s, NULL, 0);
569 * g_udev_device_get_property_as_double:
570 * @device: A #GUdevDevice.
571 * @key: Name of property.
573 * Look up the value for @key on @device and convert it to a double
574 * precision floating point number using strtod().
576 * Returns: The value for @key or 0.0 if @key doesn't exist or isn't a
580 g_udev_device_get_property_as_double (GUdevDevice *device,
586 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0.0);
587 g_return_val_if_fail (key != NULL, 0.0);
590 s = g_udev_device_get_property (device, key);
594 result = strtod (s, NULL);
600 * g_udev_device_get_property_as_boolean:
601 * @device: A #GUdevDevice.
602 * @key: Name of property.
604 * Look up the value for @key on @device and convert it to an
605 * boolean. This is done by doing a case-insensitive string comparison
606 * on the string value against "1" and "true".
608 * Returns: The value for @key or %FALSE if @key doesn't exist or
612 g_udev_device_get_property_as_boolean (GUdevDevice *device,
618 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
619 g_return_val_if_fail (key != NULL, FALSE);
622 s = g_udev_device_get_property (device, key);
626 if (strcmp (s, "1") == 0 || g_ascii_strcasecmp (s, "true") == 0)
633 split_at_whitespace (const gchar *s)
639 result = g_strsplit_set (s, " \v\t\r\n", 0);
641 /* remove empty strings, thanks GLib */
642 for (n = 0; result[n] != NULL; n++)
644 if (strlen (result[n]) == 0)
647 for (m = n; result[m] != NULL; m++)
648 result[m] = result[m + 1];
657 * g_udev_device_get_property_as_strv:
658 * @device: A #GUdevDevice.
659 * @key: Name of property.
661 * Look up the value for @key on @device and return the result of
662 * splitting it into non-empty tokens split at white space (only space
663 * (' '), form-feed ('\f'), newline ('\n'), carriage return ('\r'),
664 * horizontal tab ('\t'), and vertical tab ('\v') are considered; the
665 * locale is not taken into account).
667 * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): The value of @key on @device split into tokens or %NULL if @key doesn't exist. This array is owned by @device and should not be freed by the caller.
670 g_udev_device_get_property_as_strv (GUdevDevice *device,
676 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
677 g_return_val_if_fail (key != NULL, NULL);
679 if (device->priv->prop_strvs != NULL)
681 result = g_hash_table_lookup (device->priv->prop_strvs, key);
687 s = g_udev_device_get_property (device, key);
691 result = split_at_whitespace (s);
695 if (device->priv->prop_strvs == NULL)
696 device->priv->prop_strvs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_strfreev);
697 g_hash_table_insert (device->priv->prop_strvs, g_strdup (key), result);
700 return (const gchar* const *) result;
703 /* ---------------------------------------------------------------------------------------------------- */
706 * g_udev_device_get_sysfs_attr_keys:
707 * @device: A #GUdevDevice.
709 * Gets all keys for sysfs attributes on @device.
711 * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): A %NULL terminated string array of sysfs attribute keys. This array is owned by @device and should not be freed by the caller.
713 const gchar * const *
714 g_udev_device_get_sysfs_attr_keys (GUdevDevice *device)
716 struct udev_list_entry *l;
719 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
721 if (device->priv->sysfs_attr_keys != NULL)
724 p = g_ptr_array_new ();
725 for (l = udev_device_get_sysattr_list_entry (device->priv->udevice); l != NULL; l = udev_list_entry_get_next (l))
727 g_ptr_array_add (p, g_strdup (udev_list_entry_get_name (l)));
729 g_ptr_array_add (p, NULL);
730 device->priv->sysfs_attr_keys = (gchar **) g_ptr_array_free (p, FALSE);
733 return (const gchar * const *) device->priv->sysfs_attr_keys;
737 * g_udev_device_has_sysfs_attr:
738 * @device: A #GUdevDevice.
739 * @key: Name of sysfs attribute.
741 * Check if a the sysfs attribute with the given key exists.
743 * Returns: %TRUE only if the value for @key exist.
746 g_udev_device_has_sysfs_attr (GUdevDevice *device,
749 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
750 g_return_val_if_fail (key != NULL, FALSE);
751 return udev_device_get_sysattr_value (device->priv->udevice, key) != NULL;
755 * g_udev_device_get_sysfs_attr:
756 * @device: A #GUdevDevice.
757 * @name: Name of the sysfs attribute.
759 * Look up the sysfs attribute with @name on @device.
761 * Returns: The value of the sysfs attribute or %NULL if there is no
762 * such attribute. Do not free this string, it is owned by @device.
765 g_udev_device_get_sysfs_attr (GUdevDevice *device,
768 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
769 g_return_val_if_fail (name != NULL, NULL);
770 return udev_device_get_sysattr_value (device->priv->udevice, name);
774 * g_udev_device_get_sysfs_attr_as_int:
775 * @device: A #GUdevDevice.
776 * @name: Name of the sysfs attribute.
778 * Look up the sysfs attribute with @name on @device and convert it to an integer
781 * Returns: The value of the sysfs attribute or 0 if there is no such
785 g_udev_device_get_sysfs_attr_as_int (GUdevDevice *device,
791 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
792 g_return_val_if_fail (name != NULL, 0);
795 s = g_udev_device_get_sysfs_attr (device, name);
799 result = strtol (s, NULL, 0);
805 * g_udev_device_get_sysfs_attr_as_uint64:
806 * @device: A #GUdevDevice.
807 * @name: Name of the sysfs attribute.
809 * Look up the sysfs attribute with @name on @device and convert it to an unsigned
810 * 64-bit integer using g_ascii_strtoull().
812 * Returns: The value of the sysfs attribute or 0 if there is no such
816 g_udev_device_get_sysfs_attr_as_uint64 (GUdevDevice *device,
822 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
823 g_return_val_if_fail (name != NULL, 0);
826 s = g_udev_device_get_sysfs_attr (device, name);
830 result = g_ascii_strtoull (s, NULL, 0);
836 * g_udev_device_get_sysfs_attr_as_double:
837 * @device: A #GUdevDevice.
838 * @name: Name of the sysfs attribute.
840 * Look up the sysfs attribute with @name on @device and convert it to a double
841 * precision floating point number using strtod().
843 * Returns: The value of the sysfs attribute or 0.0 if there is no such
847 g_udev_device_get_sysfs_attr_as_double (GUdevDevice *device,
853 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0.0);
854 g_return_val_if_fail (name != NULL, 0.0);
857 s = g_udev_device_get_sysfs_attr (device, name);
861 result = strtod (s, NULL);
867 * g_udev_device_get_sysfs_attr_as_boolean:
868 * @device: A #GUdevDevice.
869 * @name: Name of the sysfs attribute.
871 * Look up the sysfs attribute with @name on @device and convert it to an
872 * boolean. This is done by doing a case-insensitive string comparison
873 * on the string value against "1" and "true".
875 * Returns: The value of the sysfs attribute or %FALSE if there is no such
879 g_udev_device_get_sysfs_attr_as_boolean (GUdevDevice *device,
885 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
886 g_return_val_if_fail (name != NULL, FALSE);
889 s = g_udev_device_get_sysfs_attr (device, name);
893 if (strcmp (s, "1") == 0 || g_ascii_strcasecmp (s, "true") == 0)
900 * g_udev_device_get_sysfs_attr_as_strv:
901 * @device: A #GUdevDevice.
902 * @name: Name of the sysfs attribute.
904 * Look up the sysfs attribute with @name on @device and return the result of
905 * splitting it into non-empty tokens split at white space (only space (' '),
906 * form-feed ('\f'), newline ('\n'), carriage return ('\r'), horizontal
907 * tab ('\t'), and vertical tab ('\v') are considered; the locale is
908 * not taken into account).
910 * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): The value of the sysfs attribute split into tokens or %NULL if there is no such attribute. This array is owned by @device and should not be freed by the caller.
912 const gchar * const *
913 g_udev_device_get_sysfs_attr_as_strv (GUdevDevice *device,
919 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
920 g_return_val_if_fail (name != NULL, NULL);
922 if (device->priv->sysfs_attr_strvs != NULL)
924 result = g_hash_table_lookup (device->priv->sysfs_attr_strvs, name);
930 s = g_udev_device_get_sysfs_attr (device, name);
934 result = split_at_whitespace (s);
938 if (device->priv->sysfs_attr_strvs == NULL)
939 device->priv->sysfs_attr_strvs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_strfreev);
940 g_hash_table_insert (device->priv->sysfs_attr_strvs, g_strdup (name), result);
943 return (const gchar* const *) result;
947 * g_udev_device_get_tags:
948 * @device: A #GUdevDevice.
950 * Gets all tags for @device.
952 * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): A %NULL terminated string array of tags. This array is owned by @device and should not be freed by the caller.
957 g_udev_device_get_tags (GUdevDevice *device)
959 struct udev_list_entry *l;
962 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
964 if (device->priv->tags != NULL)
967 p = g_ptr_array_new ();
968 for (l = udev_device_get_tags_list_entry (device->priv->udevice); l != NULL; l = udev_list_entry_get_next (l))
970 g_ptr_array_add (p, g_strdup (udev_list_entry_get_name (l)));
972 g_ptr_array_add (p, NULL);
973 device->priv->tags = (gchar **) g_ptr_array_free (p, FALSE);
976 return (const gchar * const *) device->priv->tags;
980 * g_udev_device_get_is_initialized:
981 * @device: A #GUdevDevice.
983 * Gets whether @device has been initalized.
985 * Returns: Whether @device has been initialized.
990 g_udev_device_get_is_initialized (GUdevDevice *device)
992 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
993 return udev_device_get_is_initialized (device->priv->udevice);
997 * g_udev_device_get_usec_since_initialized:
998 * @device: A #GUdevDevice.
1000 * Gets number of micro-seconds since @device was initialized.
1002 * This only works for devices with properties in the udev
1003 * database. All other devices return 0.
1005 * Returns: Number of micro-seconds since @device was initialized or 0 if unknown.
1010 g_udev_device_get_usec_since_initialized (GUdevDevice *device)
1012 g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
1013 return udev_device_get_usec_since_initialized (device->priv->udevice);