summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@gmail.com>2015-05-07 12:17:37 +0200
committerDavid Herrmann <dh.herrmann@gmail.com>2015-05-07 16:38:44 +0200
commit43a593b5b4097b887e49eaacafbc1337bd709718 (patch)
treefaf1fa480892f1065ab817ac3cb0ee175b5ccc6c
downloadlibgudev-43a593b5b4097b887e49eaacafbc1337bd709718.tar.gz
Initial import
Import initial libgudev from systemd-218. This includes the libgudev sources, the introspection data and gtk-doc reference documentation.
-rw-r--r--.gitignore41
-rw-r--r--Makefile.am187
-rwxr-xr-xautogen.sh18
-rw-r--r--configure.ac65
-rw-r--r--docs/.gitignore12
-rw-r--r--docs/Makefile.am107
-rw-r--r--docs/gudev-docs.xml53
-rw-r--r--docs/gudev-sections.txt102
-rw-r--r--docs/gudev.types4
-rw-r--r--docs/version.xml.in1
-rw-r--r--gudev-1.0.pc.in11
-rw-r--r--gudev/gudev.h32
-rw-r--r--gudev/gudevclient.c533
-rw-r--r--gudev/gudevclient.h99
-rw-r--r--gudev/gudevdevice.c1027
-rw-r--r--gudev/gudevdevice.h130
-rw-r--r--gudev/gudevenumerator.c429
-rw-r--r--gudev/gudevenumerator.h106
-rw-r--r--gudev/gudevenums.h48
-rw-r--r--gudev/gudevenumtypes.c.template39
-rw-r--r--gudev/gudevenumtypes.h.template24
-rw-r--r--gudev/gudevmarshal.list1
-rw-r--r--gudev/gudevprivate.h40
-rw-r--r--gudev/gudevtypes.h50
-rw-r--r--libgudev-1.0.sym68
-rwxr-xr-xscripts/gjs-example.js75
-rwxr-xr-xscripts/seed-example-enum.js38
-rwxr-xr-xscripts/seed-example.js72
28 files changed, 3412 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6f43cc9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,41 @@
+*.a
+*.cache
+*.gir
+*.html
+*.la
+*.lo
+*.log
+*.o
+*.plist
+*.pyc
+*.stamp
+*.swp
+*.trs
+*.typelib
+*~
+.deps/
+.dirstamp
+.libs/
+/*.gcda
+/*.gcno
+/*.tar.bz2
+/*.tar.gz
+/*.tar.xz
+/Makefile
+/Makefile.in
+/aclocal.m4
+/build-aux/
+/config.h
+/config.h.in
+/config.log
+/config.status
+/configure
+/gtk-doc.make
+/gudev/gudevenumtypes.h
+/gudev/gudevenumtypes.c
+/gudev/gudevmarshal.h
+/gudev/gudevmarshal.c
+/gudev-1.0.pc
+/libtool
+/m4/
+/stamp-*
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..18822be
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,187 @@
+# ------------------------------------------------------------------------------
+# Common variables
+
+ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
+AUTOMAKE_OPTIONS = color-tests parallel-tests
+DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc
+SUBDIRS = .
+lib_LTLIBRARIES =
+noinst_DATA =
+MANPAGES =
+CLEANFILES = $(BUILT_SOURCES)
+EXTRA_DIST =
+BUILT_SOURCES =
+
+GCC_COLORS ?= 'ooh, shiny!'
+export GCC_COLORS
+
+# remove targets if the command fails
+.DELETE_ON_ERROR:
+
+# keep intermediate files
+.SECONDARY:
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA =
+
+AM_MAKEFLAGS = --no-print-directory
+AM_CPPFLAGS =
+AM_CFLAGS =
+
+# ------------------------------------------------------------------------------
+# Version numbers
+
+LIBGUDEV_CURRENT=2
+LIBGUDEV_REVISION=0
+LIBGUDEV_AGE=2
+
+# ------------------------------------------------------------------------------
+# libgudev
+
+libgudev_includedir = $(includedir)/gudev-1.0/gudev
+
+libgudev_include_HEADERS = \
+ gudev/gudev.h \
+ gudev/gudevenums.h \
+ gudev/gudevenumtypes.h \
+ gudev/gudevtypes.h \
+ gudev/gudevclient.h \
+ gudev/gudevdevice.h \
+ gudev/gudevenumerator.h
+
+lib_LTLIBRARIES += \
+ libgudev-1.0.la
+
+pkgconfig_DATA += \
+ gudev-1.0.pc
+
+EXTRA_DIST += \
+ gudev-1.0.pc.in \
+ gudev/gudevmarshal.list \
+ gudev/gudevenumtypes.h.template \
+ gudev/gudevenumtypes.c.template \
+ scripts/gjs-example.js \
+ scripts/seed-example-enum.js \
+ scripts/seed-example.js
+
+libgudev_1_0_la_SOURCES = \
+ libgudev-1.0.sym \
+ gudev/gudevenums.h \
+ gudev/gudevenumtypes.h \
+ gudev/gudevenumtypes.h\
+ gudev/gudevtypes.h \
+ gudev/gudevclient.h \
+ gudev/gudevclient.c \
+ gudev/gudevdevice.h \
+ gudev/gudevdevice.c \
+ gudev/gudevenumerator.h \
+ gudev/gudevenumerator.c \
+ gudev/gudevprivate.h
+
+nodist_libgudev_1_0_la_SOURCES = \
+ gudev/gudevmarshal.h \
+ gudev/gudevmarshal.c \
+ gudev/gudevenumtypes.h \
+ gudev/gudevenumtypes.c
+
+BUILT_SOURCES += \
+ $(nodist_libgudev_1_0_la_SOURCES)
+
+libgudev_1_0_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -I$(top_builddir)/gudev \
+ -I$(top_srcdir)/gudev \
+ -D_POSIX_PTHREAD_SEMANTICS \
+ -D_REENTRANT \
+ -D_GUDEV_COMPILATION \
+ -DG_LOG_DOMAIN=\"GUdev\"
+
+libgudev_1_0_la_CFLAGS = \
+ $(AM_CFLAGS) \
+ -fvisibility=default \
+ $(LIBUDEV_CFLAGS) \
+ $(GLIB_CFLAGS)
+
+libgudev_1_0_la_LIBADD = \
+ $(LIBUDEV_LIBS) \
+ $(GLIB_LIBS)
+
+libgudev_1_0_la_LDFLAGS = \
+ $(AM_LDFLAGS) \
+ -version-info $(LIBGUDEV_CURRENT):$(LIBGUDEV_REVISION):$(LIBGUDEV_AGE) \
+ -export-dynamic \
+ -no-undefined \
+ -Wl,--version-script=$(top_srcdir)/libgudev-1.0.sym
+
+gudev/gudevmarshal.h: gudev/gudevmarshal.list
+ $(AM_V_at)$(MKDIR_P) $(dir $@)
+ $(AM_V_GEN)glib-genmarshal $< --prefix=g_udev_marshal --header > $@
+
+gudev/gudevmarshal.c: gudev/gudevmarshal.list
+ $(AM_V_at)$(MKDIR_P) $(dir $@)
+ $(AM_V_GEN)echo '#include "gudevmarshal.h"' > $@ && \
+ glib-genmarshal $< --prefix=g_udev_marshal --body >> $@
+
+gudev/gudevenumtypes.%: gudev/gudevenumtypes.%.template gudev/gudevenums.h
+ $(AM_V_at)$(MKDIR_P) $(dir $@)
+ $(AM_V_GEN)glib-mkenums --template $^ > $@
+
+if HAVE_INTROSPECTION
+-include $(INTROSPECTION_MAKEFILE)
+
+gudev/GUdev-1.0.gir: libgudev-1.0.la
+
+gudev_GUdev_1_0_gir_INCLUDES = GObject-2.0
+
+gudev_GUdev_1_0_gir_CFLAGS = \
+ $(AM_CFLAGS) \
+ $(INCLUDES) \
+ -D_GUDEV_COMPILATION \
+ -D_GUDEV_WORK_AROUND_DEV_T_BUG \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ -I$(top_srcdir)/gudev \
+ -I$(top_builddir)/gudev
+
+gudev_GUdev_1_0_gir_LIBS = libgudev-1.0.la
+
+gudev_GUdev_1_0_gir_SCANNERFLAGS = \
+ --pkg-export=gudev-1.0 \
+ --warn-all
+
+gudev_GUdev_1_0_gir_FILES = \
+ gudev/gudev.h \
+ gudev/gudevtypes.h \
+ gudev/gudevenums.h \
+ gudev/gudevenumtypes.h \
+ gudev/gudevclient.h \
+ gudev/gudevdevice.h \
+ gudev/gudevenumerator.h \
+ gudev/gudevclient.c \
+ gudev/gudevdevice.c \
+ gudev/gudevenumerator.c
+
+INTROSPECTION_GIRS = gudev/GUdev-1.0.gir
+INTROSPECTION_SCANNER_ARGS = --c-include=gudev/gudev.h
+
+girdir = $(datadir)/gir-1.0
+gir_DATA = \
+ gudev/GUdev-1.0.gir
+
+typelibsdir = $(libdir)/girepository-1.0
+typelibs_DATA = \
+ gudev/GUdev-1.0.typelib
+
+CLEANFILES += $(gir_DATA) $(typelibs_DATA)
+endif # HAVE_INTROSPECTION
+
+# ------------------------------------------------------------------------------
+# docs
+
+if ENABLE_GTK_DOC
+SUBDIRS += docs
+endif
+
+#docs/html:
+# $(AM_V_at)$(MKDIR_P) $(dir $@)
+# $(AM_V_LN)$(LN_S) -f ../gudev/html $@
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000..f235b50
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+# Run this to generate all the initial makefiles, etc.
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+which gnome-autogen.sh || {
+ echo "You need to install gnome-common from the GNOME git"
+ exit 1
+}
+
+git submodule update --init --recursive
+
+REQUIRED_AUTOCONF_VERSION=2.64
+REQUIRED_AUTOMAKE_VERSION=1.11
+REQUIRED_INTLTOOL_VERSION=0.40.0
+REQUIRED_PKG_CONFIG_VERSION=0.22
+. gnome-autogen.sh
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..f920fae
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,65 @@
+AC_PREREQ([2.64])
+AC_INIT([libgudev],
+ [220],
+ [http://bugzilla.gnome.org/enter_bug.cgi?product=gudev],
+ [libgudev],
+ [https://developer.gnome.org/gudev])
+AC_CONFIG_SRCDIR([gudev/gudev.h])
+AC_CONFIG_MACRO_DIR([m4])
+AC_CONFIG_HEADERS([config.h])
+AC_CONFIG_AUX_DIR([build-aux])
+
+AC_USE_SYSTEM_EXTENSIONS
+AC_SYS_LARGEFILE
+AM_MAINTAINER_MODE([enable])
+AM_INIT_AUTOMAKE([foreign 1.11 -Wall -Wno-portability silent-rules tar-pax no-dist-gzip dist-xz subdir-objects parallel-tests])
+AM_SILENT_RULES([yes])
+AC_CANONICAL_HOST
+LT_PREREQ([2.2])
+LT_INIT([disable-static])
+
+AC_PROG_MKDIR_P
+AC_PROG_LN_S
+AC_PROG_SED
+AC_PROG_GREP
+AC_PROG_AWK
+AC_PROG_CC_C99
+PKG_PROG_PKG_CONFIG
+
+# gtkdocize greps for '^GTK_DOC_CHECK', so it needs to be on its own line
+m4_ifdef([GTK_DOC_CHECK], [
+GTK_DOC_CHECK([1.18],[--flavour no-tmpl])],
+ [AM_CONDITIONAL([ENABLE_GTK_DOC], [false])
+ enable_gtk_doc=no])
+
+m4_ifdef([GOBJECT_INTROSPECTION_CHECK], [
+GOBJECT_INTROSPECTION_CHECK([1.31.1])
+], [
+ AM_CONDITIONAL([HAVE_INTROSPECTION], [false])
+ enable_introspection=no])
+
+PKG_CHECK_MODULES([LIBUDEV], [libudev >= 218])
+PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.22.0 gobject-2.0 >= 2.22.0 gio-2.0])
+
+AC_CONFIG_FILES([
+ Makefile
+ gudev-1.0.pc
+ docs/Makefile
+ docs/version.xml
+])
+
+AC_OUTPUT
+AC_MSG_RESULT([
+ $PACKAGE_NAME $VERSION
+ gintrospection: ${enable_introspection}
+ gtk-doc: ${enable_gtk_doc}
+
+ prefix: ${prefix}
+ exec_prefix: ${exec_prefix}
+ includedir: ${includedir}
+ libdir: ${libdir}
+
+ CFLAGS: ${CFLAGS}
+ CPPFLAGS: ${CPPFLAGS}
+ LDFLAGS: ${LDFLAGS}
+])
diff --git a/docs/.gitignore b/docs/.gitignore
new file mode 100644
index 0000000..c99095e
--- /dev/null
+++ b/docs/.gitignore
@@ -0,0 +1,12 @@
+/*.txt
+/Makefile
+/Makefile.in
+/gudev.args
+/gudev.hierarchy
+/gudev.interfaces
+/gudev.prerequisites
+/gudev.signals
+/html/
+/tmpl/
+/version.xml
+/xml/
diff --git a/docs/Makefile.am b/docs/Makefile.am
new file mode 100644
index 0000000..0e8d7d0
--- /dev/null
+++ b/docs/Makefile.am
@@ -0,0 +1,107 @@
+## Process this file with automake to produce Makefile.in
+
+# We require automake 1.10 at least.
+AUTOMAKE_OPTIONS = 1.10 color-tests
+
+# This is a blank Makefile.am for using gtk-doc.
+# Copy this to your project's API docs directory and modify the variables to
+# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples
+# of using the various options.
+
+# The name of the module, e.g. 'glib'.
+DOC_MODULE=gudev
+
+# Uncomment for versioned docs and specify the version of the module, e.g. '2'.
+#DOC_MODULE_VERSION=2
+
+# The top-level SGML file. You can change this if you want to.
+DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.xml
+
+# The directory containing the source code. Relative to $(srcdir).
+# gtk-doc will search all .c & .h files beneath here for inline comments
+# documenting the functions and macros.
+# e.g. DOC_SOURCE_DIR=../../../gtk
+DOC_SOURCE_DIR=$(top_srcdir)/gudev $(top_builddir)/gudev
+
+# Extra options to pass to gtkdoc-scangobj. Not normally needed.
+SCANGOBJ_OPTIONS=
+
+# Extra options to supply to gtkdoc-scan.
+# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
+SCAN_OPTIONS=
+
+# Extra options to supply to gtkdoc-mkdb.
+# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml
+MKDB_OPTIONS=--xml-mode --output-format=xml --name-space=g_udev
+
+# Extra options to supply to gtkdoc-mktmpl
+# e.g. MKTMPL_OPTIONS=--only-section-tmpl
+MKTMPL_OPTIONS=
+
+# Extra options to supply to gtkdoc-mkhtml
+MKHTML_OPTIONS=--path=$(abs_srcdir) --path=$(abs_builddir)
+
+# Extra options to supply to gtkdoc-fixref. Not normally needed.
+# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html
+FIXXREF_OPTIONS=>/dev/null 2>&1
+
+# Used for dependencies. The docs will be rebuilt if any of these change.
+# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h
+# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c
+HFILE_GLOB=$(top_srcdir)/gudev/*.h
+CFILE_GLOB=$(top_srcdir)/gudev/*.c
+
+# Extra header to include when scanning, which are not under DOC_SOURCE_DIR
+# e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h
+EXTRA_HFILES=
+
+# Header files to ignore when scanning. Use base file name, no paths
+# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
+IGNORE_HFILES=gudevenumtypes.h gudevmarshal.h
+
+# Images to copy into HTML directory.
+# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
+HTML_IMAGES=
+
+# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
+# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
+content_files = version.xml
+
+# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
+# These files must be listed here *and* in content_files
+# e.g. expand_content_files=running.sgml
+expand_content_files=
+
+# Hack, hack. You silly gtk-doc, you must not add CFLAGS multiple
+# times when calling gcc; it surely can not work with options that must
+# be listed only once.
+# Kill CFLAGS here because gtk-doc thinks adding CFLAGS to CC _and_ also
+# adding CFLAGS itself again would work.
+override CFLAGS=
+override LDFLAGS=
+
+# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
+# Only needed if you are using gtkdoc-scangobj to dynamically query widget
+# signals and properties.
+# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
+# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
+GTKDOC_CFLAGS = \
+ $(GLIB_CFLAGS) \
+ -I$(top_srcdir)/gudev \
+ -I$(top_builddir)/gudev
+
+GTKDOC_LIBS = \
+ $(GLIB_LIBS) \
+ $(top_builddir)/libgudev-1.0.la
+
+# This includes the standard gtk-doc make rules, copied by gtkdocize.
+include $(top_srcdir)/gtk-doc.make
+
+# Other files to distribute
+# e.g. EXTRA_DIST += version.xml.in
+EXTRA_DIST += version.xml.in
+
+# Files not to distribute
+# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types
+# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt
+#DISTCLEANFILES +=
diff --git a/docs/gudev-docs.xml b/docs/gudev-docs.xml
new file mode 100644
index 0000000..2961da3
--- /dev/null
+++ b/docs/gudev-docs.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
+[
+ <!ENTITY version SYSTEM "version.xml">
+]>
+<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
+ <bookinfo>
+ <title>GUdev Reference Manual</title>
+ <releaseinfo>
+ For version &version; — the latest version of this
+ documentation can be found at
+ <ulink role="online-location" url="https://developer.gnome.org/gudev">
+ https://developer.gnome.org/gudev
+ </ulink>.
+ </releaseinfo>
+ <copyright>
+ <year>2009-2015</year>
+ <holder>David Zeuthen &lt;davidz@redhat.com&gt;</holder>
+ <holder>Bastien Nocera &lt;hadess@hadess.net&gt;</holder>
+ <holder>David Herrmann &lt;dh.herrmann@gmail.com&gt;</holder>
+ </copyright>
+ </bookinfo>
+
+ <chapter id="ref-API">
+ <title>API Reference</title>
+ <xi:include href="xml/gudevclient.xml"/>
+ <xi:include href="xml/gudevdevice.xml"/>
+ <xi:include href="xml/gudevenumerator.xml"/>
+ </chapter>
+
+ <chapter id="gudev-hierarchy">
+ <title>Object Hierarchy</title>
+ <xi:include href="xml/tree_index.sgml"/>
+ </chapter>
+
+ <index id="api-index-full">
+ <title>API Index</title>
+ <xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
+ </index>
+
+ <index role="165">
+ <title>Index of new symbols in 165</title>
+ <xi:include href="xml/api-index-165.xml"><xi:fallback /></xi:include>
+ </index>
+
+ <index id="api-index-deprecated" role="deprecated">
+ <title>Index of deprecated API</title>
+ <xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
+ </index>
+
+ <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
+</book>
diff --git a/docs/gudev-sections.txt b/docs/gudev-sections.txt
new file mode 100644
index 0000000..90765ee
--- /dev/null
+++ b/docs/gudev-sections.txt
@@ -0,0 +1,102 @@
+<SECTION>
+<FILE>gudevclient</FILE>
+<TITLE>GUdevClient</TITLE>
+GUdevClient
+GUdevClientClass
+GUdevDeviceType
+GUdevDeviceNumber
+g_udev_client_new
+g_udev_client_query_by_subsystem
+g_udev_client_query_by_device_number
+g_udev_client_query_by_device_file
+g_udev_client_query_by_sysfs_path
+g_udev_client_query_by_subsystem_and_name
+<SUBSECTION Standard>
+G_UDEV_CLIENT
+G_UDEV_IS_CLIENT
+G_UDEV_TYPE_CLIENT
+g_udev_client_get_type
+G_UDEV_CLIENT_CLASS
+G_UDEV_IS_CLIENT_CLASS
+G_UDEV_CLIENT_GET_CLASS
+<SUBSECTION Private>
+GUdevClientPrivate
+</SECTION>
+
+<SECTION>
+<FILE>gudevdevice</FILE>
+<TITLE>GUdevDevice</TITLE>
+GUdevDevice
+GUdevDeviceClass
+g_udev_device_get_subsystem
+g_udev_device_get_devtype
+g_udev_device_get_name
+g_udev_device_get_number
+g_udev_device_get_sysfs_path
+g_udev_device_get_driver
+g_udev_device_get_action
+g_udev_device_get_seqnum
+g_udev_device_get_device_type
+g_udev_device_get_device_number
+g_udev_device_get_device_file
+g_udev_device_get_device_file_symlinks
+g_udev_device_get_parent
+g_udev_device_get_parent_with_subsystem
+g_udev_device_get_tags
+g_udev_device_get_is_initialized
+g_udev_device_get_usec_since_initialized
+g_udev_device_get_property_keys
+g_udev_device_has_property
+g_udev_device_get_property
+g_udev_device_get_property_as_int
+g_udev_device_get_property_as_uint64
+g_udev_device_get_property_as_double
+g_udev_device_get_property_as_boolean
+g_udev_device_get_property_as_strv
+g_udev_device_get_sysfs_attr_keys
+g_udev_device_has_sysfs_attr
+g_udev_device_get_sysfs_attr
+g_udev_device_get_sysfs_attr_as_int
+g_udev_device_get_sysfs_attr_as_uint64
+g_udev_device_get_sysfs_attr_as_double
+g_udev_device_get_sysfs_attr_as_boolean
+g_udev_device_get_sysfs_attr_as_strv
+<SUBSECTION Standard>
+G_UDEV_DEVICE
+G_UDEV_IS_DEVICE
+G_UDEV_TYPE_DEVICE
+g_udev_device_get_type
+G_UDEV_DEVICE_CLASS
+G_UDEV_IS_DEVICE_CLASS
+G_UDEV_DEVICE_GET_CLASS
+<SUBSECTION Private>
+GUdevDevicePrivate
+</SECTION>
+
+<SECTION>
+<FILE>gudevenumerator</FILE>
+<TITLE>GUdevEnumerator</TITLE>
+GUdevEnumerator
+GUdevEnumeratorClass
+g_udev_enumerator_new
+g_udev_enumerator_add_match_subsystem
+g_udev_enumerator_add_nomatch_subsystem
+g_udev_enumerator_add_match_sysfs_attr
+g_udev_enumerator_add_nomatch_sysfs_attr
+g_udev_enumerator_add_match_property
+g_udev_enumerator_add_match_name
+g_udev_enumerator_add_match_tag
+g_udev_enumerator_add_match_is_initialized
+g_udev_enumerator_add_sysfs_path
+g_udev_enumerator_execute
+<SUBSECTION Standard>
+G_UDEV_ENUMERATOR
+G_UDEV_IS_ENUMERATOR
+G_UDEV_TYPE_ENUMERATOR
+g_udev_enumerator_get_type
+G_UDEV_ENUMERATOR_CLASS
+G_UDEV_IS_ENUMERATOR_CLASS
+G_UDEV_ENUMERATOR_GET_CLASS
+<SUBSECTION Private>
+GUdevEnumeratorPrivate
+</SECTION>
diff --git a/docs/gudev.types b/docs/gudev.types
new file mode 100644
index 0000000..a89857a
--- /dev/null
+++ b/docs/gudev.types
@@ -0,0 +1,4 @@
+g_udev_device_type_get_type
+g_udev_device_get_type
+g_udev_client_get_type
+g_udev_enumerator_get_type
diff --git a/docs/version.xml.in b/docs/version.xml.in
new file mode 100644
index 0000000..d78bda9
--- /dev/null
+++ b/docs/version.xml.in
@@ -0,0 +1 @@
+@VERSION@
diff --git a/gudev-1.0.pc.in b/gudev-1.0.pc.in
new file mode 100644
index 0000000..058262d
--- /dev/null
+++ b/gudev-1.0.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: gudev-1.0
+Description: GObject bindings for libudev
+Version: @VERSION@
+Requires: glib-2.0, gobject-2.0
+Libs: -L${libdir} -lgudev-1.0
+Cflags: -I${includedir}/gudev-1.0
diff --git a/gudev/gudev.h b/gudev/gudev.h
new file mode 100644
index 0000000..1dc42b1
--- /dev/null
+++ b/gudev/gudev.h
@@ -0,0 +1,32 @@
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __G_UDEV_H__
+#define __G_UDEV_H__
+
+#define _GUDEV_INSIDE_GUDEV_H
+#include <gudev/gudevenums.h>
+#include <gudev/gudevenumtypes.h>
+#include <gudev/gudevtypes.h>
+#include <gudev/gudevclient.h>
+#include <gudev/gudevdevice.h>
+#include <gudev/gudevenumerator.h>
+#undef _GUDEV_INSIDE_GUDEV_H
+
+#endif /* __G_UDEV_H__ */
diff --git a/gudev/gudevclient.c b/gudev/gudevclient.c
new file mode 100644
index 0000000..8b9516c
--- /dev/null
+++ b/gudev/gudevclient.c
@@ -0,0 +1,533 @@
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008-2010 David Zeuthen <davidz@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include "gudevclient.h"
+#include "gudevdevice.h"
+#include "gudevmarshal.h"
+#include "gudevprivate.h"
+
+/**
+ * SECTION:gudevclient
+ * @short_description: Query devices and listen to uevents
+ *
+ * #GUdevClient is used to query information about devices on a Linux
+ * system from the Linux kernel and the udev device
+ * manager.
+ *
+ * Device information is retrieved from the kernel (through the
+ * <literal>sysfs</literal> filesystem) and the udev daemon (through a
+ * <literal>tmpfs</literal> filesystem) and presented through
+ * #GUdevDevice objects. This means that no blocking IO ever happens
+ * (in both cases, we are essentially just reading data from kernel
+ * memory) and as such there are no asynchronous versions of the
+ * provided methods.
+ *
+ * To get #GUdevDevice objects, use
+ * g_udev_client_query_by_subsystem(),
+ * g_udev_client_query_by_device_number(),
+ * g_udev_client_query_by_device_file(),
+ * g_udev_client_query_by_sysfs_path(),
+ * g_udev_client_query_by_subsystem_and_name()
+ * or the #GUdevEnumerator type.
+ *
+ * To listen to uevents, connect to the #GUdevClient::uevent signal.
+ */
+
+struct _GUdevClientPrivate
+{
+ GSource *watch_source;
+ struct udev *udev;
+ struct udev_monitor *monitor;
+
+ gchar **subsystems;
+};
+
+enum
+{
+ PROP_0,
+ PROP_SUBSYSTEMS,
+};
+
+enum
+{
+ UEVENT_SIGNAL,
+ LAST_SIGNAL,
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (GUdevClient, g_udev_client, G_TYPE_OBJECT)
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static gboolean
+monitor_event (GIOChannel *source,
+ GIOCondition condition,
+ gpointer data)
+{
+ GUdevClient *client = (GUdevClient *) data;
+ GUdevDevice *device;
+ struct udev_device *udevice;
+
+ if (client->priv->monitor == NULL)
+ goto out;
+ udevice = udev_monitor_receive_device (client->priv->monitor);
+ if (udevice == NULL)
+ goto out;
+
+ device = _g_udev_device_new (udevice);
+ udev_device_unref (udevice);
+ g_signal_emit (client,
+ signals[UEVENT_SIGNAL],
+ 0,
+ g_udev_device_get_action (device),
+ device);
+ g_object_unref (device);
+
+ out:
+ return TRUE;
+}
+
+static void
+g_udev_client_finalize (GObject *object)
+{
+ GUdevClient *client = G_UDEV_CLIENT (object);
+
+ if (client->priv->watch_source != NULL)
+ {
+ g_source_destroy (client->priv->watch_source);
+ client->priv->watch_source = NULL;
+ }
+
+ if (client->priv->monitor != NULL)
+ {
+ udev_monitor_unref (client->priv->monitor);
+ client->priv->monitor = NULL;
+ }
+
+ if (client->priv->udev != NULL)
+ {
+ udev_unref (client->priv->udev);
+ client->priv->udev = NULL;
+ }
+
+ g_strfreev (client->priv->subsystems);
+
+ if (G_OBJECT_CLASS (g_udev_client_parent_class)->finalize != NULL)
+ G_OBJECT_CLASS (g_udev_client_parent_class)->finalize (object);
+}
+
+static void
+g_udev_client_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GUdevClient *client = G_UDEV_CLIENT (object);
+
+ switch (prop_id)
+ {
+ case PROP_SUBSYSTEMS:
+ if (client->priv->subsystems != NULL)
+ g_strfreev (client->priv->subsystems);
+ client->priv->subsystems = g_strdupv (g_value_get_boxed (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+g_udev_client_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GUdevClient *client = G_UDEV_CLIENT (object);
+
+ switch (prop_id)
+ {
+ case PROP_SUBSYSTEMS:
+ g_value_set_boxed (value, client->priv->subsystems);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+g_udev_client_constructed (GObject *object)
+{
+ GUdevClient *client = G_UDEV_CLIENT (object);
+ GIOChannel *channel;
+ guint n;
+
+ client->priv->udev = udev_new ();
+
+ /* connect to event source */
+ client->priv->monitor = udev_monitor_new_from_netlink (client->priv->udev, "udev");
+
+ //g_debug ("ss = %p", client->priv->subsystems);
+
+ if (client->priv->subsystems != NULL)
+ {
+ /* install subsystem filters to only wake up for certain events */
+ for (n = 0; client->priv->subsystems[n] != NULL; n++)
+ {
+ gchar *subsystem;
+ gchar *devtype;
+ gchar *s;
+
+ subsystem = g_strdup (client->priv->subsystems[n]);
+ devtype = NULL;
+
+ //g_debug ("s = '%s'", subsystem);
+
+ s = strstr (subsystem, "/");
+ if (s != NULL)
+ {
+ devtype = s + 1;
+ *s = '\0';
+ }
+
+ if (client->priv->monitor != NULL)
+ udev_monitor_filter_add_match_subsystem_devtype (client->priv->monitor, subsystem, devtype);
+
+ g_free (subsystem);
+ }
+
+ /* listen to events, and buffer them */
+ if (client->priv->monitor != NULL)
+ {
+ udev_monitor_enable_receiving (client->priv->monitor);
+ channel = g_io_channel_unix_new (udev_monitor_get_fd (client->priv->monitor));
+ client->priv->watch_source = g_io_create_watch (channel, G_IO_IN);
+ g_io_channel_unref (channel);
+ g_source_set_callback (client->priv->watch_source, (GSourceFunc) monitor_event, client, NULL);
+ g_source_attach (client->priv->watch_source, g_main_context_get_thread_default ());
+ g_source_unref (client->priv->watch_source);
+ }
+ else
+ {
+ client->priv->watch_source = NULL;
+ }
+ }
+
+ if (G_OBJECT_CLASS (g_udev_client_parent_class)->constructed != NULL)
+ G_OBJECT_CLASS (g_udev_client_parent_class)->constructed (object);
+}
+
+
+static void
+g_udev_client_class_init (GUdevClientClass *klass)
+{
+ GObjectClass *gobject_class = (GObjectClass *) klass;
+
+ gobject_class->constructed = g_udev_client_constructed;
+ gobject_class->set_property = g_udev_client_set_property;
+ gobject_class->get_property = g_udev_client_get_property;
+ gobject_class->finalize = g_udev_client_finalize;
+
+ /**
+ * GUdevClient:subsystems:
+ *
+ * The subsystems to listen for uevents on.
+ *
+ * To listen for only a specific DEVTYPE for a given SUBSYSTEM, use
+ * "subsystem/devtype". For example, to only listen for uevents
+ * where SUBSYSTEM is usb and DEVTYPE is usb_interface, use
+ * "usb/usb_interface".
+ *
+ * If this property is %NULL, then no events will be reported. If
+ * it's the empty array, events from all subsystems will be
+ * reported.
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_SUBSYSTEMS,
+ g_param_spec_boxed ("subsystems",
+ "The subsystems to listen for changes on",
+ "The subsystems to listen for changes on",
+ G_TYPE_STRV,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE));
+
+ /**
+ * GUdevClient::uevent:
+ * @client: The #GUdevClient receiving the event.
+ * @action: The action for the uevent e.g. "add", "remove", "change", "move", etc.
+ * @device: Details about the #GUdevDevice the event is for.
+ *
+ * Emitted when @client receives an uevent.
+ *
+ * This signal is emitted in the
+ * <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
+ * of the thread that @client was created in.
+ */
+ signals[UEVENT_SIGNAL] = g_signal_new ("uevent",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GUdevClientClass, uevent),
+ NULL,
+ NULL,
+ g_udev_marshal_VOID__STRING_OBJECT,
+ G_TYPE_NONE,
+ 2,
+ G_TYPE_STRING,
+ G_UDEV_TYPE_DEVICE);
+
+ g_type_class_add_private (klass, sizeof (GUdevClientPrivate));
+}
+
+static void
+g_udev_client_init (GUdevClient *client)
+{
+ client->priv = G_TYPE_INSTANCE_GET_PRIVATE (client,
+ G_UDEV_TYPE_CLIENT,
+ GUdevClientPrivate);
+}
+
+/**
+ * g_udev_client_new:
+ * @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.
+ *
+ * Constructs a #GUdevClient object that can be used to query
+ * information about devices. Connect to the #GUdevClient::uevent
+ * signal to listen for uevents. Note that signals are emitted in the
+ * <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
+ * of the thread that you call this constructor from.
+ *
+ * Returns: A new #GUdevClient object. Free with g_object_unref().
+ */
+GUdevClient *
+g_udev_client_new (const gchar * const *subsystems)
+{
+ return G_UDEV_CLIENT (g_object_new (G_UDEV_TYPE_CLIENT, "subsystems", subsystems, NULL));
+}
+
+/**
+ * g_udev_client_query_by_subsystem:
+ * @client: A #GUdevClient.
+ * @subsystem: (allow-none): The subsystem to get devices for or %NULL to get all devices.
+ *
+ * Gets all devices belonging to @subsystem.
+ *
+ * Returns: (nullable) (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.
+ */
+GList *
+g_udev_client_query_by_subsystem (GUdevClient *client,
+ const gchar *subsystem)
+{
+ struct udev_enumerate *enumerate;
+ struct udev_list_entry *l, *devices;
+ GList *ret;
+
+ g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
+
+ ret = NULL;
+
+ /* prepare a device scan */
+ enumerate = udev_enumerate_new (client->priv->udev);
+
+ /* filter for subsystem */
+ if (subsystem != NULL)
+ udev_enumerate_add_match_subsystem (enumerate, subsystem);
+ /* retrieve the list */
+ udev_enumerate_scan_devices (enumerate);
+
+ /* add devices to the list */
+ devices = udev_enumerate_get_list_entry (enumerate);
+ for (l = devices; l != NULL; l = udev_list_entry_get_next (l))
+ {
+ struct udev_device *udevice;
+ GUdevDevice *device;
+
+ udevice = udev_device_new_from_syspath (udev_enumerate_get_udev (enumerate),
+ udev_list_entry_get_name (l));
+ if (udevice == NULL)
+ continue;
+ device = _g_udev_device_new (udevice);
+ udev_device_unref (udevice);
+ ret = g_list_prepend (ret, device);
+ }
+ udev_enumerate_unref (enumerate);
+
+ ret = g_list_reverse (ret);
+
+ return ret;
+}
+
+/**
+ * g_udev_client_query_by_device_number:
+ * @client: A #GUdevClient.
+ * @type: A value from the #GUdevDeviceType enumeration.
+ * @number: A device number.
+ *
+ * Looks up a device for a type and device number.
+ *
+ * Returns: (nullable) (transfer full): A #GUdevDevice object or %NULL
+ * if the device was not found. Free with g_object_unref().
+ */
+GUdevDevice *
+g_udev_client_query_by_device_number (GUdevClient *client,
+ GUdevDeviceType type,
+ GUdevDeviceNumber number)
+{
+ struct udev_device *udevice;
+ GUdevDevice *device;
+
+ g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
+
+ device = NULL;
+ udevice = udev_device_new_from_devnum (client->priv->udev, type, number);
+
+ if (udevice == NULL)
+ goto out;
+
+ device = _g_udev_device_new (udevice);
+ udev_device_unref (udevice);
+
+ out:
+ return device;
+}
+
+/**
+ * g_udev_client_query_by_device_file:
+ * @client: A #GUdevClient.
+ * @device_file: A device file.
+ *
+ * Looks up a device for a device file.
+ *
+ * Returns: (nullable) (transfer full): A #GUdevDevice object or %NULL
+ * if the device was not found. Free with g_object_unref().
+ */
+GUdevDevice *
+g_udev_client_query_by_device_file (GUdevClient *client,
+ const gchar *device_file)
+{
+ struct stat stat_buf;
+ GUdevDevice *device;
+
+ g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
+ g_return_val_if_fail (device_file != NULL, NULL);
+
+ device = NULL;
+
+ if (stat (device_file, &stat_buf) != 0)
+ goto out;
+
+ if (stat_buf.st_rdev == 0)
+ goto out;
+
+ if (S_ISBLK (stat_buf.st_mode))
+ device = g_udev_client_query_by_device_number (client, G_UDEV_DEVICE_TYPE_BLOCK, stat_buf.st_rdev);
+ else if (S_ISCHR (stat_buf.st_mode))
+ device = g_udev_client_query_by_device_number (client, G_UDEV_DEVICE_TYPE_CHAR, stat_buf.st_rdev);
+
+ out:
+ return device;
+}
+
+/**
+ * g_udev_client_query_by_sysfs_path:
+ * @client: A #GUdevClient.
+ * @sysfs_path: A sysfs path.
+ *
+ * Looks up a device for a sysfs path.
+ *
+ * Returns: (nullable) (transfer full): A #GUdevDevice object or %NULL
+ * if the device was not found. Free with g_object_unref().
+ */
+GUdevDevice *
+g_udev_client_query_by_sysfs_path (GUdevClient *client,
+ const gchar *sysfs_path)
+{
+ struct udev_device *udevice;
+ GUdevDevice *device;
+
+ g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
+ g_return_val_if_fail (sysfs_path != NULL, NULL);
+
+ device = NULL;
+ udevice = udev_device_new_from_syspath (client->priv->udev, sysfs_path);
+ if (udevice == NULL)
+ goto out;
+
+ device = _g_udev_device_new (udevice);
+ udev_device_unref (udevice);
+
+ out:
+ return device;
+}
+
+/**
+ * g_udev_client_query_by_subsystem_and_name:
+ * @client: A #GUdevClient.
+ * @subsystem: A subsystem name.
+ * @name: The name of the device.
+ *
+ * Looks up a device for a subsystem and name.
+ *
+ * Returns: (nullable) (transfer full): A #GUdevDevice object or %NULL
+ * if the device was not found. Free with g_object_unref().
+ */
+GUdevDevice *
+g_udev_client_query_by_subsystem_and_name (GUdevClient *client,
+ const gchar *subsystem,
+ const gchar *name)
+{
+ struct udev_device *udevice;
+ GUdevDevice *device;
+
+ g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
+ g_return_val_if_fail (subsystem != NULL, NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+
+ device = NULL;
+ udevice = udev_device_new_from_subsystem_sysname (client->priv->udev, subsystem, name);
+ if (udevice == NULL)
+ goto out;
+
+ device = _g_udev_device_new (udevice);
+ udev_device_unref (udevice);
+
+ out:
+ return device;
+}
+
+struct udev *
+_g_udev_client_get_udev (GUdevClient *client)
+{
+ g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
+ return client->priv->udev;
+}
diff --git a/gudev/gudevclient.h b/gudev/gudevclient.h
new file mode 100644
index 0000000..23bfce6
--- /dev/null
+++ b/gudev/gudevclient.h
@@ -0,0 +1,99 @@
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H)
+#error "Only <gudev/gudev.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef __G_UDEV_CLIENT_H__
+#define __G_UDEV_CLIENT_H__
+
+#include <gudev/gudevtypes.h>
+
+G_BEGIN_DECLS
+
+#define G_UDEV_TYPE_CLIENT (g_udev_client_get_type ())
+#define G_UDEV_CLIENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_UDEV_TYPE_CLIENT, GUdevClient))
+#define G_UDEV_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_UDEV_TYPE_CLIENT, GUdevClientClass))
+#define G_UDEV_IS_CLIENT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_UDEV_TYPE_CLIENT))
+#define G_UDEV_IS_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_UDEV_TYPE_CLIENT))
+#define G_UDEV_CLIENT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_UDEV_TYPE_CLIENT, GUdevClientClass))
+
+typedef struct _GUdevClientClass GUdevClientClass;
+typedef struct _GUdevClientPrivate GUdevClientPrivate;
+
+/**
+ * GUdevClient:
+ *
+ * The #GUdevClient struct is opaque and should not be accessed directly.
+ */
+struct _GUdevClient
+{
+ GObject parent;
+
+ /*< private >*/
+ GUdevClientPrivate *priv;
+};
+
+/**
+ * GUdevClientClass:
+ * @parent_class: Parent class.
+ * @uevent: Signal class handler for the #GUdevClient::uevent signal.
+ *
+ * Class structure for #GUdevClient.
+ */
+struct _GUdevClientClass
+{
+ GObjectClass parent_class;
+
+ /* signals */
+ void (*uevent) (GUdevClient *client,
+ const gchar *action,
+ GUdevDevice *device);
+
+ /*< private >*/
+ /* Padding for future expansion */
+ void (*reserved1) (void);
+ void (*reserved2) (void);
+ void (*reserved3) (void);
+ void (*reserved4) (void);
+ void (*reserved5) (void);
+ void (*reserved6) (void);
+ void (*reserved7) (void);
+ void (*reserved8) (void);
+};
+
+GType g_udev_client_get_type (void) G_GNUC_CONST;
+GUdevClient *g_udev_client_new (const gchar* const *subsystems);
+GList *g_udev_client_query_by_subsystem (GUdevClient *client,
+ const gchar *subsystem);
+GUdevDevice *g_udev_client_query_by_device_number (GUdevClient *client,
+ GUdevDeviceType type,
+ GUdevDeviceNumber number);
+GUdevDevice *g_udev_client_query_by_device_file (GUdevClient *client,
+ const gchar *device_file);
+GUdevDevice *g_udev_client_query_by_sysfs_path (GUdevClient *client,
+ const gchar *sysfs_path);
+GUdevDevice *g_udev_client_query_by_subsystem_and_name (GUdevClient *client,
+ const gchar *subsystem,
+ const gchar *name);
+
+G_END_DECLS
+
+#endif /* __G_UDEV_CLIENT_H__ */
diff --git a/gudev/gudevdevice.c b/gudev/gudevdevice.c
new file mode 100644
index 0000000..5530d2c
--- /dev/null
+++ b/gudev/gudevdevice.c
@@ -0,0 +1,1027 @@
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include "gudevdevice.h"
+#include "gudevprivate.h"
+
+/**
+ * SECTION:gudevdevice
+ * @short_description: Get information about a device
+ *
+ * The #GUdevDevice class is used to get information about a specific
+ * device. Note that you cannot instantiate a #GUdevDevice object
+ * yourself. Instead you must use #GUdevClient to obtain #GUdevDevice
+ * objects.
+ *
+ * To get basic information about a device, use
+ * g_udev_device_get_subsystem(), g_udev_device_get_devtype(),
+ * g_udev_device_get_name(), g_udev_device_get_number(),
+ * g_udev_device_get_sysfs_path(), g_udev_device_get_driver(),
+ * g_udev_device_get_action(), g_udev_device_get_seqnum(),
+ * g_udev_device_get_device_type(), g_udev_device_get_device_number(),
+ * g_udev_device_get_device_file(),
+ * g_udev_device_get_device_file_symlinks().
+ *
+ * To navigate the device tree, use g_udev_device_get_parent() and
+ * g_udev_device_get_parent_with_subsystem().
+ *
+ * To access udev properties for the device, use
+ * g_udev_device_get_property_keys(),
+ * g_udev_device_has_property(),
+ * g_udev_device_get_property(),
+ * g_udev_device_get_property_as_int(),
+ * g_udev_device_get_property_as_uint64(),
+ * g_udev_device_get_property_as_double(),
+ * g_udev_device_get_property_as_boolean() and
+ * g_udev_device_get_property_as_strv().
+ *
+ * To access sysfs attributes for the device, use
+ * g_udev_device_get_sysfs_attr_keys(),
+ * g_udev_device_has_sysfs_attr(),
+ * g_udev_device_get_sysfs_attr(),
+ * g_udev_device_get_sysfs_attr_as_int(),
+ * g_udev_device_get_sysfs_attr_as_uint64(),
+ * g_udev_device_get_sysfs_attr_as_double(),
+ * g_udev_device_get_sysfs_attr_as_boolean() and
+ * g_udev_device_get_sysfs_attr_as_strv().
+ *
+ * Note that all getters on #GUdevDevice are non-reffing – returned
+ * values are owned by the object, should not be freed and are only
+ * valid as long as the object is alive.
+ *
+ * By design, #GUdevDevice will not react to changes for a device – it
+ * only contains a snapshot of information when the #GUdevDevice
+ * object was created. To work with changes, you typically connect to
+ * the #GUdevClient::uevent signal on a #GUdevClient and get a new
+ * #GUdevDevice whenever an event happens.
+ */
+
+struct _GUdevDevicePrivate
+{
+ struct udev_device *udevice;
+
+ /* computed ondemand and cached */
+ gchar **device_file_symlinks;
+ gchar **property_keys;
+ gchar **sysfs_attr_keys;
+ gchar **tags;
+ GHashTable *prop_strvs;
+ GHashTable *sysfs_attr_strvs;
+};
+
+G_DEFINE_TYPE (GUdevDevice, g_udev_device, G_TYPE_OBJECT)
+
+static void
+g_udev_device_finalize (GObject *object)
+{
+ GUdevDevice *device = G_UDEV_DEVICE (object);
+
+ g_strfreev (device->priv->device_file_symlinks);
+ g_strfreev (device->priv->property_keys);
+ g_strfreev (device->priv->sysfs_attr_keys);
+ g_strfreev (device->priv->tags);
+
+ if (device->priv->udevice != NULL)
+ udev_device_unref (device->priv->udevice);
+
+ if (device->priv->prop_strvs != NULL)
+ g_hash_table_unref (device->priv->prop_strvs);
+
+ if (device->priv->sysfs_attr_strvs != NULL)
+ g_hash_table_unref (device->priv->sysfs_attr_strvs);
+
+ if (G_OBJECT_CLASS (g_udev_device_parent_class)->finalize != NULL)
+ (* G_OBJECT_CLASS (g_udev_device_parent_class)->finalize) (object);
+}
+
+static void
+g_udev_device_class_init (GUdevDeviceClass *klass)
+{
+ GObjectClass *gobject_class = (GObjectClass *) klass;
+
+ gobject_class->finalize = g_udev_device_finalize;
+
+ g_type_class_add_private (klass, sizeof (GUdevDevicePrivate));
+}
+
+static void
+g_udev_device_init (GUdevDevice *device)
+{
+ device->priv = G_TYPE_INSTANCE_GET_PRIVATE (device,
+ G_UDEV_TYPE_DEVICE,
+ GUdevDevicePrivate);
+}
+
+
+GUdevDevice *
+_g_udev_device_new (struct udev_device *udevice)
+{
+ GUdevDevice *device;
+
+ device = G_UDEV_DEVICE (g_object_new (G_UDEV_TYPE_DEVICE, NULL));
+ device->priv->udevice = udev_device_ref (udevice);
+
+ return device;
+}
+
+/**
+ * g_udev_device_get_subsystem:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the subsystem for @device.
+ *
+ * Returns: The subsystem for @device.
+ */
+const gchar *
+g_udev_device_get_subsystem (GUdevDevice *device)
+{
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+ return udev_device_get_subsystem (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_devtype:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the device type for @device.
+ *
+ * Returns: The devtype for @device.
+ */
+const gchar *
+g_udev_device_get_devtype (GUdevDevice *device)
+{
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+ return udev_device_get_devtype (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_name:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the name of @device, e.g. "sda3".
+ *
+ * Returns: The name of @device.
+ */
+const gchar *
+g_udev_device_get_name (GUdevDevice *device)
+{
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+ return udev_device_get_sysname (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_number:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the number of @device, e.g. "3" if g_udev_device_get_name() returns "sda3".
+ *
+ * Returns: The number of @device.
+ */
+const gchar *
+g_udev_device_get_number (GUdevDevice *device)
+{
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+ return udev_device_get_sysnum (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_sysfs_path:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the sysfs path for @device.
+ *
+ * Returns: The sysfs path for @device.
+ */
+const gchar *
+g_udev_device_get_sysfs_path (GUdevDevice *device)
+{
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+ return udev_device_get_syspath (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_driver:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the name of the driver used for @device.
+ *
+ * Returns: (nullable): The name of the driver for @device or %NULL if
+ * unknown.
+ */
+const gchar *
+g_udev_device_get_driver (GUdevDevice *device)
+{
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+ return udev_device_get_driver (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_action:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the most recent action (e.g. "add", "remove", "change", etc.) for @device.
+ *
+ * Returns: An action string.
+ */
+const gchar *
+g_udev_device_get_action (GUdevDevice *device)
+{
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+ return udev_device_get_action (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_seqnum:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the most recent sequence number for @device.
+ *
+ * Returns: A sequence number.
+ */
+guint64
+g_udev_device_get_seqnum (GUdevDevice *device)
+{
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
+ return udev_device_get_seqnum (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_device_type:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the type of the device file, if any, for @device.
+ *
+ * Returns: The device number for @device or #G_UDEV_DEVICE_TYPE_NONE if the device does not have a device file.
+ */
+GUdevDeviceType
+g_udev_device_get_device_type (GUdevDevice *device)
+{
+ struct stat stat_buf;
+ const gchar *device_file;
+ GUdevDeviceType type;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), G_UDEV_DEVICE_TYPE_NONE);
+
+ type = G_UDEV_DEVICE_TYPE_NONE;
+
+ /* TODO: would be better to have support for this in libudev... */
+
+ device_file = g_udev_device_get_device_file (device);
+ if (device_file == NULL)
+ goto out;
+
+ if (stat (device_file, &stat_buf) != 0)
+ goto out;
+
+ if (S_ISBLK (stat_buf.st_mode))
+ type = G_UDEV_DEVICE_TYPE_BLOCK;
+ else if (S_ISCHR (stat_buf.st_mode))
+ type = G_UDEV_DEVICE_TYPE_CHAR;
+
+ out:
+ return type;
+}
+
+/**
+ * g_udev_device_get_device_number:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the device number, if any, for @device.
+ *
+ * Returns: The device number for @device or 0 if unknown.
+ */
+GUdevDeviceNumber
+g_udev_device_get_device_number (GUdevDevice *device)
+{
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
+ return udev_device_get_devnum (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_device_file:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the device file for @device.
+ *
+ * Returns: (nullable): The device file for @device or %NULL if no
+ * device file exists.
+ */
+const gchar *
+g_udev_device_get_device_file (GUdevDevice *device)
+{
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+ return udev_device_get_devnode (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_device_file_symlinks:
+ * @device: A #GUdevDevice.
+ *
+ * Gets a list of symlinks (in <literal>/dev</literal>) that points to
+ * the device file for @device.
+ *
+ * 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.
+ */
+const gchar * const *
+g_udev_device_get_device_file_symlinks (GUdevDevice *device)
+{
+ struct udev_list_entry *l;
+ GPtrArray *p;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+
+ if (device->priv->device_file_symlinks != NULL)
+ goto out;
+
+ p = g_ptr_array_new ();
+ for (l = udev_device_get_devlinks_list_entry (device->priv->udevice); l != NULL; l = udev_list_entry_get_next (l))
+ {
+ g_ptr_array_add (p, g_strdup (udev_list_entry_get_name (l)));
+ }
+ g_ptr_array_add (p, NULL);
+ device->priv->device_file_symlinks = (gchar **) g_ptr_array_free (p, FALSE);
+
+ out:
+ return (const gchar * const *) device->priv->device_file_symlinks;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+/**
+ * g_udev_device_get_parent:
+ * @device: A #GUdevDevice.
+ *
+ * Gets the immediate parent of @device, if any.
+ *
+ * Returns: (nullable) (transfer full): A #GUdevDevice or %NULL if
+ * @device has no parent. Free with g_object_unref().
+ */
+GUdevDevice *
+g_udev_device_get_parent (GUdevDevice *device)
+{
+ GUdevDevice *ret;
+ struct udev_device *udevice;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+
+ ret = NULL;
+
+ udevice = udev_device_get_parent (device->priv->udevice);
+ if (udevice == NULL)
+ goto out;
+
+ ret = _g_udev_device_new (udevice);
+
+ out:
+ return ret;
+}
+
+/**
+ * g_udev_device_get_parent_with_subsystem:
+ * @device: A #GUdevDevice.
+ * @subsystem: The subsystem of the parent to get.
+ * @devtype: (allow-none): The devtype of the parent to get or %NULL.
+ *
+ * Walks up the chain of parents of @device and returns the first
+ * device encountered where @subsystem and @devtype matches, if any.
+ *
+ * Returns: (nullable) (transfer full): A #GUdevDevice or %NULL if
+ * @device has no parent with @subsystem and @devtype. Free with
+ * g_object_unref().
+ */
+GUdevDevice *
+g_udev_device_get_parent_with_subsystem (GUdevDevice *device,
+ const gchar *subsystem,
+ const gchar *devtype)
+{
+ GUdevDevice *ret;
+ struct udev_device *udevice;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+ g_return_val_if_fail (subsystem != NULL, NULL);
+
+ ret = NULL;
+
+ udevice = udev_device_get_parent_with_subsystem_devtype (device->priv->udevice,
+ subsystem,
+ devtype);
+ if (udevice == NULL)
+ goto out;
+
+ ret = _g_udev_device_new (udevice);
+
+ out:
+ return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+/**
+ * g_udev_device_get_property_keys:
+ * @device: A #GUdevDevice.
+ *
+ * Gets all keys for properties on @device.
+ *
+ * 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.
+ */
+const gchar* const *
+g_udev_device_get_property_keys (GUdevDevice *device)
+{
+ struct udev_list_entry *l;
+ GPtrArray *p;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+
+ if (device->priv->property_keys != NULL)
+ goto out;
+
+ p = g_ptr_array_new ();
+ for (l = udev_device_get_properties_list_entry (device->priv->udevice); l != NULL; l = udev_list_entry_get_next (l))
+ {
+ g_ptr_array_add (p, g_strdup (udev_list_entry_get_name (l)));
+ }
+ g_ptr_array_add (p, NULL);
+ device->priv->property_keys = (gchar **) g_ptr_array_free (p, FALSE);
+
+ out:
+ return (const gchar * const *) device->priv->property_keys;
+}
+
+
+/**
+ * g_udev_device_has_property:
+ * @device: A #GUdevDevice.
+ * @key: Name of property.
+ *
+ * Check if a the property with the given key exists.
+ *
+ * Returns: %TRUE only if the value for @key exist.
+ */
+gboolean
+g_udev_device_has_property (GUdevDevice *device,
+ const gchar *key)
+{
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
+ g_return_val_if_fail (key != NULL, FALSE);
+ return udev_device_get_property_value (device->priv->udevice, key) != NULL;
+}
+
+/**
+ * g_udev_device_get_property:
+ * @device: A #GUdevDevice.
+ * @key: Name of property.
+ *
+ * Look up the value for @key on @device.
+ *
+ * Returns: (nullable): The value for @key or %NULL if @key doesn't
+ * exist on @device. Do not free this string, it is owned by @device.
+ */
+const gchar *
+g_udev_device_get_property (GUdevDevice *device,
+ const gchar *key)
+{
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+ return udev_device_get_property_value (device->priv->udevice, key);
+}
+
+/**
+ * g_udev_device_get_property_as_int:
+ * @device: A #GUdevDevice.
+ * @key: Name of property.
+ *
+ * Look up the value for @key on @device and convert it to an integer
+ * using strtol().
+ *
+ * Returns: The value for @key or 0 if @key doesn't exist or
+ * isn't an integer.
+ */
+gint
+g_udev_device_get_property_as_int (GUdevDevice *device,
+ const gchar *key)
+{
+ gint result;
+ const gchar *s;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
+ g_return_val_if_fail (key != NULL, 0);
+
+ result = 0;
+ s = g_udev_device_get_property (device, key);
+ if (s == NULL)
+ goto out;
+
+ result = strtol (s, NULL, 0);
+out:
+ return result;
+}
+
+/**
+ * g_udev_device_get_property_as_uint64:
+ * @device: A #GUdevDevice.
+ * @key: Name of property.
+ *
+ * Look up the value for @key on @device and convert it to an unsigned
+ * 64-bit integer using g_ascii_strtoull().
+ *
+ * Returns: The value for @key or 0 if @key doesn't exist or isn't a
+ * #guint64.
+ */
+guint64
+g_udev_device_get_property_as_uint64 (GUdevDevice *device,
+ const gchar *key)
+{
+ guint64 result;
+ const gchar *s;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
+ g_return_val_if_fail (key != NULL, 0);
+
+ result = 0;
+ s = g_udev_device_get_property (device, key);
+ if (s == NULL)
+ goto out;
+
+ result = g_ascii_strtoull (s, NULL, 0);
+out:
+ return result;
+}
+
+/**
+ * g_udev_device_get_property_as_double:
+ * @device: A #GUdevDevice.
+ * @key: Name of property.
+ *
+ * Look up the value for @key on @device and convert it to a double
+ * precision floating point number using strtod().
+ *
+ * Returns: The value for @key or 0.0 if @key doesn't exist or isn't a
+ * #gdouble.
+ */
+gdouble
+g_udev_device_get_property_as_double (GUdevDevice *device,
+ const gchar *key)
+{
+ gdouble result;
+ const gchar *s;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0.0);
+ g_return_val_if_fail (key != NULL, 0.0);
+
+ result = 0.0;
+ s = g_udev_device_get_property (device, key);
+ if (s == NULL)
+ goto out;
+
+ result = strtod (s, NULL);
+out:
+ return result;
+}
+
+/**
+ * g_udev_device_get_property_as_boolean:
+ * @device: A #GUdevDevice.
+ * @key: Name of property.
+ *
+ * Look up the value for @key on @device and convert it to an
+ * boolean. This is done by doing a case-insensitive string comparison
+ * on the string value against "1" and "true".
+ *
+ * Returns: The value for @key or %FALSE if @key doesn't exist or
+ * isn't a #gboolean.
+ */
+gboolean
+g_udev_device_get_property_as_boolean (GUdevDevice *device,
+ const gchar *key)
+{
+ gboolean result;
+ const gchar *s;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
+ g_return_val_if_fail (key != NULL, FALSE);
+
+ result = FALSE;
+ s = g_udev_device_get_property (device, key);
+ if (s == NULL)
+ goto out;
+
+ if (strcmp (s, "1") == 0 || g_ascii_strcasecmp (s, "true") == 0)
+ result = TRUE;
+ out:
+ return result;
+}
+
+static gchar **
+split_at_whitespace (const gchar *s)
+{
+ gchar **result;
+ guint n;
+ guint m;
+
+ result = g_strsplit_set (s, " \v\t\r\n", 0);
+
+ /* remove empty strings, thanks GLib */
+ for (n = 0; result[n] != NULL; n++)
+ {
+ if (strlen (result[n]) == 0)
+ {
+ g_free (result[n]);
+ for (m = n; result[m] != NULL; m++)
+ result[m] = result[m + 1];
+ n--;
+ }
+ }
+
+ return result;
+}
+
+/**
+ * g_udev_device_get_property_as_strv:
+ * @device: A #GUdevDevice.
+ * @key: Name of property.
+ *
+ * Look up the value for @key on @device and return the result of
+ * splitting it into non-empty tokens split at white space (only space
+ * (' '), form-feed ('\f'), newline ('\n'), carriage return ('\r'),
+ * horizontal tab ('\t'), and vertical tab ('\v') are considered; the
+ * locale is not taken into account).
+ *
+ * Returns: (nullable) (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.
+ */
+const gchar* const *
+g_udev_device_get_property_as_strv (GUdevDevice *device,
+ const gchar *key)
+{
+ gchar **result;
+ const gchar *s;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+
+ if (device->priv->prop_strvs != NULL)
+ {
+ result = g_hash_table_lookup (device->priv->prop_strvs, key);
+ if (result != NULL)
+ goto out;
+ }
+
+ result = NULL;
+ s = g_udev_device_get_property (device, key);
+ if (s == NULL)
+ goto out;
+
+ result = split_at_whitespace (s);
+ if (result == NULL)
+ goto out;
+
+ if (device->priv->prop_strvs == NULL)
+ device->priv->prop_strvs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_strfreev);
+ g_hash_table_insert (device->priv->prop_strvs, g_strdup (key), result);
+
+out:
+ return (const gchar* const *) result;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+/**
+ * g_udev_device_get_sysfs_attr_keys:
+ * @device: A #GUdevDevice.
+ *
+ * Gets all keys for sysfs attributes on @device.
+ *
+ * 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.
+ */
+const gchar * const *
+g_udev_device_get_sysfs_attr_keys (GUdevDevice *device)
+{
+ struct udev_list_entry *l;
+ GPtrArray *p;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+
+ if (device->priv->sysfs_attr_keys != NULL)
+ goto out;
+
+ p = g_ptr_array_new ();
+ for (l = udev_device_get_sysattr_list_entry (device->priv->udevice); l != NULL; l = udev_list_entry_get_next (l))
+ {
+ g_ptr_array_add (p, g_strdup (udev_list_entry_get_name (l)));
+ }
+ g_ptr_array_add (p, NULL);
+ device->priv->sysfs_attr_keys = (gchar **) g_ptr_array_free (p, FALSE);
+
+ out:
+ return (const gchar * const *) device->priv->sysfs_attr_keys;
+}
+
+/**
+ * g_udev_device_has_sysfs_attr:
+ * @device: A #GUdevDevice.
+ * @key: Name of sysfs attribute.
+ *
+ * Check if a the sysfs attribute with the given key exists.
+ *
+ * Returns: %TRUE only if the value for @key exist.
+ */
+gboolean
+g_udev_device_has_sysfs_attr (GUdevDevice *device,
+ const gchar *key)
+{
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
+ g_return_val_if_fail (key != NULL, FALSE);
+ return udev_device_get_sysattr_value (device->priv->udevice, key) != NULL;
+}
+
+/**
+ * g_udev_device_get_sysfs_attr:
+ * @device: A #GUdevDevice.
+ * @name: Name of the sysfs attribute.
+ *
+ * Look up the sysfs attribute with @name on @device.
+ *
+ * Returns: (nullable): The value of the sysfs attribute or %NULL if
+ * there is no such attribute. Do not free this string, it is owned by
+ * @device.
+ */
+const gchar *
+g_udev_device_get_sysfs_attr (GUdevDevice *device,
+ const gchar *name)
+{
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+ return udev_device_get_sysattr_value (device->priv->udevice, name);
+}
+
+/**
+ * g_udev_device_get_sysfs_attr_as_int:
+ * @device: A #GUdevDevice.
+ * @name: Name of the sysfs attribute.
+ *
+ * Look up the sysfs attribute with @name on @device and convert it to an integer
+ * using strtol().
+ *
+ * Returns: The value of the sysfs attribute or 0 if there is no such
+ * attribute.
+ */
+gint
+g_udev_device_get_sysfs_attr_as_int (GUdevDevice *device,
+ const gchar *name)
+{
+ gint result;
+ const gchar *s;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
+ g_return_val_if_fail (name != NULL, 0);
+
+ result = 0;
+ s = g_udev_device_get_sysfs_attr (device, name);
+ if (s == NULL)
+ goto out;
+
+ result = strtol (s, NULL, 0);
+out:
+ return result;
+}
+
+/**
+ * g_udev_device_get_sysfs_attr_as_uint64:
+ * @device: A #GUdevDevice.
+ * @name: Name of the sysfs attribute.
+ *
+ * Look up the sysfs attribute with @name on @device and convert it to an unsigned
+ * 64-bit integer using g_ascii_strtoull().
+ *
+ * Returns: The value of the sysfs attribute or 0 if there is no such
+ * attribute.
+ */
+guint64
+g_udev_device_get_sysfs_attr_as_uint64 (GUdevDevice *device,
+ const gchar *name)
+{
+ guint64 result;
+ const gchar *s;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
+ g_return_val_if_fail (name != NULL, 0);
+
+ result = 0;
+ s = g_udev_device_get_sysfs_attr (device, name);
+ if (s == NULL)
+ goto out;
+
+ result = g_ascii_strtoull (s, NULL, 0);
+out:
+ return result;
+}
+
+/**
+ * g_udev_device_get_sysfs_attr_as_double:
+ * @device: A #GUdevDevice.
+ * @name: Name of the sysfs attribute.
+ *
+ * Look up the sysfs attribute with @name on @device and convert it to a double
+ * precision floating point number using strtod().
+ *
+ * Returns: The value of the sysfs attribute or 0.0 if there is no such
+ * attribute.
+ */
+gdouble
+g_udev_device_get_sysfs_attr_as_double (GUdevDevice *device,
+ const gchar *name)
+{
+ gdouble result;
+ const gchar *s;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0.0);
+ g_return_val_if_fail (name != NULL, 0.0);
+
+ result = 0.0;
+ s = g_udev_device_get_sysfs_attr (device, name);
+ if (s == NULL)
+ goto out;
+
+ result = strtod (s, NULL);
+out:
+ return result;
+}
+
+/**
+ * g_udev_device_get_sysfs_attr_as_boolean:
+ * @device: A #GUdevDevice.
+ * @name: Name of the sysfs attribute.
+ *
+ * Look up the sysfs attribute with @name on @device and convert it to an
+ * boolean. This is done by doing a case-insensitive string comparison
+ * on the string value against "1" and "true".
+ *
+ * Returns: The value of the sysfs attribute or %FALSE if there is no such
+ * attribute.
+ */
+gboolean
+g_udev_device_get_sysfs_attr_as_boolean (GUdevDevice *device,
+ const gchar *name)
+{
+ gboolean result;
+ const gchar *s;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+
+ result = FALSE;
+ s = g_udev_device_get_sysfs_attr (device, name);
+ if (s == NULL)
+ goto out;
+
+ if (strcmp (s, "1") == 0 || g_ascii_strcasecmp (s, "true") == 0)
+ result = TRUE;
+ out:
+ return result;
+}
+
+/**
+ * g_udev_device_get_sysfs_attr_as_strv:
+ * @device: A #GUdevDevice.
+ * @name: Name of the sysfs attribute.
+ *
+ * Look up the sysfs attribute with @name on @device and return the result of
+ * splitting it into non-empty tokens split at white space (only space (' '),
+ * form-feed ('\f'), newline ('\n'), carriage return ('\r'), horizontal
+ * tab ('\t'), and vertical tab ('\v') are considered; the locale is
+ * not taken into account).
+ *
+ * Returns: (nullable) (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.
+ */
+const gchar * const *
+g_udev_device_get_sysfs_attr_as_strv (GUdevDevice *device,
+ const gchar *name)
+{
+ gchar **result;
+ const gchar *s;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+
+ if (device->priv->sysfs_attr_strvs != NULL)
+ {
+ result = g_hash_table_lookup (device->priv->sysfs_attr_strvs, name);
+ if (result != NULL)
+ goto out;
+ }
+
+ result = NULL;
+ s = g_udev_device_get_sysfs_attr (device, name);
+ if (s == NULL)
+ goto out;
+
+ result = split_at_whitespace (s);
+ if (result == NULL)
+ goto out;
+
+ if (device->priv->sysfs_attr_strvs == NULL)
+ device->priv->sysfs_attr_strvs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_strfreev);
+ g_hash_table_insert (device->priv->sysfs_attr_strvs, g_strdup (name), result);
+
+out:
+ return (const gchar* const *) result;
+}
+
+/**
+ * g_udev_device_get_tags:
+ * @device: A #GUdevDevice.
+ *
+ * Gets all tags for @device.
+ *
+ * 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.
+ *
+ * Since: 165
+ */
+const gchar* const *
+g_udev_device_get_tags (GUdevDevice *device)
+{
+ struct udev_list_entry *l;
+ GPtrArray *p;
+
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
+
+ if (device->priv->tags != NULL)
+ goto out;
+
+ p = g_ptr_array_new ();
+ for (l = udev_device_get_tags_list_entry (device->priv->udevice); l != NULL; l = udev_list_entry_get_next (l))
+ {
+ g_ptr_array_add (p, g_strdup (udev_list_entry_get_name (l)));
+ }
+ g_ptr_array_add (p, NULL);
+ device->priv->tags = (gchar **) g_ptr_array_free (p, FALSE);
+
+ out:
+ return (const gchar * const *) device->priv->tags;
+}
+
+/**
+ * g_udev_device_get_is_initialized:
+ * @device: A #GUdevDevice.
+ *
+ * Gets whether @device has been initalized.
+ *
+ * Returns: Whether @device has been initialized.
+ *
+ * Since: 165
+ */
+gboolean
+g_udev_device_get_is_initialized (GUdevDevice *device)
+{
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
+ return udev_device_get_is_initialized (device->priv->udevice);
+}
+
+/**
+ * g_udev_device_get_usec_since_initialized:
+ * @device: A #GUdevDevice.
+ *
+ * Gets number of micro-seconds since @device was initialized.
+ *
+ * This only works for devices with properties in the udev
+ * database. All other devices return 0.
+ *
+ * Returns: Number of micro-seconds since @device was initialized or 0 if unknown.
+ *
+ * Since: 165
+ */
+guint64
+g_udev_device_get_usec_since_initialized (GUdevDevice *device)
+{
+ g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
+ return udev_device_get_usec_since_initialized (device->priv->udevice);
+}
diff --git a/gudev/gudevdevice.h b/gudev/gudevdevice.h
new file mode 100644
index 0000000..72ec180
--- /dev/null
+++ b/gudev/gudevdevice.h
@@ -0,0 +1,130 @@
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H)
+#error "Only <gudev/gudev.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef __G_UDEV_DEVICE_H__
+#define __G_UDEV_DEVICE_H__
+
+#include <gudev/gudevtypes.h>
+
+G_BEGIN_DECLS
+
+#define G_UDEV_TYPE_DEVICE (g_udev_device_get_type ())
+#define G_UDEV_DEVICE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_UDEV_TYPE_DEVICE, GUdevDevice))
+#define G_UDEV_DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_UDEV_TYPE_DEVICE, GUdevDeviceClass))
+#define G_UDEV_IS_DEVICE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_UDEV_TYPE_DEVICE))
+#define G_UDEV_IS_DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_UDEV_TYPE_DEVICE))
+#define G_UDEV_DEVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_UDEV_TYPE_DEVICE, GUdevDeviceClass))
+
+typedef struct _GUdevDeviceClass GUdevDeviceClass;
+typedef struct _GUdevDevicePrivate GUdevDevicePrivate;
+
+/**
+ * GUdevDevice:
+ *
+ * The #GUdevDevice struct is opaque and should not be accessed directly.
+ */
+struct _GUdevDevice
+{
+ GObject parent;
+
+ /*< private >*/
+ GUdevDevicePrivate *priv;
+};
+
+/**
+ * GUdevDeviceClass:
+ * @parent_class: Parent class.
+ *
+ * Class structure for #GUdevDevice.
+ */
+struct _GUdevDeviceClass
+{
+ GObjectClass parent_class;
+
+ /*< private >*/
+ /* Padding for future expansion */
+ void (*reserved1) (void);
+ void (*reserved2) (void);
+ void (*reserved3) (void);
+ void (*reserved4) (void);
+ void (*reserved5) (void);
+ void (*reserved6) (void);
+ void (*reserved7) (void);
+ void (*reserved8) (void);
+};
+
+GType g_udev_device_get_type (void) G_GNUC_CONST;
+gboolean g_udev_device_get_is_initialized (GUdevDevice *device);
+guint64 g_udev_device_get_usec_since_initialized (GUdevDevice *device);
+const gchar *g_udev_device_get_subsystem (GUdevDevice *device);
+const gchar *g_udev_device_get_devtype (GUdevDevice *device);
+const gchar *g_udev_device_get_name (GUdevDevice *device);
+const gchar *g_udev_device_get_number (GUdevDevice *device);
+const gchar *g_udev_device_get_sysfs_path (GUdevDevice *device);
+const gchar *g_udev_device_get_driver (GUdevDevice *device);
+const gchar *g_udev_device_get_action (GUdevDevice *device);
+guint64 g_udev_device_get_seqnum (GUdevDevice *device);
+GUdevDeviceType g_udev_device_get_device_type (GUdevDevice *device);
+GUdevDeviceNumber g_udev_device_get_device_number (GUdevDevice *device);
+const gchar *g_udev_device_get_device_file (GUdevDevice *device);
+const gchar* const *g_udev_device_get_device_file_symlinks (GUdevDevice *device);
+GUdevDevice *g_udev_device_get_parent (GUdevDevice *device);
+GUdevDevice *g_udev_device_get_parent_with_subsystem (GUdevDevice *device,
+ const gchar *subsystem,
+ const gchar *devtype);
+const gchar* const *g_udev_device_get_property_keys (GUdevDevice *device);
+gboolean g_udev_device_has_property (GUdevDevice *device,
+ const gchar *key);
+const gchar *g_udev_device_get_property (GUdevDevice *device,
+ const gchar *key);
+gint g_udev_device_get_property_as_int (GUdevDevice *device,
+ const gchar *key);
+guint64 g_udev_device_get_property_as_uint64 (GUdevDevice *device,
+ const gchar *key);
+gdouble g_udev_device_get_property_as_double (GUdevDevice *device,
+ const gchar *key);
+gboolean g_udev_device_get_property_as_boolean (GUdevDevice *device,
+ const gchar *key);
+const gchar* const *g_udev_device_get_property_as_strv (GUdevDevice *device,
+ const gchar *key);
+
+const gchar* const *g_udev_device_get_sysfs_attr_keys (GUdevDevice *device);
+gboolean g_udev_device_has_sysfs_attr (GUdevDevice *device,
+ const gchar *key);
+const gchar *g_udev_device_get_sysfs_attr (GUdevDevice *device,
+ const gchar *name);
+gint g_udev_device_get_sysfs_attr_as_int (GUdevDevice *device,
+ const gchar *name);
+guint64 g_udev_device_get_sysfs_attr_as_uint64 (GUdevDevice *device,
+ const gchar *name);
+gdouble g_udev_device_get_sysfs_attr_as_double (GUdevDevice *device,
+ const gchar *name);
+gboolean g_udev_device_get_sysfs_attr_as_boolean (GUdevDevice *device,
+ const gchar *name);
+const gchar* const *g_udev_device_get_sysfs_attr_as_strv (GUdevDevice *device,
+ const gchar *name);
+const gchar* const *g_udev_device_get_tags (GUdevDevice *device);
+
+G_END_DECLS
+
+#endif /* __G_UDEV_DEVICE_H__ */
diff --git a/gudev/gudevenumerator.c b/gudev/gudevenumerator.c
new file mode 100644
index 0000000..1fb3098
--- /dev/null
+++ b/gudev/gudevenumerator.c
@@ -0,0 +1,429 @@
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008-2010 David Zeuthen <davidz@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "gudevclient.h"
+#include "gudevenumerator.h"
+#include "gudevdevice.h"
+#include "gudevmarshal.h"
+#include "gudevprivate.h"
+
+/**
+ * SECTION:gudevenumerator
+ * @short_description: Lookup and sort devices
+ *
+ * #GUdevEnumerator is used to lookup and sort devices.
+ *
+ * Since: 165
+ */
+
+struct _GUdevEnumeratorPrivate
+{
+ GUdevClient *client;
+ struct udev_enumerate *e;
+};
+
+enum
+{
+ PROP_0,
+ PROP_CLIENT,
+};
+
+G_DEFINE_TYPE (GUdevEnumerator, g_udev_enumerator, G_TYPE_OBJECT)
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+g_udev_enumerator_finalize (GObject *object)
+{
+ GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object);
+
+ if (enumerator->priv->client != NULL)
+ {
+ g_object_unref (enumerator->priv->client);
+ enumerator->priv->client = NULL;
+ }
+
+ if (enumerator->priv->e != NULL)
+ {
+ udev_enumerate_unref (enumerator->priv->e);
+ enumerator->priv->e = NULL;
+ }
+
+ if (G_OBJECT_CLASS (g_udev_enumerator_parent_class)->finalize != NULL)
+ G_OBJECT_CLASS (g_udev_enumerator_parent_class)->finalize (object);
+}
+
+static void
+g_udev_enumerator_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object);
+
+ switch (prop_id)
+ {
+ case PROP_CLIENT:
+ if (enumerator->priv->client != NULL)
+ g_object_unref (enumerator->priv->client);
+ enumerator->priv->client = g_value_dup_object (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+g_udev_enumerator_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object);
+
+ switch (prop_id)
+ {
+ case PROP_CLIENT:
+ g_value_set_object (value, enumerator->priv->client);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+g_udev_enumerator_constructed (GObject *object)
+{
+ GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object);
+
+ g_assert (G_UDEV_IS_CLIENT (enumerator->priv->client));
+
+ enumerator->priv->e = udev_enumerate_new (_g_udev_client_get_udev (enumerator->priv->client));
+
+ if (G_OBJECT_CLASS (g_udev_enumerator_parent_class)->constructed != NULL)
+ G_OBJECT_CLASS (g_udev_enumerator_parent_class)->constructed (object);
+}
+
+static void
+g_udev_enumerator_class_init (GUdevEnumeratorClass *klass)
+{
+ GObjectClass *gobject_class = (GObjectClass *) klass;
+
+ gobject_class->finalize = g_udev_enumerator_finalize;
+ gobject_class->set_property = g_udev_enumerator_set_property;
+ gobject_class->get_property = g_udev_enumerator_get_property;
+ gobject_class->constructed = g_udev_enumerator_constructed;
+
+ /**
+ * GUdevEnumerator:client:
+ *
+ * The #GUdevClient to enumerate devices from.
+ *
+ * Since: 165
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_CLIENT,
+ g_param_spec_object ("client",
+ "The client to enumerate devices from",
+ "The client to enumerate devices from",
+ G_UDEV_TYPE_CLIENT,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE));
+
+ g_type_class_add_private (klass, sizeof (GUdevEnumeratorPrivate));
+}
+
+static void
+g_udev_enumerator_init (GUdevEnumerator *enumerator)
+{
+ enumerator->priv = G_TYPE_INSTANCE_GET_PRIVATE (enumerator,
+ G_UDEV_TYPE_ENUMERATOR,
+ GUdevEnumeratorPrivate);
+}
+
+/**
+ * g_udev_enumerator_new:
+ * @client: A #GUdevClient to enumerate devices from.
+ *
+ * Constructs a #GUdevEnumerator object that can be used to enumerate
+ * and sort devices. Use the add_match_*() and add_nomatch_*() methods
+ * and execute the query to get a list of devices with
+ * g_udev_enumerator_execute().
+ *
+ * Returns: A new #GUdevEnumerator object. Free with g_object_unref().
+ *
+ * Since: 165
+ */
+GUdevEnumerator *
+g_udev_enumerator_new (GUdevClient *client)
+{
+ g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
+ return G_UDEV_ENUMERATOR (g_object_new (G_UDEV_TYPE_ENUMERATOR, "client", client, NULL));
+}
+
+
+/**
+ * g_udev_enumerator_add_match_subsystem:
+ * @enumerator: A #GUdevEnumerator.
+ * @subsystem: Wildcard for subsystem name e.g. 'scsi' or 'a*'.
+ *
+ * All returned devices will match the given @subsystem.
+ *
+ * Returns: (transfer none): The passed in @enumerator.
+ *
+ * Since: 165
+ */
+GUdevEnumerator *
+g_udev_enumerator_add_match_subsystem (GUdevEnumerator *enumerator,
+ const gchar *subsystem)
+{
+ g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
+ g_return_val_if_fail (subsystem != NULL, NULL);
+ udev_enumerate_add_match_subsystem (enumerator->priv->e, subsystem);
+ return enumerator;
+}
+
+/**
+ * g_udev_enumerator_add_nomatch_subsystem:
+ * @enumerator: A #GUdevEnumerator.
+ * @subsystem: Wildcard for subsystem name e.g. 'scsi' or 'a*'.
+ *
+ * All returned devices will not match the given @subsystem.
+ *
+ * Returns: (transfer none): The passed in @enumerator.
+ *
+ * Since: 165
+ */
+GUdevEnumerator *
+g_udev_enumerator_add_nomatch_subsystem (GUdevEnumerator *enumerator,
+ const gchar *subsystem)
+{
+ g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
+ g_return_val_if_fail (subsystem != NULL, NULL);
+ udev_enumerate_add_nomatch_subsystem (enumerator->priv->e, subsystem);
+ return enumerator;
+}
+
+/**
+ * g_udev_enumerator_add_match_sysfs_attr:
+ * @enumerator: A #GUdevEnumerator.
+ * @name: Wildcard filter for sysfs attribute key.
+ * @value: Wildcard filter for sysfs attribute value.
+ *
+ * All returned devices will have a sysfs attribute matching the given @name and @value.
+ *
+ * Returns: (transfer none): The passed in @enumerator.
+ *
+ * Since: 165
+ */
+GUdevEnumerator *
+g_udev_enumerator_add_match_sysfs_attr (GUdevEnumerator *enumerator,
+ const gchar *name,
+ const gchar *value)
+{
+ g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+ g_return_val_if_fail (value != NULL, NULL);
+ udev_enumerate_add_match_sysattr (enumerator->priv->e, name, value);
+ return enumerator;
+}
+
+/**
+ * g_udev_enumerator_add_nomatch_sysfs_attr:
+ * @enumerator: A #GUdevEnumerator.
+ * @name: Wildcard filter for sysfs attribute key.
+ * @value: Wildcard filter for sysfs attribute value.
+ *
+ * All returned devices will not have a sysfs attribute matching the given @name and @value.
+ *
+ * Returns: (transfer none): The passed in @enumerator.
+ *
+ * Since: 165
+ */
+GUdevEnumerator *
+g_udev_enumerator_add_nomatch_sysfs_attr (GUdevEnumerator *enumerator,
+ const gchar *name,
+ const gchar *value)
+{
+ g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+ g_return_val_if_fail (value != NULL, NULL);
+ udev_enumerate_add_nomatch_sysattr (enumerator->priv->e, name, value);
+ return enumerator;
+}
+
+/**
+ * g_udev_enumerator_add_match_property:
+ * @enumerator: A #GUdevEnumerator.
+ * @name: Wildcard filter for property name.
+ * @value: Wildcard filter for property value.
+ *
+ * All returned devices will have a property matching the given @name and @value.
+ *
+ * Returns: (transfer none): The passed in @enumerator.
+ *
+ * Since: 165
+ */
+GUdevEnumerator *
+g_udev_enumerator_add_match_property (GUdevEnumerator *enumerator,
+ const gchar *name,
+ const gchar *value)
+{
+ g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+ g_return_val_if_fail (value != NULL, NULL);
+ udev_enumerate_add_match_property (enumerator->priv->e, name, value);
+ return enumerator;
+}
+
+/**
+ * g_udev_enumerator_add_match_name:
+ * @enumerator: A #GUdevEnumerator.
+ * @name: Wildcard filter for kernel name e.g. "sda*".
+ *
+ * All returned devices will match the given @name.
+ *
+ * Returns: (transfer none): The passed in @enumerator.
+ *
+ * Since: 165
+ */
+GUdevEnumerator *
+g_udev_enumerator_add_match_name (GUdevEnumerator *enumerator,
+ const gchar *name)
+{
+ g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+ udev_enumerate_add_match_sysname (enumerator->priv->e, name);
+ return enumerator;
+}
+
+/**
+ * g_udev_enumerator_add_sysfs_path:
+ * @enumerator: A #GUdevEnumerator.
+ * @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"
+ *
+ * Add a device to the list of devices, to retrieve it back sorted in dependency order.
+ *
+ * Returns: (transfer none): The passed in @enumerator.
+ *
+ * Since: 165
+ */
+GUdevEnumerator *
+g_udev_enumerator_add_sysfs_path (GUdevEnumerator *enumerator,
+ const gchar *sysfs_path)
+{
+ g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
+ g_return_val_if_fail (sysfs_path != NULL, NULL);
+ udev_enumerate_add_syspath (enumerator->priv->e, sysfs_path);
+ return enumerator;
+}
+
+/**
+ * g_udev_enumerator_add_match_tag:
+ * @enumerator: A #GUdevEnumerator.
+ * @tag: A udev tag e.g. "udev-acl".
+ *
+ * All returned devices will match the given @tag.
+ *
+ * Returns: (transfer none): The passed in @enumerator.
+ *
+ * Since: 165
+ */
+GUdevEnumerator *
+g_udev_enumerator_add_match_tag (GUdevEnumerator *enumerator,
+ const gchar *tag)
+{
+ g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
+ g_return_val_if_fail (tag != NULL, NULL);
+ udev_enumerate_add_match_tag (enumerator->priv->e, tag);
+ return enumerator;
+}
+
+/**
+ * g_udev_enumerator_add_match_is_initialized:
+ * @enumerator: A #GUdevEnumerator.
+ *
+ * All returned devices will be initialized.
+ *
+ * Returns: (transfer none): The passed in @enumerator.
+ *
+ * Since: 165
+ */
+GUdevEnumerator *
+g_udev_enumerator_add_match_is_initialized (GUdevEnumerator *enumerator)
+{
+ g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
+ udev_enumerate_add_match_is_initialized (enumerator->priv->e);
+ return enumerator;
+}
+
+/**
+ * g_udev_enumerator_execute:
+ * @enumerator: A #GUdevEnumerator.
+ *
+ * Executes the query in @enumerator.
+ *
+ * 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.
+ *
+ * Since: 165
+ */
+GList *
+g_udev_enumerator_execute (GUdevEnumerator *enumerator)
+{
+ GList *ret;
+ struct udev_list_entry *l, *devices;
+
+ g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
+
+ ret = NULL;
+
+ /* retrieve the list */
+ udev_enumerate_scan_devices (enumerator->priv->e);
+
+ devices = udev_enumerate_get_list_entry (enumerator->priv->e);
+ for (l = devices; l != NULL; l = udev_list_entry_get_next (l))
+ {
+ struct udev_device *udevice;
+ GUdevDevice *device;
+
+ udevice = udev_device_new_from_syspath (udev_enumerate_get_udev (enumerator->priv->e),
+ udev_list_entry_get_name (l));
+ if (udevice == NULL)
+ continue;
+
+ device = _g_udev_device_new (udevice);
+ udev_device_unref (udevice);
+ ret = g_list_prepend (ret, device);
+ }
+
+ ret = g_list_reverse (ret);
+
+ return ret;
+}
diff --git a/gudev/gudevenumerator.h b/gudev/gudevenumerator.h
new file mode 100644
index 0000000..e1dbcf1
--- /dev/null
+++ b/gudev/gudevenumerator.h
@@ -0,0 +1,106 @@
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008-2010 David Zeuthen <davidz@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H)
+#error "Only <gudev/gudev.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef __G_UDEV_ENUMERATOR_H__
+#define __G_UDEV_ENUMERATOR_H__
+
+#include <gudev/gudevtypes.h>
+
+G_BEGIN_DECLS
+
+#define G_UDEV_TYPE_ENUMERATOR (g_udev_enumerator_get_type ())
+#define G_UDEV_ENUMERATOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_UDEV_TYPE_ENUMERATOR, GUdevEnumerator))
+#define G_UDEV_ENUMERATOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_UDEV_TYPE_ENUMERATOR, GUdevEnumeratorClass))
+#define G_UDEV_IS_ENUMERATOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_UDEV_TYPE_ENUMERATOR))
+#define G_UDEV_IS_ENUMERATOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_UDEV_TYPE_ENUMERATOR))
+#define G_UDEV_ENUMERATOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_UDEV_TYPE_ENUMERATOR, GUdevEnumeratorClass))
+
+typedef struct _GUdevEnumeratorClass GUdevEnumeratorClass;
+typedef struct _GUdevEnumeratorPrivate GUdevEnumeratorPrivate;
+
+/**
+ * GUdevEnumerator:
+ *
+ * The #GUdevEnumerator struct is opaque and should not be accessed directly.
+ *
+ * Since: 165
+ */
+struct _GUdevEnumerator
+{
+ GObject parent;
+
+ /*< private >*/
+ GUdevEnumeratorPrivate *priv;
+};
+
+/**
+ * GUdevEnumeratorClass:
+ * @parent_class: Parent class.
+ *
+ * Class structure for #GUdevEnumerator.
+ *
+ * Since: 165
+ */
+struct _GUdevEnumeratorClass
+{
+ GObjectClass parent_class;
+
+ /*< private >*/
+ /* Padding for future expansion */
+ void (*reserved1) (void);
+ void (*reserved2) (void);
+ void (*reserved3) (void);
+ void (*reserved4) (void);
+ void (*reserved5) (void);
+ void (*reserved6) (void);
+ void (*reserved7) (void);
+ void (*reserved8) (void);
+};
+
+GType g_udev_enumerator_get_type (void) G_GNUC_CONST;
+GUdevEnumerator *g_udev_enumerator_new (GUdevClient *client);
+GUdevEnumerator *g_udev_enumerator_add_match_subsystem (GUdevEnumerator *enumerator,
+ const gchar *subsystem);
+GUdevEnumerator *g_udev_enumerator_add_nomatch_subsystem (GUdevEnumerator *enumerator,
+ const gchar *subsystem);
+GUdevEnumerator *g_udev_enumerator_add_match_sysfs_attr (GUdevEnumerator *enumerator,
+ const gchar *name,
+ const gchar *value);
+GUdevEnumerator *g_udev_enumerator_add_nomatch_sysfs_attr (GUdevEnumerator *enumerator,
+ const gchar *name,
+ const gchar *value);
+GUdevEnumerator *g_udev_enumerator_add_match_property (GUdevEnumerator *enumerator,
+ const gchar *name,
+ const gchar *value);
+GUdevEnumerator *g_udev_enumerator_add_match_name (GUdevEnumerator *enumerator,
+ const gchar *name);
+GUdevEnumerator *g_udev_enumerator_add_match_tag (GUdevEnumerator *enumerator,
+ const gchar *tag);
+GUdevEnumerator *g_udev_enumerator_add_match_is_initialized (GUdevEnumerator *enumerator);
+GUdevEnumerator *g_udev_enumerator_add_sysfs_path (GUdevEnumerator *enumerator,
+ const gchar *sysfs_path);
+GList *g_udev_enumerator_execute (GUdevEnumerator *enumerator);
+
+G_END_DECLS
+
+#endif /* __G_UDEV_ENUMERATOR_H__ */
diff --git a/gudev/gudevenums.h b/gudev/gudevenums.h
new file mode 100644
index 0000000..467e93b
--- /dev/null
+++ b/gudev/gudevenums.h
@@ -0,0 +1,48 @@
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H)
+#error "Only <gudev/gudev.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef __G_UDEV_ENUMS_H__
+#define __G_UDEV_ENUMS_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/**
+ * GUdevDeviceType:
+ * @G_UDEV_DEVICE_TYPE_NONE: Device does not have a device file.
+ * @G_UDEV_DEVICE_TYPE_BLOCK: Device is a block device.
+ * @G_UDEV_DEVICE_TYPE_CHAR: Device is a character device.
+ *
+ * Enumeration used to specify a the type of a device.
+ */
+typedef enum
+{
+ G_UDEV_DEVICE_TYPE_NONE = 0,
+ G_UDEV_DEVICE_TYPE_BLOCK = 'b',
+ G_UDEV_DEVICE_TYPE_CHAR = 'c',
+} GUdevDeviceType;
+
+G_END_DECLS
+
+#endif /* __G_UDEV_ENUMS_H__ */
diff --git a/gudev/gudevenumtypes.c.template b/gudev/gudevenumtypes.c.template
new file mode 100644
index 0000000..fc30b39
--- /dev/null
+++ b/gudev/gudevenumtypes.c.template
@@ -0,0 +1,39 @@
+/*** BEGIN file-header ***/
+#include <gudev.h>
+
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+/* enumerations from "@filename@" */
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+GType
+@enum_name@_get_type (void)
+{
+ static volatile gsize g_define_type_id__volatile = 0;
+
+ if (g_once_init_enter (&g_define_type_id__volatile))
+ {
+ static const G@Type@Value values[] = {
+/*** END value-header ***/
+
+/*** BEGIN value-production ***/
+ { @VALUENAME@, "@VALUENAME@", "@valuenick@" },
+/*** END value-production ***/
+
+/*** BEGIN value-tail ***/
+ { 0, NULL, NULL }
+ };
+ GType g_define_type_id =
+ g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
+ g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
+ }
+
+ return g_define_type_id__volatile;
+}
+
+/*** END value-tail ***/
+
+/*** BEGIN file-tail ***/
+/*** END file-tail ***/
diff --git a/gudev/gudevenumtypes.h.template b/gudev/gudevenumtypes.h.template
new file mode 100644
index 0000000..d0ab339
--- /dev/null
+++ b/gudev/gudevenumtypes.h.template
@@ -0,0 +1,24 @@
+/*** BEGIN file-header ***/
+#ifndef __GUDEV_ENUM_TYPES_H__
+#define __GUDEV_ENUM_TYPES_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+
+/* enumerations from "@filename@" */
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+GType @enum_name@_get_type (void) G_GNUC_CONST;
+#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ())
+/*** END value-header ***/
+
+/*** BEGIN file-tail ***/
+G_END_DECLS
+
+#endif /* __GUDEV_ENUM_TYPES_H__ */
+/*** END file-tail ***/
diff --git a/gudev/gudevmarshal.list b/gudev/gudevmarshal.list
new file mode 100644
index 0000000..7e66599
--- /dev/null
+++ b/gudev/gudevmarshal.list
@@ -0,0 +1 @@
+VOID:STRING,OBJECT
diff --git a/gudev/gudevprivate.h b/gudev/gudevprivate.h
new file mode 100644
index 0000000..52e272b
--- /dev/null
+++ b/gudev/gudevprivate.h
@@ -0,0 +1,40 @@
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H)
+#error "Only <gudev/gudev.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef __G_UDEV_PRIVATE_H__
+#define __G_UDEV_PRIVATE_H__
+
+#include <gudev/gudevtypes.h>
+
+#include <libudev.h>
+
+G_BEGIN_DECLS
+
+GUdevDevice *
+_g_udev_device_new (struct udev_device *udevice);
+
+struct udev *_g_udev_client_get_udev (GUdevClient *client);
+
+G_END_DECLS
+
+#endif /* __G_UDEV_PRIVATE_H__ */
diff --git a/gudev/gudevtypes.h b/gudev/gudevtypes.h
new file mode 100644
index 0000000..e2f688f
--- /dev/null
+++ b/gudev/gudevtypes.h
@@ -0,0 +1,50 @@
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H)
+#error "Only <gudev/gudev.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef __G_UDEV_TYPES_H__
+#define __G_UDEV_TYPES_H__
+
+#include <gudev/gudevenums.h>
+#include <sys/types.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GUdevClient GUdevClient;
+typedef struct _GUdevDevice GUdevDevice;
+typedef struct _GUdevEnumerator GUdevEnumerator;
+
+/**
+ * GUdevDeviceNumber:
+ *
+ * Corresponds to the standard #dev_t type as defined by POSIX (Until
+ * bug 584517 is resolved this work-around is needed).
+ */
+#ifdef _GUDEV_WORK_AROUND_DEV_T_BUG
+typedef guint64 GUdevDeviceNumber; /* __UQUAD_TYPE */
+#else
+typedef dev_t GUdevDeviceNumber;
+#endif
+
+G_END_DECLS
+
+#endif /* __G_UDEV_TYPES_H__ */
diff --git a/libgudev-1.0.sym b/libgudev-1.0.sym
new file mode 100644
index 0000000..0600486
--- /dev/null
+++ b/libgudev-1.0.sym
@@ -0,0 +1,68 @@
+/***
+ This file is part of systemd.
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+***/
+
+{
+global:
+ g_udev_client_get_type;
+ g_udev_client_new;
+ g_udev_client_query_by_device_file;
+ g_udev_client_query_by_device_number;
+ g_udev_client_query_by_subsystem;
+ g_udev_client_query_by_subsystem_and_name;
+ g_udev_client_query_by_sysfs_path;
+ g_udev_device_get_action;
+ g_udev_device_get_device_file;
+ g_udev_device_get_device_file_symlinks;
+ g_udev_device_get_device_number;
+ g_udev_device_get_device_type;
+ g_udev_device_get_devtype;
+ g_udev_device_get_driver;
+ g_udev_device_get_is_initialized;
+ g_udev_device_get_name;
+ g_udev_device_get_number;
+ g_udev_device_get_parent;
+ g_udev_device_get_parent_with_subsystem;
+ g_udev_device_get_property;
+ g_udev_device_get_property_as_boolean;
+ g_udev_device_get_property_as_double;
+ g_udev_device_get_property_as_int;
+ g_udev_device_get_property_as_strv;
+ g_udev_device_get_property_as_uint64;
+ g_udev_device_get_property_keys;
+ g_udev_device_get_seqnum;
+ g_udev_device_get_subsystem;
+ g_udev_device_get_sysfs_attr;
+ g_udev_device_get_sysfs_attr_as_boolean;
+ g_udev_device_get_sysfs_attr_as_double;
+ g_udev_device_get_sysfs_attr_as_int;
+ g_udev_device_get_sysfs_attr_as_strv;
+ g_udev_device_get_sysfs_attr_as_uint64;
+ g_udev_device_get_sysfs_attr_keys;
+ g_udev_device_get_sysfs_path;
+ g_udev_device_get_tags;
+ g_udev_device_get_type;
+ g_udev_device_get_usec_since_initialized;
+ g_udev_device_has_property;
+ g_udev_device_has_sysfs_attr;
+ g_udev_device_type_get_type;
+ g_udev_enumerator_add_match_is_initialized;
+ g_udev_enumerator_add_match_name;
+ g_udev_enumerator_add_match_property;
+ g_udev_enumerator_add_match_subsystem;
+ g_udev_enumerator_add_match_sysfs_attr;
+ g_udev_enumerator_add_match_tag;
+ g_udev_enumerator_add_nomatch_subsystem;
+ g_udev_enumerator_add_nomatch_sysfs_attr;
+ g_udev_enumerator_add_sysfs_path;
+ g_udev_enumerator_execute;
+ g_udev_enumerator_get_type;
+ g_udev_enumerator_new;
+local:
+ *;
+};
diff --git a/scripts/gjs-example.js b/scripts/gjs-example.js
new file mode 100755
index 0000000..5586fd6
--- /dev/null
+++ b/scripts/gjs-example.js
@@ -0,0 +1,75 @@
+#!/usr/bin/env gjs-console
+
+// This currently depends on the following patches to gjs
+//
+// http://bugzilla.gnome.org/show_bug.cgi?id=584558
+// http://bugzilla.gnome.org/show_bug.cgi?id=584560
+// http://bugzilla.gnome.org/show_bug.cgi?id=584568
+
+const GUdev = imports.gi.GUdev;
+const Mainloop = imports.mainloop;
+
+function print_device (device) {
+ print (" subsystem: " + device.get_subsystem ());
+ print (" devtype: " + device.get_devtype ());
+ print (" name: " + device.get_name ());
+ print (" number: " + device.get_number ());
+ print (" sysfs_path: " + device.get_sysfs_path ());
+ print (" driver: " + device.get_driver ());
+ print (" action: " + device.get_action ());
+ print (" seqnum: " + device.get_seqnum ());
+ print (" device type: " + device.get_device_type ());
+ print (" device number: " + device.get_device_number ());
+ print (" device file: " + device.get_device_file ());
+ print (" device file symlinks: " + device.get_device_file_symlinks ());
+ print (" foo: " + device.get_sysfs_attr_as_strv ("stat"));
+ var keys = device.get_property_keys ();
+ for (var n = 0; n < keys.length; n++) {
+ print (" " + keys[n] + "=" + device.get_property (keys[n]));
+ }
+}
+
+function on_uevent (client, action, device) {
+ print ("action " + action + " on device " + device.get_sysfs_path());
+ print_device (device);
+ print ("");
+}
+
+var client = new GUdev.Client ({subsystems: ["block", "usb/usb_interface"]});
+client.connect ("uevent", on_uevent);
+
+var block_devices = client.query_by_subsystem ("block");
+for (var n = 0; n < block_devices.length; n++) {
+ print ("block device: " + block_devices[n].get_device_file ());
+}
+
+var d;
+
+d = client.query_by_device_number (GUdev.DeviceType.BLOCK, 0x0810);
+if (d == null) {
+ print ("query_by_device_number 0x810 -> null");
+} else {
+ print ("query_by_device_number 0x810 -> " + d.get_device_file ());
+ var dd = d.get_parent_with_subsystem ("usb", null);
+ print_device (dd);
+ print ("--------------------------------------------------------------------------");
+ while (d != null) {
+ print_device (d);
+ print ("");
+ d = d.get_parent ();
+ }
+}
+
+d = client.query_by_sysfs_path ("/sys/block/sda/sda1");
+print ("query_by_sysfs_path (\"/sys/block/sda1\") -> " + d.get_device_file ());
+
+d = client.query_by_subsystem_and_name ("block", "sda2");
+print ("query_by_subsystem_and_name (\"block\", \"sda2\") -> " + d.get_device_file ());
+
+d = client.query_by_device_file ("/dev/sda");
+print ("query_by_device_file (\"/dev/sda\") -> " + d.get_device_file ());
+
+d = client.query_by_device_file ("/dev/block/8:0");
+print ("query_by_device_file (\"/dev/block/8:0\") -> " + d.get_device_file ());
+
+Mainloop.run('udev-example');
diff --git a/scripts/seed-example-enum.js b/scripts/seed-example-enum.js
new file mode 100755
index 0000000..66206ad
--- /dev/null
+++ b/scripts/seed-example-enum.js
@@ -0,0 +1,38 @@
+#!/usr/bin/env seed
+
+const GLib = imports.gi.GLib;
+const GUdev = imports.gi.GUdev;
+
+function print_device(device) {
+ print(" initialized: " + device.get_is_initialized());
+ print(" usec since initialized: " + device.get_usec_since_initialized());
+ print(" subsystem: " + device.get_subsystem());
+ print(" devtype: " + device.get_devtype());
+ print(" name: " + device.get_name());
+ print(" number: " + device.get_number());
+ print(" sysfs_path: " + device.get_sysfs_path());
+ print(" driver: " + device.get_driver());
+ print(" action: " + device.get_action());
+ print(" seqnum: " + device.get_seqnum());
+ print(" device type: " + device.get_device_type());
+ print(" device number: " + device.get_device_number());
+ print(" device file: " + device.get_device_file());
+ print(" device file symlinks: " + device.get_device_file_symlinks());
+ print(" tags: " + device.get_tags());
+ var keys = device.get_property_keys();
+ for (var n = 0; n < keys.length; n++) {
+ print(" " + keys[n] + "=" + device.get_property(keys[n]));
+ }
+}
+
+var client = new GUdev.Client({subsystems: []});
+var enumerator = new GUdev.Enumerator({client: client});
+enumerator.add_match_subsystem('b*')
+
+var devices = enumerator.execute();
+
+for (var n=0; n < devices.length; n++) {
+ var device = devices[n];
+ print_device(device);
+ print("");
+}
diff --git a/scripts/seed-example.js b/scripts/seed-example.js
new file mode 100755
index 0000000..e2ac324
--- /dev/null
+++ b/scripts/seed-example.js
@@ -0,0 +1,72 @@
+#!/usr/bin/env seed
+
+// seed example
+
+const GLib = imports.gi.GLib;
+const GUdev = imports.gi.GUdev;
+
+function print_device (device) {
+ print (" subsystem: " + device.get_subsystem ());
+ print (" devtype: " + device.get_devtype ());
+ print (" name: " + device.get_name ());
+ print (" number: " + device.get_number ());
+ print (" sysfs_path: " + device.get_sysfs_path ());
+ print (" driver: " + device.get_driver ());
+ print (" action: " + device.get_action ());
+ print (" seqnum: " + device.get_seqnum ());
+ print (" device type: " + device.get_device_type ());
+ print (" device number: " + device.get_device_number ());
+ print (" device file: " + device.get_device_file ());
+ print (" device file symlinks: " + device.get_device_file_symlinks ());
+ print (" foo: " + device.get_sysfs_attr_as_strv ("stat"));
+ var keys = device.get_property_keys ();
+ for (var n = 0; n < keys.length; n++) {
+ print (" " + keys[n] + "=" + device.get_property (keys[n]));
+ }
+}
+
+function on_uevent (client, action, device) {
+ print ("action " + action + " on device " + device.get_sysfs_path());
+ print_device (device);
+ print ("");
+}
+
+var client = new GUdev.Client ({subsystems: ["block", "usb/usb_interface"]});
+client.signal.connect ("uevent", on_uevent);
+
+var block_devices = client.query_by_subsystem ("block");
+for (var n = 0; n < block_devices.length; n++) {
+ print ("block device: " + block_devices[n].get_device_file ());
+}
+
+var d;
+
+d = client.query_by_device_number (GUdev.DeviceType.BLOCK, 0x0810);
+if (d == null) {
+ print ("query_by_device_number 0x810 -> null");
+} else {
+ print ("query_by_device_number 0x810 -> " + d.get_device_file ());
+ dd = d.get_parent_with_subsystem ("usb", null);
+ print_device (dd);
+ print ("--------------------------------------------------------------------------");
+ while (d != null) {
+ print_device (d);
+ print ("");
+ d = d.get_parent ();
+ }
+}
+
+d = client.query_by_sysfs_path ("/sys/block/sda/sda1");
+print ("query_by_sysfs_path (\"/sys/block/sda1\") -> " + d.get_device_file ());
+
+d = client.query_by_subsystem_and_name ("block", "sda2");
+print ("query_by_subsystem_and_name (\"block\", \"sda2\") -> " + d.get_device_file ());
+
+d = client.query_by_device_file ("/dev/sda");
+print ("query_by_device_file (\"/dev/sda\") -> " + d.get_device_file ());
+
+d = client.query_by_device_file ("/dev/block/8:0");
+print ("query_by_device_file (\"/dev/block/8:0\") -> " + d.get_device_file ());
+
+var mainloop = GLib.main_loop_new ();
+GLib.main_loop_run (mainloop);