Blame gudev/gudevclient.c

rpm-build 07bc2b
/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
rpm-build 07bc2b
 *
rpm-build 07bc2b
 * Copyright (C) 2008-2010 David Zeuthen <davidz@redhat.com>
rpm-build 07bc2b
 *
rpm-build 07bc2b
 * This library is free software; you can redistribute it and/or
rpm-build 07bc2b
 * modify it under the terms of the GNU Library General Public
rpm-build 07bc2b
 * License as published by the Free Software Foundation; either
rpm-build 07bc2b
 * version 2 of the License, or (at your option) any later version.
rpm-build 07bc2b
 *
rpm-build 07bc2b
 * This library is distributed in the hope that it will be useful,
rpm-build 07bc2b
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
rpm-build 07bc2b
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
rpm-build 07bc2b
 * Library General Public License for more details.
rpm-build 07bc2b
 *
rpm-build 07bc2b
 * You should have received a copy of the GNU Library General Public
rpm-build 07bc2b
 * License along with this library; if not, write to the Free Software
rpm-build 07bc2b
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
rpm-build 07bc2b
 */
rpm-build 07bc2b
rpm-build 07bc2b
#ifdef HAVE_CONFIG_H
rpm-build 07bc2b
#  include "config.h"
rpm-build 07bc2b
#endif
rpm-build 07bc2b
rpm-build 07bc2b
#include <stdlib.h>
rpm-build 07bc2b
#include <string.h>
rpm-build 07bc2b
#include <sys/stat.h>
rpm-build 07bc2b
rpm-build 07bc2b
#include "gudevclient.h"
rpm-build 07bc2b
#include "gudevdevice.h"
rpm-build 07bc2b
#include "gudevprivate.h"
rpm-build 07bc2b
rpm-build 07bc2b
/**
rpm-build 07bc2b
 * SECTION:gudevclient
rpm-build 07bc2b
 * @short_description: Query devices and listen to uevents
rpm-build 07bc2b
 *
rpm-build 07bc2b
 * #GUdevClient is used to query information about devices on a Linux
rpm-build 07bc2b
 * system from the Linux kernel and the udev device
rpm-build 07bc2b
 * manager.
rpm-build 07bc2b
 *
rpm-build 07bc2b
 * Device information is retrieved from the kernel (through the
rpm-build 07bc2b
 * <literal>sysfs</literal> filesystem) and the udev daemon (through a
rpm-build 07bc2b
 * <literal>tmpfs</literal> filesystem) and presented through
rpm-build 07bc2b
 * #GUdevDevice objects. This means that no blocking IO ever happens
rpm-build 07bc2b
 * (in both cases, we are essentially just reading data from kernel
rpm-build 07bc2b
 * memory) and as such there are no asynchronous versions of the
rpm-build 07bc2b
 * provided methods.
rpm-build 07bc2b
 *
rpm-build 07bc2b
 * To get #GUdevDevice objects, use
rpm-build 07bc2b
 * g_udev_client_query_by_subsystem(),
rpm-build 07bc2b
 * g_udev_client_query_by_device_number(),
rpm-build 07bc2b
 * g_udev_client_query_by_device_file(),
rpm-build 07bc2b
 * g_udev_client_query_by_sysfs_path(),
rpm-build 07bc2b
 * g_udev_client_query_by_subsystem_and_name()
rpm-build 07bc2b
 * or the #GUdevEnumerator type.
rpm-build 07bc2b
 *
rpm-build 07bc2b
 * To listen to uevents, connect to the #GUdevClient::uevent signal.
rpm-build 07bc2b
 */
rpm-build 07bc2b
rpm-build 07bc2b
struct _GUdevClientPrivate
rpm-build 07bc2b
{
rpm-build 07bc2b
  GSource *watch_source;
rpm-build 07bc2b
  struct udev *udev;
rpm-build 07bc2b
  struct udev_monitor *monitor;
rpm-build 07bc2b
rpm-build 07bc2b
  gchar **subsystems;
rpm-build 07bc2b
};
rpm-build 07bc2b
rpm-build 07bc2b
enum
rpm-build 07bc2b
{
rpm-build 07bc2b
  PROP_0,
rpm-build 07bc2b
  PROP_SUBSYSTEMS,
rpm-build 07bc2b
};
rpm-build 07bc2b
rpm-build 07bc2b
enum
rpm-build 07bc2b
{
rpm-build 07bc2b
  UEVENT_SIGNAL,
rpm-build 07bc2b
  LAST_SIGNAL,
rpm-build 07bc2b
};
rpm-build 07bc2b
rpm-build 07bc2b
static guint signals[LAST_SIGNAL] = { 0 };
rpm-build 07bc2b
rpm-build 07bc2b
G_DEFINE_TYPE (GUdevClient, g_udev_client, G_TYPE_OBJECT)
rpm-build 07bc2b
rpm-build 07bc2b
/* ---------------------------------------------------------------------------------------------------- */
rpm-build 07bc2b
rpm-build 07bc2b
static gboolean
rpm-build 07bc2b
monitor_event (GIOChannel *source,
rpm-build 07bc2b
               GIOCondition condition,
rpm-build 07bc2b
               gpointer data)
rpm-build 07bc2b
{
rpm-build 07bc2b
  GUdevClient *client = (GUdevClient *) data;
rpm-build 07bc2b
  GUdevDevice *device;
rpm-build 07bc2b
  struct udev_device *udevice;
rpm-build 07bc2b
rpm-build 07bc2b
  if (client->priv->monitor == NULL)
rpm-build 07bc2b
    goto out;
rpm-build 07bc2b
  udevice = udev_monitor_receive_device (client->priv->monitor);
rpm-build 07bc2b
  if (udevice == NULL)
rpm-build 07bc2b
    goto out;
rpm-build 07bc2b
rpm-build 07bc2b
  device = _g_udev_device_new (udevice);
rpm-build 07bc2b
  udev_device_unref (udevice);
rpm-build 07bc2b
  g_signal_emit (client,
rpm-build 07bc2b
                 signals[UEVENT_SIGNAL],
rpm-build 07bc2b
                 0,
rpm-build 07bc2b
                 g_udev_device_get_action (device),
rpm-build 07bc2b
                 device);
rpm-build 07bc2b
  g_object_unref (device);
rpm-build 07bc2b
rpm-build 07bc2b
 out:
rpm-build 07bc2b
  return TRUE;
rpm-build 07bc2b
}
rpm-build 07bc2b
rpm-build 07bc2b
static void
rpm-build 07bc2b
g_udev_client_finalize (GObject *object)
rpm-build 07bc2b
{
rpm-build 07bc2b
  GUdevClient *client = G_UDEV_CLIENT (object);
rpm-build 07bc2b
rpm-build 07bc2b
  if (client->priv->watch_source != NULL)
rpm-build 07bc2b
    {
rpm-build 07bc2b
      g_source_destroy (client->priv->watch_source);
rpm-build 07bc2b
      client->priv->watch_source = NULL;
rpm-build 07bc2b
    }
rpm-build 07bc2b
rpm-build 07bc2b
  if (client->priv->monitor != NULL)
rpm-build 07bc2b
    {
rpm-build 07bc2b
      udev_monitor_unref (client->priv->monitor);
rpm-build 07bc2b
      client->priv->monitor = NULL;
rpm-build 07bc2b
    }
rpm-build 07bc2b
rpm-build 07bc2b
  if (client->priv->udev != NULL)
rpm-build 07bc2b
    {
rpm-build 07bc2b
      udev_unref (client->priv->udev);
rpm-build 07bc2b
      client->priv->udev = NULL;
rpm-build 07bc2b
    }
rpm-build 07bc2b
rpm-build 07bc2b
  g_strfreev (client->priv->subsystems);
rpm-build 07bc2b
rpm-build 07bc2b
  if (G_OBJECT_CLASS (g_udev_client_parent_class)->finalize != NULL)
rpm-build 07bc2b
    G_OBJECT_CLASS (g_udev_client_parent_class)->finalize (object);
rpm-build 07bc2b
}
rpm-build 07bc2b
rpm-build 07bc2b
static void
rpm-build 07bc2b
g_udev_client_set_property (GObject      *object,
rpm-build 07bc2b
                            guint         prop_id,
rpm-build 07bc2b
                            const GValue *value,
rpm-build 07bc2b
                            GParamSpec   *pspec)
rpm-build 07bc2b
{
rpm-build 07bc2b
  GUdevClient *client = G_UDEV_CLIENT (object);
rpm-build 07bc2b
rpm-build 07bc2b
  switch (prop_id)
rpm-build 07bc2b
    {
rpm-build 07bc2b
    case PROP_SUBSYSTEMS:
rpm-build 07bc2b
      if (client->priv->subsystems != NULL)
rpm-build 07bc2b
        g_strfreev (client->priv->subsystems);
rpm-build 07bc2b
      client->priv->subsystems = g_strdupv (g_value_get_boxed (value));
rpm-build 07bc2b
      break;
rpm-build 07bc2b
rpm-build 07bc2b
    default:
rpm-build 07bc2b
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
rpm-build 07bc2b
      break;
rpm-build 07bc2b
    }
rpm-build 07bc2b
}
rpm-build 07bc2b
rpm-build 07bc2b
static void
rpm-build 07bc2b
g_udev_client_get_property (GObject     *object,
rpm-build 07bc2b
                            guint        prop_id,
rpm-build 07bc2b
                            GValue      *value,
rpm-build 07bc2b
                            GParamSpec  *pspec)
rpm-build 07bc2b
{
rpm-build 07bc2b
  GUdevClient *client = G_UDEV_CLIENT (object);
rpm-build 07bc2b
rpm-build 07bc2b
  switch (prop_id)
rpm-build 07bc2b
    {
rpm-build 07bc2b
    case PROP_SUBSYSTEMS:
rpm-build 07bc2b
      g_value_set_boxed (value, client->priv->subsystems);
rpm-build 07bc2b
      break;
rpm-build 07bc2b
rpm-build 07bc2b
    default:
rpm-build 07bc2b
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
rpm-build 07bc2b
      break;
rpm-build 07bc2b
    }
rpm-build 07bc2b
}
rpm-build 07bc2b
rpm-build 07bc2b
static void
rpm-build 07bc2b
g_udev_client_constructed (GObject *object)
rpm-build 07bc2b
{
rpm-build 07bc2b
  GUdevClient *client = G_UDEV_CLIENT (object);
rpm-build 07bc2b
  GIOChannel *channel;
rpm-build 07bc2b
  guint n;
rpm-build 07bc2b
rpm-build 07bc2b
  client->priv->udev = udev_new ();
rpm-build 07bc2b
rpm-build 07bc2b
  /* connect to event source */
rpm-build 07bc2b
  client->priv->monitor = udev_monitor_new_from_netlink (client->priv->udev, "udev");
rpm-build 07bc2b
rpm-build 07bc2b
  //g_debug ("ss = %p", client->priv->subsystems);
rpm-build 07bc2b
rpm-build 07bc2b
  if (client->priv->subsystems != NULL)
rpm-build 07bc2b
    {
rpm-build 07bc2b
      /* install subsystem filters to only wake up for certain events */
rpm-build 07bc2b
      for (n = 0; client->priv->subsystems[n] != NULL; n++)
rpm-build 07bc2b
        {
rpm-build 07bc2b
          gchar *subsystem;
rpm-build 07bc2b
          gchar *devtype;
rpm-build 07bc2b
          gchar *s;
rpm-build 07bc2b
rpm-build 07bc2b
          subsystem = g_strdup (client->priv->subsystems[n]);
rpm-build 07bc2b
          devtype = NULL;
rpm-build 07bc2b
rpm-build 07bc2b
          //g_debug ("s = '%s'", subsystem);
rpm-build 07bc2b
rpm-build 07bc2b
          s = strstr (subsystem, "/");
rpm-build 07bc2b
          if (s != NULL)
rpm-build 07bc2b
            {
rpm-build 07bc2b
              devtype = s + 1;
rpm-build 07bc2b
              *s = '\0';
rpm-build 07bc2b
            }
rpm-build 07bc2b
rpm-build 07bc2b
          if (client->priv->monitor != NULL)
rpm-build 07bc2b
              udev_monitor_filter_add_match_subsystem_devtype (client->priv->monitor, subsystem, devtype);
rpm-build 07bc2b
rpm-build 07bc2b
          g_free (subsystem);
rpm-build 07bc2b
        }
rpm-build 07bc2b
rpm-build 07bc2b
      /* listen to events, and buffer them */
rpm-build 07bc2b
      if (client->priv->monitor != NULL)
rpm-build 07bc2b
        {
rpm-build 07bc2b
          udev_monitor_enable_receiving (client->priv->monitor);
rpm-build 07bc2b
          channel = g_io_channel_unix_new (udev_monitor_get_fd (client->priv->monitor));
rpm-build 07bc2b
          client->priv->watch_source = g_io_create_watch (channel, G_IO_IN);
rpm-build 07bc2b
          g_io_channel_unref (channel);
rpm-build 07bc2b
          g_source_set_callback (client->priv->watch_source, (GSourceFunc) monitor_event, client, NULL);
rpm-build 07bc2b
          g_source_attach (client->priv->watch_source, g_main_context_get_thread_default ());
rpm-build 07bc2b
          g_source_unref (client->priv->watch_source);
rpm-build 07bc2b
        }
rpm-build 07bc2b
      else
rpm-build 07bc2b
        {
rpm-build 07bc2b
          client->priv->watch_source = NULL;
rpm-build 07bc2b
        }
rpm-build 07bc2b
    }
rpm-build 07bc2b
rpm-build 07bc2b
  if (G_OBJECT_CLASS (g_udev_client_parent_class)->constructed != NULL)
rpm-build 07bc2b
    G_OBJECT_CLASS (g_udev_client_parent_class)->constructed (object);
rpm-build 07bc2b
}
rpm-build 07bc2b
rpm-build 07bc2b
rpm-build 07bc2b
static void
rpm-build 07bc2b
g_udev_client_class_init (GUdevClientClass *klass)
rpm-build 07bc2b
{
rpm-build 07bc2b
  GObjectClass *gobject_class = (GObjectClass *) klass;
rpm-build 07bc2b
rpm-build 07bc2b
  gobject_class->constructed  = g_udev_client_constructed;
rpm-build 07bc2b
  gobject_class->set_property = g_udev_client_set_property;
rpm-build 07bc2b
  gobject_class->get_property = g_udev_client_get_property;
rpm-build 07bc2b
  gobject_class->finalize     = g_udev_client_finalize;
rpm-build 07bc2b
rpm-build 07bc2b
  /**
rpm-build 07bc2b
   * GUdevClient:subsystems:
rpm-build 07bc2b
   *
rpm-build 07bc2b
   * The subsystems to listen for uevents on.
rpm-build 07bc2b
   *
rpm-build 07bc2b
   * To listen for only a specific DEVTYPE for a given SUBSYSTEM, use
rpm-build 07bc2b
   * "subsystem/devtype". For example, to only listen for uevents
rpm-build 07bc2b
   * where SUBSYSTEM is usb and DEVTYPE is usb_interface, use
rpm-build 07bc2b
   * "usb/usb_interface".
rpm-build 07bc2b
   *
rpm-build 07bc2b
   * If this property is %NULL, then no events will be reported. If
rpm-build 07bc2b
   * it's the empty array, events from all subsystems will be
rpm-build 07bc2b
   * reported.
rpm-build 07bc2b
   */
rpm-build 07bc2b
  g_object_class_install_property (gobject_class,
rpm-build 07bc2b
                                   PROP_SUBSYSTEMS,
rpm-build 07bc2b
                                   g_param_spec_boxed ("subsystems",
rpm-build 07bc2b
                                                       "The subsystems to listen for changes on",
rpm-build 07bc2b
                                                       "The subsystems to listen for changes on",
rpm-build 07bc2b
                                                       G_TYPE_STRV,
rpm-build 07bc2b
                                                       G_PARAM_CONSTRUCT_ONLY |
rpm-build 07bc2b
                                                       G_PARAM_READWRITE));
rpm-build 07bc2b
rpm-build 07bc2b
  /**
rpm-build 07bc2b
   * GUdevClient::uevent:
rpm-build 07bc2b
   * @client: The #GUdevClient receiving the event.
rpm-build 07bc2b
   * @action: The action for the uevent e.g. "add", "remove", "change", "move", etc.
rpm-build 07bc2b
   * @device: Details about the #GUdevDevice the event is for.
rpm-build 07bc2b
   *
rpm-build 07bc2b
   * Emitted when @client receives an uevent.
rpm-build 07bc2b
   *
rpm-build 07bc2b
   * This signal is emitted in the
rpm-build 07bc2b
   * <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
rpm-build 07bc2b
   * of the thread that @client was created in.
rpm-build 07bc2b
   */
rpm-build 07bc2b
  signals[UEVENT_SIGNAL] = g_signal_new ("uevent",
rpm-build 07bc2b
                                         G_TYPE_FROM_CLASS (klass),
rpm-build 07bc2b
                                         G_SIGNAL_RUN_LAST,
rpm-build 07bc2b
                                         G_STRUCT_OFFSET (GUdevClientClass, uevent),
rpm-build 07bc2b
                                         NULL,
rpm-build 07bc2b
                                         NULL,
rpm-build 07bc2b
                                         g_cclosure_marshal_generic,
rpm-build 07bc2b
                                         G_TYPE_NONE,
rpm-build 07bc2b
                                         2,
rpm-build 07bc2b
                                         G_TYPE_STRING,
rpm-build 07bc2b
                                         G_UDEV_TYPE_DEVICE);
rpm-build 07bc2b
rpm-build 07bc2b
  g_type_class_add_private (klass, sizeof (GUdevClientPrivate));
rpm-build 07bc2b
}
rpm-build 07bc2b
rpm-build 07bc2b
static void
rpm-build 07bc2b
g_udev_client_init (GUdevClient *client)
rpm-build 07bc2b
{
rpm-build 07bc2b
  client->priv = G_TYPE_INSTANCE_GET_PRIVATE (client,
rpm-build 07bc2b
                                              G_UDEV_TYPE_CLIENT,
rpm-build 07bc2b
                                              GUdevClientPrivate);
rpm-build 07bc2b
}
rpm-build 07bc2b
rpm-build 07bc2b
/**
rpm-build 07bc2b
 * g_udev_client_new:
rpm-build 07bc2b
 * @subsystems: (array zero-terminated=1) (element-type utf8) (transfer none) (allow-none): A %NULL terminated string array of subsystems to listen for uevents on, %NULL to not listen on uevents at all, or an empty array to listen to uevents on all subsystems. See the documentation for the #GUdevClient:subsystems property for details on this parameter.
rpm-build 07bc2b
 *
rpm-build 07bc2b
 * Constructs a #GUdevClient object that can be used to query
rpm-build 07bc2b
 * information about devices. Connect to the #GUdevClient::uevent
rpm-build 07bc2b
 * signal to listen for uevents. Note that signals are emitted in the
rpm-build 07bc2b
 * <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
rpm-build 07bc2b
 * of the thread that you call this constructor from.
rpm-build 07bc2b
 *
rpm-build 07bc2b
 * Returns: A new #GUdevClient object. Free with g_object_unref().
rpm-build 07bc2b
 */
rpm-build 07bc2b
GUdevClient *
rpm-build 07bc2b
g_udev_client_new (const gchar * const *subsystems)
rpm-build 07bc2b
{
rpm-build 07bc2b
  return G_UDEV_CLIENT (g_object_new (G_UDEV_TYPE_CLIENT, "subsystems", subsystems, NULL));
rpm-build 07bc2b
}
rpm-build 07bc2b
rpm-build 07bc2b
/**
rpm-build 07bc2b
 * g_udev_client_query_by_subsystem:
rpm-build 07bc2b
 * @client: A #GUdevClient.
rpm-build 07bc2b
 * @subsystem: (allow-none): The subsystem to get devices for or %NULL to get all devices.
rpm-build 07bc2b
 *
rpm-build 07bc2b
 * Gets all devices belonging to @subsystem.
rpm-build 07bc2b
 *
rpm-build 07bc2b
 * Returns: (nullable) (element-type GUdevDevice) (transfer full): A
rpm-build 07bc2b
 * list of #GUdevDevice objects. The caller should free the result by
rpm-build 07bc2b
 * using g_object_unref() on each element in the list and then
rpm-build 07bc2b
 * g_list_free() on the list.
rpm-build 07bc2b
 */
rpm-build 07bc2b
GList *
rpm-build 07bc2b
g_udev_client_query_by_subsystem (GUdevClient  *client,
rpm-build 07bc2b
                                  const gchar  *subsystem)
rpm-build 07bc2b
{
rpm-build 07bc2b
  struct udev_enumerate *enumerate;
rpm-build 07bc2b
  struct udev_list_entry *l, *devices;
rpm-build 07bc2b
  GList *ret;
rpm-build 07bc2b
rpm-build 07bc2b
  g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
rpm-build 07bc2b
rpm-build 07bc2b
  ret = NULL;
rpm-build 07bc2b
rpm-build 07bc2b
  /* prepare a device scan */
rpm-build 07bc2b
  enumerate = udev_enumerate_new (client->priv->udev);
rpm-build 07bc2b
rpm-build 07bc2b
  /* filter for subsystem */
rpm-build 07bc2b
  if (subsystem != NULL)
rpm-build 07bc2b
    udev_enumerate_add_match_subsystem (enumerate, subsystem);
rpm-build 07bc2b
  /* retrieve the list */
rpm-build 07bc2b
  udev_enumerate_scan_devices (enumerate);
rpm-build 07bc2b
rpm-build 07bc2b
  /* add devices to the list */
rpm-build 07bc2b
  devices = udev_enumerate_get_list_entry (enumerate);
rpm-build 07bc2b
  for (l = devices; l != NULL; l = udev_list_entry_get_next (l))
rpm-build 07bc2b
    {
rpm-build 07bc2b
      struct udev_device *udevice;
rpm-build 07bc2b
      GUdevDevice *device;
rpm-build 07bc2b
rpm-build 07bc2b
      udevice = udev_device_new_from_syspath (udev_enumerate_get_udev (enumerate),
rpm-build 07bc2b
                                              udev_list_entry_get_name (l));
rpm-build 07bc2b
      if (udevice == NULL)
rpm-build 07bc2b
        continue;
rpm-build 07bc2b
      device = _g_udev_device_new (udevice);
rpm-build 07bc2b
      udev_device_unref (udevice);
rpm-build 07bc2b
      ret = g_list_prepend (ret, device);
rpm-build 07bc2b
    }
rpm-build 07bc2b
  udev_enumerate_unref (enumerate);
rpm-build 07bc2b
rpm-build 07bc2b
  ret = g_list_reverse (ret);
rpm-build 07bc2b
rpm-build 07bc2b
  return ret;
rpm-build 07bc2b
}
rpm-build 07bc2b
rpm-build 07bc2b
/**
rpm-build 07bc2b
 * g_udev_client_query_by_device_number:
rpm-build 07bc2b
 * @client: A #GUdevClient.
rpm-build 07bc2b
 * @type: A value from the #GUdevDeviceType enumeration.
rpm-build 07bc2b
 * @number: A device number.
rpm-build 07bc2b
 *
rpm-build 07bc2b
 * Looks up a device for a type and device number.
rpm-build 07bc2b
 *
rpm-build 07bc2b
 * Returns: (nullable) (transfer full): A #GUdevDevice object or %NULL
rpm-build 07bc2b
 * if the device was not found. Free with g_object_unref().
rpm-build 07bc2b
 */
rpm-build 07bc2b
GUdevDevice *
rpm-build 07bc2b
g_udev_client_query_by_device_number (GUdevClient      *client,
rpm-build 07bc2b
                                      GUdevDeviceType   type,
rpm-build 07bc2b
                                      GUdevDeviceNumber number)
rpm-build 07bc2b
{
rpm-build 07bc2b
  struct udev_device *udevice;
rpm-build 07bc2b
  GUdevDevice *device;
rpm-build 07bc2b
rpm-build 07bc2b
  g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
rpm-build 07bc2b
rpm-build 07bc2b
  device = NULL;
rpm-build 07bc2b
  udevice = udev_device_new_from_devnum (client->priv->udev, type, number);
rpm-build 07bc2b
rpm-build 07bc2b
  if (udevice == NULL)
rpm-build 07bc2b
    goto out;
rpm-build 07bc2b
rpm-build 07bc2b
  device = _g_udev_device_new (udevice);
rpm-build 07bc2b
  udev_device_unref (udevice);
rpm-build 07bc2b
rpm-build 07bc2b
 out:
rpm-build 07bc2b
  return device;
rpm-build 07bc2b
}
rpm-build 07bc2b
rpm-build 07bc2b
/**
rpm-build 07bc2b
 * g_udev_client_query_by_device_file:
rpm-build 07bc2b
 * @client: A #GUdevClient.
rpm-build 07bc2b
 * @device_file: A device file.
rpm-build 07bc2b
 *
rpm-build 07bc2b
 * Looks up a device for a device file.
rpm-build 07bc2b
 *
rpm-build 07bc2b
 * Returns: (nullable) (transfer full): A #GUdevDevice object or %NULL
rpm-build 07bc2b
 * if the device was not found. Free with g_object_unref().
rpm-build 07bc2b
 */
rpm-build 07bc2b
GUdevDevice *
rpm-build 07bc2b
g_udev_client_query_by_device_file (GUdevClient  *client,
rpm-build 07bc2b
                                    const gchar  *device_file)
rpm-build 07bc2b
{
rpm-build 07bc2b
  struct stat stat_buf;
rpm-build 07bc2b
  GUdevDevice *device;
rpm-build 07bc2b
rpm-build 07bc2b
  g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
rpm-build 07bc2b
  g_return_val_if_fail (device_file != NULL, NULL);
rpm-build 07bc2b
rpm-build 07bc2b
  device = NULL;
rpm-build 07bc2b
rpm-build 07bc2b
  if (stat (device_file, &stat_buf) != 0)
rpm-build 07bc2b
    goto out;
rpm-build 07bc2b
rpm-build 07bc2b
  if (stat_buf.st_rdev == 0)
rpm-build 07bc2b
    goto out;
rpm-build 07bc2b
rpm-build 07bc2b
  if (S_ISBLK (stat_buf.st_mode))
rpm-build 07bc2b
    device = g_udev_client_query_by_device_number (client, G_UDEV_DEVICE_TYPE_BLOCK, stat_buf.st_rdev);
rpm-build 07bc2b
  else if (S_ISCHR (stat_buf.st_mode))
rpm-build 07bc2b
    device = g_udev_client_query_by_device_number (client, G_UDEV_DEVICE_TYPE_CHAR, stat_buf.st_rdev);
rpm-build 07bc2b
rpm-build 07bc2b
 out:
rpm-build 07bc2b
  return device;
rpm-build 07bc2b
}
rpm-build 07bc2b
rpm-build 07bc2b
/**
rpm-build 07bc2b
 * g_udev_client_query_by_sysfs_path:
rpm-build 07bc2b
 * @client: A #GUdevClient.
rpm-build 07bc2b
 * @sysfs_path: A sysfs path.
rpm-build 07bc2b
 *
rpm-build 07bc2b
 * Looks up a device for a sysfs path.
rpm-build 07bc2b
 *
rpm-build 07bc2b
 * Returns: (nullable) (transfer full): A #GUdevDevice object or %NULL
rpm-build 07bc2b
 * if the device was not found. Free with g_object_unref().
rpm-build 07bc2b
 */
rpm-build 07bc2b
GUdevDevice *
rpm-build 07bc2b
g_udev_client_query_by_sysfs_path (GUdevClient  *client,
rpm-build 07bc2b
                                   const gchar  *sysfs_path)
rpm-build 07bc2b
{
rpm-build 07bc2b
  struct udev_device *udevice;
rpm-build 07bc2b
  GUdevDevice *device;
rpm-build 07bc2b
rpm-build 07bc2b
  g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
rpm-build 07bc2b
  g_return_val_if_fail (sysfs_path != NULL, NULL);
rpm-build 07bc2b
rpm-build 07bc2b
  device = NULL;
rpm-build 07bc2b
  udevice = udev_device_new_from_syspath (client->priv->udev, sysfs_path);
rpm-build 07bc2b
  if (udevice == NULL)
rpm-build 07bc2b
    goto out;
rpm-build 07bc2b
rpm-build 07bc2b
  device = _g_udev_device_new (udevice);
rpm-build 07bc2b
  udev_device_unref (udevice);
rpm-build 07bc2b
rpm-build 07bc2b
 out:
rpm-build 07bc2b
  return device;
rpm-build 07bc2b
}
rpm-build 07bc2b
rpm-build 07bc2b
/**
rpm-build 07bc2b
 * g_udev_client_query_by_subsystem_and_name:
rpm-build 07bc2b
 * @client: A #GUdevClient.
rpm-build 07bc2b
 * @subsystem: A subsystem name.
rpm-build 07bc2b
 * @name: The name of the device.
rpm-build 07bc2b
 *
rpm-build 07bc2b
 * Looks up a device for a subsystem and name.
rpm-build 07bc2b
 *
rpm-build 07bc2b
 * Returns: (nullable) (transfer full): A #GUdevDevice object or %NULL
rpm-build 07bc2b
 * if the device was not found. Free with g_object_unref().
rpm-build 07bc2b
 */
rpm-build 07bc2b
GUdevDevice *
rpm-build 07bc2b
g_udev_client_query_by_subsystem_and_name (GUdevClient  *client,
rpm-build 07bc2b
                                           const gchar  *subsystem,
rpm-build 07bc2b
                                           const gchar  *name)
rpm-build 07bc2b
{
rpm-build 07bc2b
  struct udev_device *udevice;
rpm-build 07bc2b
  GUdevDevice *device;
rpm-build 07bc2b
rpm-build 07bc2b
  g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
rpm-build 07bc2b
  g_return_val_if_fail (subsystem != NULL, NULL);
rpm-build 07bc2b
  g_return_val_if_fail (name != NULL, NULL);
rpm-build 07bc2b
rpm-build 07bc2b
  device = NULL;
rpm-build 07bc2b
  udevice = udev_device_new_from_subsystem_sysname (client->priv->udev, subsystem, name);
rpm-build 07bc2b
  if (udevice == NULL)
rpm-build 07bc2b
    goto out;
rpm-build 07bc2b
rpm-build 07bc2b
  device = _g_udev_device_new (udevice);
rpm-build 07bc2b
  udev_device_unref (udevice);
rpm-build 07bc2b
rpm-build 07bc2b
 out:
rpm-build 07bc2b
  return device;
rpm-build 07bc2b
}
rpm-build 07bc2b
rpm-build 07bc2b
struct udev_enumerate *
rpm-build 07bc2b
_g_udev_client_new_enumerate (GUdevClient *client)
rpm-build 07bc2b
{
rpm-build 07bc2b
  struct udev_enumerate *enumerate;
rpm-build 07bc2b
rpm-build 07bc2b
  enumerate = udev_enumerate_new (client->priv->udev);
rpm-build 07bc2b
rpm-build 07bc2b
  if (client->priv->subsystems != NULL)
rpm-build 07bc2b
    {
rpm-build 07bc2b
      guint n;
rpm-build 07bc2b
      for (n = 0; client->priv->subsystems[n] != NULL; n++)
rpm-build 07bc2b
        {
rpm-build 07bc2b
          gchar *subsystem;
rpm-build 07bc2b
          gchar *devtype;
rpm-build 07bc2b
          gchar *s;
rpm-build 07bc2b
rpm-build 07bc2b
          subsystem = g_strdup (client->priv->subsystems[n]);
rpm-build 07bc2b
          devtype = NULL;
rpm-build 07bc2b
rpm-build 07bc2b
          s = strstr (subsystem, "/");
rpm-build 07bc2b
          if (s != NULL)
rpm-build 07bc2b
            {
rpm-build 07bc2b
              devtype = s + 1;
rpm-build 07bc2b
              *s = '\0';
rpm-build 07bc2b
            }
rpm-build 07bc2b
rpm-build 07bc2b
          udev_enumerate_add_match_subsystem (enumerate, subsystem);
rpm-build 07bc2b
rpm-build 07bc2b
          if (devtype != NULL)
rpm-build 07bc2b
            udev_enumerate_add_match_property (enumerate, "DEVTYPE", devtype);
rpm-build 07bc2b
rpm-build 07bc2b
          g_free (subsystem);
rpm-build 07bc2b
        }
rpm-build 07bc2b
    }
rpm-build 07bc2b
rpm-build 07bc2b
  return enumerate;
rpm-build 07bc2b
}