1 /* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
3 * Copyright (C) 2008-2010 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 Lesser 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 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
29 #include "gudevclient.h"
30 #include "gudevenumerator.h"
31 #include "gudevdevice.h"
32 #include "gudevmarshal.h"
33 #include "gudevprivate.h"
36 * SECTION:gudevenumerator
37 * @short_description: Lookup and sort devices
39 * #GUdevEnumerator is used to lookup and sort devices.
44 struct _GUdevEnumeratorPrivate
47 struct udev_enumerate *e;
56 G_DEFINE_TYPE (GUdevEnumerator, g_udev_enumerator, G_TYPE_OBJECT)
58 /* ---------------------------------------------------------------------------------------------------- */
61 g_udev_enumerator_finalize (GObject *object)
63 GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object);
65 if (enumerator->priv->client != NULL)
67 g_object_unref (enumerator->priv->client);
68 enumerator->priv->client = NULL;
71 if (enumerator->priv->e != NULL)
73 udev_enumerate_unref (enumerator->priv->e);
74 enumerator->priv->e = NULL;
77 if (G_OBJECT_CLASS (g_udev_enumerator_parent_class)->finalize != NULL)
78 G_OBJECT_CLASS (g_udev_enumerator_parent_class)->finalize (object);
82 g_udev_enumerator_set_property (GObject *object,
87 GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object);
92 if (enumerator->priv->client != NULL)
93 g_object_unref (enumerator->priv->client);
94 enumerator->priv->client = g_value_dup_object (value);
98 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
104 g_udev_enumerator_get_property (GObject *object,
109 GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object);
114 g_value_set_object (value, enumerator->priv->client);
118 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
124 g_udev_enumerator_constructed (GObject *object)
126 GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object);
128 g_assert (G_UDEV_IS_CLIENT (enumerator->priv->client));
130 enumerator->priv->e = udev_enumerate_new (_g_udev_client_get_udev (enumerator->priv->client));
132 if (G_OBJECT_CLASS (g_udev_enumerator_parent_class)->constructed != NULL)
133 G_OBJECT_CLASS (g_udev_enumerator_parent_class)->constructed (object);
137 g_udev_enumerator_class_init (GUdevEnumeratorClass *klass)
139 GObjectClass *gobject_class = (GObjectClass *) klass;
141 gobject_class->finalize = g_udev_enumerator_finalize;
142 gobject_class->set_property = g_udev_enumerator_set_property;
143 gobject_class->get_property = g_udev_enumerator_get_property;
144 gobject_class->constructed = g_udev_enumerator_constructed;
147 * GUdevEnumerator:client:
149 * The #GUdevClient to enumerate devices from.
153 g_object_class_install_property (gobject_class,
155 g_param_spec_object ("client",
156 "The client to enumerate devices from",
157 "The client to enumerate devices from",
159 G_PARAM_CONSTRUCT_ONLY |
162 g_type_class_add_private (klass, sizeof (GUdevEnumeratorPrivate));
166 g_udev_enumerator_init (GUdevEnumerator *enumerator)
168 enumerator->priv = G_TYPE_INSTANCE_GET_PRIVATE (enumerator,
169 G_UDEV_TYPE_ENUMERATOR,
170 GUdevEnumeratorPrivate);
174 * g_udev_enumerator_new:
175 * @client: A #GUdevClient to enumerate devices from.
177 * Constructs a #GUdevEnumerator object that can be used to enumerate
178 * and sort devices. Use the add_match_*() and add_nomatch_*() methods
179 * and execute the query to get a list of devices with
180 * g_udev_enumerator_execute().
182 * Returns: A new #GUdevEnumerator object. Free with g_object_unref().
187 g_udev_enumerator_new (GUdevClient *client)
189 g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
190 return G_UDEV_ENUMERATOR (g_object_new (G_UDEV_TYPE_ENUMERATOR, "client", client, NULL));
195 * g_udev_enumerator_add_match_subsystem:
196 * @enumerator: A #GUdevEnumerator.
197 * @subsystem: Wildcard for subsystem name e.g. 'scsi' or 'a*'.
199 * All returned devices will match the given @subsystem.
201 * Returns: (transfer none): The passed in @enumerator.
206 g_udev_enumerator_add_match_subsystem (GUdevEnumerator *enumerator,
207 const gchar *subsystem)
209 g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
210 g_return_val_if_fail (subsystem != NULL, NULL);
211 udev_enumerate_add_match_subsystem (enumerator->priv->e, subsystem);
216 * g_udev_enumerator_add_nomatch_subsystem:
217 * @enumerator: A #GUdevEnumerator.
218 * @subsystem: Wildcard for subsystem name e.g. 'scsi' or 'a*'.
220 * All returned devices will not match the given @subsystem.
222 * Returns: (transfer none): The passed in @enumerator.
227 g_udev_enumerator_add_nomatch_subsystem (GUdevEnumerator *enumerator,
228 const gchar *subsystem)
230 g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
231 g_return_val_if_fail (subsystem != NULL, NULL);
232 udev_enumerate_add_nomatch_subsystem (enumerator->priv->e, subsystem);
237 * g_udev_enumerator_add_match_sysfs_attr:
238 * @enumerator: A #GUdevEnumerator.
239 * @name: Wildcard filter for sysfs attribute key.
240 * @value: Wildcard filter for sysfs attribute value.
242 * All returned devices will have a sysfs attribute matching the given @name and @value.
244 * Returns: (transfer none): The passed in @enumerator.
249 g_udev_enumerator_add_match_sysfs_attr (GUdevEnumerator *enumerator,
253 g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
254 g_return_val_if_fail (name != NULL, NULL);
255 g_return_val_if_fail (value != NULL, NULL);
256 udev_enumerate_add_match_sysattr (enumerator->priv->e, name, value);
261 * g_udev_enumerator_add_nomatch_sysfs_attr:
262 * @enumerator: A #GUdevEnumerator.
263 * @name: Wildcard filter for sysfs attribute key.
264 * @value: Wildcard filter for sysfs attribute value.
266 * All returned devices will not have a sysfs attribute matching the given @name and @value.
268 * Returns: (transfer none): The passed in @enumerator.
273 g_udev_enumerator_add_nomatch_sysfs_attr (GUdevEnumerator *enumerator,
277 g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
278 g_return_val_if_fail (name != NULL, NULL);
279 g_return_val_if_fail (value != NULL, NULL);
280 udev_enumerate_add_nomatch_sysattr (enumerator->priv->e, name, value);
285 * g_udev_enumerator_add_match_property:
286 * @enumerator: A #GUdevEnumerator.
287 * @name: Wildcard filter for property name.
288 * @value: Wildcard filter for property value.
290 * All returned devices will have a property matching the given @name and @value.
292 * Returns: (transfer none): The passed in @enumerator.
297 g_udev_enumerator_add_match_property (GUdevEnumerator *enumerator,
301 g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
302 g_return_val_if_fail (name != NULL, NULL);
303 g_return_val_if_fail (value != NULL, NULL);
304 udev_enumerate_add_match_property (enumerator->priv->e, name, value);
309 * g_udev_enumerator_add_match_name:
310 * @enumerator: A #GUdevEnumerator.
311 * @name: Wildcard filter for kernel name e.g. "sda*".
313 * All returned devices will match the given @name.
315 * Returns: (transfer none): The passed in @enumerator.
320 g_udev_enumerator_add_match_name (GUdevEnumerator *enumerator,
323 g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
324 g_return_val_if_fail (name != NULL, NULL);
325 udev_enumerate_add_match_sysname (enumerator->priv->e, name);
330 * g_udev_enumerator_add_sysfs_path:
331 * @enumerator: A #GUdevEnumerator.
332 * @sysfs_path: A sysfs path, e.g. "/sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda"
334 * Add a device to the list of devices, to retrieve it back sorted in dependency order.
336 * Returns: (transfer none): The passed in @enumerator.
341 g_udev_enumerator_add_sysfs_path (GUdevEnumerator *enumerator,
342 const gchar *sysfs_path)
344 g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
345 g_return_val_if_fail (sysfs_path != NULL, NULL);
346 udev_enumerate_add_syspath (enumerator->priv->e, sysfs_path);
351 * g_udev_enumerator_add_match_tag:
352 * @enumerator: A #GUdevEnumerator.
353 * @tag: A udev tag e.g. "udev-acl".
355 * All returned devices will match the given @tag.
357 * Returns: (transfer none): The passed in @enumerator.
362 g_udev_enumerator_add_match_tag (GUdevEnumerator *enumerator,
365 g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
366 g_return_val_if_fail (tag != NULL, NULL);
367 udev_enumerate_add_match_tag (enumerator->priv->e, tag);
372 * g_udev_enumerator_add_match_is_initialized:
373 * @enumerator: A #GUdevEnumerator.
375 * All returned devices will be initialized.
377 * Returns: (transfer none): The passed in @enumerator.
382 g_udev_enumerator_add_match_is_initialized (GUdevEnumerator *enumerator)
384 g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
385 udev_enumerate_add_match_is_initialized (enumerator->priv->e);
390 * g_udev_enumerator_execute:
391 * @enumerator: A #GUdevEnumerator.
393 * Executes the query in @enumerator.
395 * Returns: (element-type GUdevDevice) (transfer full): A list of #GUdevDevice objects. The caller should free the result by using g_object_unref() on each element in the list and then g_list_free() on the list.
400 g_udev_enumerator_execute (GUdevEnumerator *enumerator)
403 struct udev_list_entry *l, *devices;
405 g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
409 /* retrieve the list */
410 udev_enumerate_scan_devices (enumerator->priv->e);
412 devices = udev_enumerate_get_list_entry (enumerator->priv->e);
413 for (l = devices; l != NULL; l = udev_list_entry_get_next (l))
415 struct udev_device *udevice;
418 udevice = udev_device_new_from_syspath (udev_enumerate_get_udev (enumerator->priv->e),
419 udev_list_entry_get_name (l));
423 device = _g_udev_device_new (udevice);
424 udev_device_unref (udevice);
425 ret = g_list_prepend (ret, device);
428 ret = g_list_reverse (ret);