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 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 "gudevclient.h"
28 #include "gudevenumerator.h"
29 #include "gudevdevice.h"
30 #include "gudevmarshal.h"
31 #include "gudevprivate.h"
34 * SECTION:gudevenumerator
35 * @short_description: Lookup and sort devices
37 * #GUdevEnumerator is used to lookup and sort devices.
42 struct _GUdevEnumeratorPrivate
45 struct udev_enumerate *e;
54 G_DEFINE_TYPE (GUdevEnumerator, g_udev_enumerator, G_TYPE_OBJECT)
56 /* ---------------------------------------------------------------------------------------------------- */
59 g_udev_enumerator_finalize (GObject *object)
61 GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object);
63 if (enumerator->priv->client != NULL)
65 g_object_unref (enumerator->priv->client);
66 enumerator->priv->client = NULL;
69 if (enumerator->priv->e != NULL)
71 udev_enumerate_unref (enumerator->priv->e);
72 enumerator->priv->e = NULL;
75 if (G_OBJECT_CLASS (g_udev_enumerator_parent_class)->finalize != NULL)
76 G_OBJECT_CLASS (g_udev_enumerator_parent_class)->finalize (object);
80 g_udev_enumerator_set_property (GObject *object,
85 GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object);
90 if (enumerator->priv->client != NULL)
91 g_object_unref (enumerator->priv->client);
92 enumerator->priv->client = g_value_dup_object (value);
96 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
102 g_udev_enumerator_get_property (GObject *object,
107 GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object);
112 g_value_set_object (value, enumerator->priv->client);
116 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
122 g_udev_enumerator_constructed (GObject *object)
124 GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object);
126 g_assert (G_UDEV_IS_CLIENT (enumerator->priv->client));
128 enumerator->priv->e = udev_enumerate_new (_g_udev_client_get_udev (enumerator->priv->client));
130 if (G_OBJECT_CLASS (g_udev_enumerator_parent_class)->constructed != NULL)
131 G_OBJECT_CLASS (g_udev_enumerator_parent_class)->constructed (object);
135 g_udev_enumerator_class_init (GUdevEnumeratorClass *klass)
137 GObjectClass *gobject_class = (GObjectClass *) klass;
139 gobject_class->finalize = g_udev_enumerator_finalize;
140 gobject_class->set_property = g_udev_enumerator_set_property;
141 gobject_class->get_property = g_udev_enumerator_get_property;
142 gobject_class->constructed = g_udev_enumerator_constructed;
145 * GUdevEnumerator:client:
147 * The #GUdevClient to enumerate devices from.
151 g_object_class_install_property (gobject_class,
153 g_param_spec_object ("client",
154 "The client to enumerate devices from",
155 "The client to enumerate devices from",
157 G_PARAM_CONSTRUCT_ONLY |
160 g_type_class_add_private (klass, sizeof (GUdevEnumeratorPrivate));
164 g_udev_enumerator_init (GUdevEnumerator *enumerator)
166 enumerator->priv = G_TYPE_INSTANCE_GET_PRIVATE (enumerator,
167 G_UDEV_TYPE_ENUMERATOR,
168 GUdevEnumeratorPrivate);
172 * g_udev_enumerator_new:
173 * @client: A #GUdevClient to enumerate devices from.
175 * Constructs a #GUdevEnumerator object that can be used to enumerate
176 * and sort devices. Use the add_match_*() and add_nomatch_*() methods
177 * and execute the query to get a list of devices with
178 * g_udev_enumerator_execute().
180 * Returns: A new #GUdevEnumerator object. Free with g_object_unref().
185 g_udev_enumerator_new (GUdevClient *client)
187 g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
188 return G_UDEV_ENUMERATOR (g_object_new (G_UDEV_TYPE_ENUMERATOR, "client", client, NULL));
193 * g_udev_enumerator_add_match_subsystem:
194 * @enumerator: A #GUdevEnumerator.
195 * @subsystem: Wildcard for subsystem name e.g. 'scsi' or 'a*'.
197 * All returned devices will match the given @subsystem.
199 * Returns: (transfer none): The passed in @enumerator.
204 g_udev_enumerator_add_match_subsystem (GUdevEnumerator *enumerator,
205 const gchar *subsystem)
207 g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
208 g_return_val_if_fail (subsystem != NULL, NULL);
209 udev_enumerate_add_match_subsystem (enumerator->priv->e, subsystem);
214 * g_udev_enumerator_add_nomatch_subsystem:
215 * @enumerator: A #GUdevEnumerator.
216 * @subsystem: Wildcard for subsystem name e.g. 'scsi' or 'a*'.
218 * All returned devices will not match the given @subsystem.
220 * Returns: (transfer none): The passed in @enumerator.
225 g_udev_enumerator_add_nomatch_subsystem (GUdevEnumerator *enumerator,
226 const gchar *subsystem)
228 g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
229 g_return_val_if_fail (subsystem != NULL, NULL);
230 udev_enumerate_add_nomatch_subsystem (enumerator->priv->e, subsystem);
235 * g_udev_enumerator_add_match_sysfs_attr:
236 * @enumerator: A #GUdevEnumerator.
237 * @name: Wildcard filter for sysfs attribute key.
238 * @value: Wildcard filter for sysfs attribute value.
240 * All returned devices will have a sysfs attribute matching the given @name and @value.
242 * Returns: (transfer none): The passed in @enumerator.
247 g_udev_enumerator_add_match_sysfs_attr (GUdevEnumerator *enumerator,
251 g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
252 g_return_val_if_fail (name != NULL, NULL);
253 g_return_val_if_fail (value != NULL, NULL);
254 udev_enumerate_add_match_sysattr (enumerator->priv->e, name, value);
259 * g_udev_enumerator_add_nomatch_sysfs_attr:
260 * @enumerator: A #GUdevEnumerator.
261 * @name: Wildcard filter for sysfs attribute key.
262 * @value: Wildcard filter for sysfs attribute value.
264 * All returned devices will not have a sysfs attribute matching the given @name and @value.
266 * Returns: (transfer none): The passed in @enumerator.
271 g_udev_enumerator_add_nomatch_sysfs_attr (GUdevEnumerator *enumerator,
275 g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
276 g_return_val_if_fail (name != NULL, NULL);
277 g_return_val_if_fail (value != NULL, NULL);
278 udev_enumerate_add_nomatch_sysattr (enumerator->priv->e, name, value);
283 * g_udev_enumerator_add_match_property:
284 * @enumerator: A #GUdevEnumerator.
285 * @name: Wildcard filter for property name.
286 * @value: Wildcard filter for property value.
288 * All returned devices will have a property matching the given @name and @value.
290 * Returns: (transfer none): The passed in @enumerator.
295 g_udev_enumerator_add_match_property (GUdevEnumerator *enumerator,
299 g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
300 g_return_val_if_fail (name != NULL, NULL);
301 g_return_val_if_fail (value != NULL, NULL);
302 udev_enumerate_add_match_property (enumerator->priv->e, name, value);
307 * g_udev_enumerator_add_match_name:
308 * @enumerator: A #GUdevEnumerator.
309 * @name: Wildcard filter for kernel name e.g. "sda*".
311 * All returned devices will match the given @name.
313 * Returns: (transfer none): The passed in @enumerator.
318 g_udev_enumerator_add_match_name (GUdevEnumerator *enumerator,
321 g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
322 g_return_val_if_fail (name != NULL, NULL);
323 udev_enumerate_add_match_sysname (enumerator->priv->e, name);
328 * g_udev_enumerator_add_sysfs_path:
329 * @enumerator: A #GUdevEnumerator.
330 * @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"
332 * Add a device to the list of devices, to retrieve it back sorted in dependency order.
334 * Returns: (transfer none): The passed in @enumerator.
339 g_udev_enumerator_add_sysfs_path (GUdevEnumerator *enumerator,
340 const gchar *sysfs_path)
342 g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
343 g_return_val_if_fail (sysfs_path != NULL, NULL);
344 udev_enumerate_add_syspath (enumerator->priv->e, sysfs_path);
349 * g_udev_enumerator_add_match_tag:
350 * @enumerator: A #GUdevEnumerator.
351 * @tag: A udev tag e.g. "udev-acl".
353 * All returned devices will match the given @tag.
355 * Returns: (transfer none): The passed in @enumerator.
360 g_udev_enumerator_add_match_tag (GUdevEnumerator *enumerator,
363 g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
364 g_return_val_if_fail (tag != NULL, NULL);
365 udev_enumerate_add_match_tag (enumerator->priv->e, tag);
370 * g_udev_enumerator_add_match_is_initialized:
371 * @enumerator: A #GUdevEnumerator.
373 * All returned devices will be initialized.
375 * Returns: (transfer none): The passed in @enumerator.
380 g_udev_enumerator_add_match_is_initialized (GUdevEnumerator *enumerator)
382 g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
383 udev_enumerate_add_match_is_initialized (enumerator->priv->e);
388 * g_udev_enumerator_execute:
389 * @enumerator: A #GUdevEnumerator.
391 * Executes the query in @enumerator.
393 * 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.
398 g_udev_enumerator_execute (GUdevEnumerator *enumerator)
401 struct udev_list_entry *l, *devices;
403 g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
407 /* retrieve the list */
408 udev_enumerate_scan_devices (enumerator->priv->e);
410 devices = udev_enumerate_get_list_entry (enumerator->priv->e);
411 for (l = devices; l != NULL; l = udev_list_entry_get_next (l))
413 struct udev_device *udevice;
416 udevice = udev_device_new_from_syspath (udev_enumerate_get_udev (enumerator->priv->e),
417 udev_list_entry_get_name (l));
421 device = _g_udev_device_new (udevice);
422 udev_device_unref (udevice);
423 ret = g_list_prepend (ret, device);
426 ret = g_list_reverse (ret);