massive update. strbuf fixes, new functions, more compat for old udev, updates to test app, version bump, use config.h, split more functions into other files

SVN revision: 48935
This commit is contained in:
Mike Blumenkrantz 2010-05-17 02:59:07 +00:00
parent 61df60e3bb
commit 567664a1a3
10 changed files with 565 additions and 204 deletions

View File

@ -2,7 +2,7 @@ ACLOCAL_AMFLAGS = -I m4
SUBDIRS = src doc
MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.guess config.h.in \
MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.guess config.h.in* \
config.log config.sub configure depcomp \
install-sh ltmain.sh missing compile eeze*doc*tar* \
m4/l*

View File

@ -1,7 +1,7 @@
# get rid of that stupid cache mechanism
rm -f config.cache
AC_INIT([eeze], [0.0.1], [enlightenment-devel@lists.sourceforge.net])
AC_INIT([eeze], [0.1.0], [enlightenment-devel@lists.sourceforge.net])
release="ver-pre-svn-05"
AC_PREREQ([2.52])
AC_CONFIG_SRCDIR([configure.ac])
@ -62,8 +62,7 @@ AS_IF(
udev_version=$(pkg-config udev --version | cut -d. -f2)
if test $udev_version -lt 23;then
EEZE_UDEV_CFLAGS="-DOLD_UDEV_RRRRRRRRRRRRRR"
AC_SUBST(EEZE_UDEV_CFLAGS)
AC_DEFINE([OLD_UDEV_RRRRRRRRRRRRRR],[1],[compat functionality for udev < 0.23])
fi
AM_CONDITIONAL([BUILD_EEZE_UDEV], [test "x${enable_eeze_udev}" = "xyes"])

View File

@ -94,9 +94,15 @@ int main()
printf("For my first trick, I will find all of your keyboards and return their syspaths.\n");
/* find all keyboards using type EEZE_UDEV_TYPE_KEYBOARD */
type = eeze_udev_find_by_type(EEZE_UDEV_TYPE_KEYBOARD, NULL);
/* add all "link" devices that aren't explicitly found, but are still
* part of the device chain
*/
eeze_udev_find_unlisted_similar(type);
EINA_LIST_FOREACH(type, l, name)
{ /* add the devpath to the hash for use in the cb later */
eina_hash_direct_add(hash, name, eeze_udev_syspath_get_devpath(name));
{
/* add the devpath to the hash for use in the cb later */
if ((check = eeze_udev_syspath_get_devpath(name)))
eina_hash_direct_add(hash, name, check);
printf("Found keyboard: %s\n", name);
}
/* we save this list for later, because once a device is unplugged it can
@ -108,10 +114,13 @@ int main()
printf("\nNext, I will find all of your mice and print the corresponding manufacturer.\n");
/* find all mice using type EEZE_UDEV_TYPE_MOUSE */
type = eeze_udev_find_by_type(EEZE_UDEV_TYPE_MOUSE, NULL);
eeze_udev_find_unlisted_similar(type);
EINA_LIST_FOREACH(type, l, name)
{ /* add the devpath to the hash for use in the cb later */
eina_hash_direct_add(hash, name, eeze_udev_syspath_get_devpath(name)); /* get a property using the device's syspath */
printf("Found mouse %s with vendor: %s\n", name, eeze_udev_syspath_get_property(name, "ID_VENDOR"));
if ((check = eeze_udev_syspath_get_devpath(name)))
eina_hash_direct_add(hash, name, check); /* get a property using the device's syspath */
if ((check = eeze_udev_syspath_get_property(name, "ID_VENDOR")))
printf("Found mouse %s with vendor: %s\n", name, check);
}
/* we save this list for later, because once a device is unplugged it can
* no longer be detected by udev, and any related properties are unusable unless
@ -122,21 +131,26 @@ int main()
printf("\nNow let's try something a little more difficult. Mountable filesystems!\n");
/* find all mountable drives using type EEZE_UDEV_TYPE_DRIVE_MOUNTABLE */
type = eeze_udev_find_by_type(EEZE_UDEV_TYPE_DRIVE_MOUNTABLE, NULL);
eeze_udev_find_unlisted_similar(type);
EINA_LIST_FOREACH(type, l, name)
{
printf("Found device: %s\n", name); /* get a property using the device's syspath */
printf("\tYou probably know it better as %s\n", eeze_udev_syspath_get_property(name, "DEVNAME"));
printf("\tIt's formatted as %s", eeze_udev_syspath_get_property(name, "ID_FS_TYPE"));
check = eeze_udev_syspath_get_property(name, "FSTAB_DIR");
if (check)
printf(", and gets mounted at %s", check);
printf("!\n");
if ((check = eeze_udev_syspath_get_property(name, "ID_FS_TYPE")))
{
printf("\tIt's formatted as %s", check);
check = eeze_udev_syspath_get_property(name, "FSTAB_DIR");
if (check)
printf(", and gets mounted at %s", check);
printf("!\n");
}
}
eina_list_free(type);
printf("\nInternal drives, anyone? With serial numbers?\n");
/* find all internal drives using type EEZE_UDEV_TYPE_DRIVE_INTERNAL */
type = eeze_udev_find_by_type(EEZE_UDEV_TYPE_DRIVE_INTERNAL, NULL);
eeze_udev_find_unlisted_similar(type);
EINA_LIST_FOREACH(type, l, name) /* get a property using the device's syspath */
printf("%s: %s\n", name, eeze_udev_syspath_get_property(name, "ID_SERIAL"));
eina_list_free(type);
@ -144,9 +158,12 @@ int main()
printf("\nGot any removables? I'm gonna find em!\n");
/* find all removable media using type EEZE_UDEV_TYPE_DRIVE_REMOVABLE */
type = eeze_udev_find_by_type(EEZE_UDEV_TYPE_DRIVE_REMOVABLE, NULL);
eeze_udev_find_unlisted_similar(type);
EINA_LIST_FOREACH(type, l, name) /* get a property using the device's syspath */
printf("\tOoh, a %s attached on your %s bus!\n", eeze_udev_syspath_get_property(name, "ID_MODEL"),
eeze_udev_syspath_get_property(name, "ID_BUS"));
{
if ((check = eeze_udev_syspath_get_property(name, "ID_MODEL")))
printf("\tOoh, a %s attached on your %s bus!\n", check, eeze_udev_syspath_get_property(name, "ID_BUS"));
}
eina_list_free(type);

View File

@ -111,10 +111,14 @@ extern "C" {
EAPI int eeze_udev_init(void);
EAPI int eeze_udev_shutdown(void);
EAPI Eina_List *eeze_udev_find_similar_from_syspath(const char *syspath);
EAPI void eeze_udev_find_unlisted_similar(Eina_List *list);
EAPI Eina_List *eeze_udev_find_by_sysattr(const char *sysattr, const char *value);
EAPI Eina_List *eeze_udev_find_by_type(const Eeze_Udev_Type type, const char *name);
EAPI Eina_List *eeze_udev_find_by_filter(const char *subsystem, const char *type, const char *name);
EAPI const char *eeze_udev_syspath_rootdev_get(const char *syspath);
EAPI const char *eeze_udev_syspath_get_parent(const char *syspath);
EAPI Eina_List *eeze_udev_syspath_get_parents(const char *syspath);
EAPI const char *eeze_udev_syspath_get_devpath(const char *syspath);
EAPI const char *eeze_udev_syspath_get_subsystem(const char *syspath);
EAPI const char *eeze_udev_syspath_get_property(const char *syspath, const char *property);

View File

@ -1,6 +1,6 @@
MAINTAINERCLEANFILES = Makefile.in
AM_CPPFLAGS = @ECORE_CFLAGS@ @EEZE_UDEV_CFLAGS@
AM_CPPFLAGS = @ECORE_CFLAGS@
if BUILD_EEZE_UDEV
@ -13,7 +13,9 @@ libeeze_udev_la_SOURCES = \
Eeze_Udev.h \
eeze_udev.c \
eeze_udev_watch.c \
eeze_udev_main.c
eeze_udev_main.c \
eeze_udev_find.c \
eeze_udev_private.c
libeeze_udev_la_LIBADD = @ECORE_LIBS@ @UDEV_LIBS@
libeeze_udev_la_LDFLAGS = -no-undefined -version-info @version_info@ @eeze_udev_release_info@

View File

@ -1,8 +1,9 @@
#include "eeze_udev_private.h"
#include <Eeze_Udev.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* from watch.c */
Eina_Bool _walk_parents_for_attr(struct udev_device *device, const char *sysattr, const char* value);
#include <Eeze_Udev.h>
#include "eeze_udev_private.h"
/**
* @defgroup udev udev
@ -21,7 +22,7 @@ Eina_Bool _walk_parents_for_attr(struct udev_device *device, const char *sysattr
* @ingroup udev
*/
EAPI const char *
eeze_udev_syspath_rootdev_get(const char *syspath)
eeze_udev_syspath_get_parent(const char *syspath)
{
struct udev *udev;
struct udev_device *device, *parent;
@ -49,167 +50,46 @@ eeze_udev_syspath_rootdev_get(const char *syspath)
}
/**
* Find devices using a EEZE_UDEV_TYPE_* and/or a name.
* Returns a list of all parent device syspaths for @p syspath.
*
* @param type A Eeze_Udev_Type or 0
* @param name A filter for the device name or NULL
* @return A Eina_List* of matched devices or NULL on failure
*
* Return a list of syspaths (/sys/$syspath) for matching udev devices.
* @param syspath The device to find parents of
* @return A list of the parent devices of @p syspath
*
* @ingroup udev
*/
EAPI Eina_List *
eeze_udev_find_by_type(const Eeze_Udev_Type etype, const char *name)
eeze_udev_syspath_get_parents(const char *syspath)
{
struct udev *udev;
struct udev_enumerate *en;
struct udev_list_entry *devs, *cur;
struct udev_device *device;
const char *devname;
Eina_List *ret = NULL;
if ((!etype) && (!name)) return NULL;
struct udev_device *child, *parent, *device;
const char *path;
Eina_Strbuf *sbuf;
Eina_List *devlist = NULL;
if (!syspath) return NULL;
udev = udev_new();
if (!udev) return NULL;
en = udev_enumerate_new(udev);
if (!en) return NULL;
sbuf = eina_strbuf_new();
if (!strstr(syspath, "/sys/"))
eina_strbuf_append(sbuf, "/sys/");
eina_strbuf_append(sbuf, syspath);
switch (etype)
{
case EEZE_UDEV_TYPE_NONE:
break;
case EEZE_UDEV_TYPE_KEYBOARD:
udev_enumerate_add_match_subsystem(en, "input");
udev_enumerate_add_match_property(en, "ID_INPUT_KEYBOARD", "1");
break;
case EEZE_UDEV_TYPE_MOUSE:
udev_enumerate_add_match_subsystem(en, "input");
udev_enumerate_add_match_property(en, "ID_INPUT_MOUSE", "1");
break;
case EEZE_UDEV_TYPE_TOUCHPAD:
udev_enumerate_add_match_subsystem(en, "input");
udev_enumerate_add_match_property(en, "ID_INPUT_TOUCHPAD", "1");
break;
case EEZE_UDEV_TYPE_DRIVE_MOUNTABLE:
udev_enumerate_add_match_subsystem(en, "block");
udev_enumerate_add_match_property(en, "ID_FS_USAGE", "filesystem");
udev_enumerate_add_nomatch_sysattr(en, "capability", "52");
break;
case EEZE_UDEV_TYPE_DRIVE_INTERNAL:
udev_enumerate_add_match_subsystem(en, "block");
udev_enumerate_add_match_property(en, "ID_TYPE", "disk");
udev_enumerate_add_match_property(en, "ID_BUS", "ata");
udev_enumerate_add_match_sysattr(en, "removable", "0");
break;
case EEZE_UDEV_TYPE_DRIVE_REMOVABLE:
udev_enumerate_add_match_subsystem(en, "block");
udev_enumerate_add_match_property(en, "ID_TYPE", "disk");
udev_enumerate_add_match_sysattr(en, "removable", "1");
break;
case EEZE_UDEV_TYPE_DRIVE_CDROM:
udev_enumerate_add_match_subsystem(en, "block");
udev_enumerate_add_match_property(en, "ID_CDROM", "1");
break;
case EEZE_UDEV_TYPE_POWER_AC:
udev_enumerate_add_match_subsystem(en, "power_supply");
udev_enumerate_add_match_property(en, "POWER_SUPPLY_TYPE", "Mains");
break;
case EEZE_UDEV_TYPE_POWER_BAT:
udev_enumerate_add_match_subsystem(en, "power_supply");
udev_enumerate_add_match_property(en, "POWER_SUPPLY_TYPE", "Battery");
break;
/*
case EEZE_UDEV_TYPE_ANDROID:
udev_enumerate_add_match_subsystem(en, "block");
udev_enumerate_add_match_property(en, "ID_MODEL", "Android_*");
break;
*/
default:
break;
}
udev_enumerate_scan_devices(en);
devs = udev_enumerate_get_list_entry(en);
udev_list_entry_foreach(cur, devs)
{
devname = udev_list_entry_get_name(cur);
device = udev_device_new_from_syspath(udev, devname);
if (name)
if (!strstr(devname,name))
goto out;
ret = eina_list_append(ret, eina_stringshare_add(udev_device_get_property_value(device, "DEVPATH")));
out:
udev_device_unref(device);
}
udev_enumerate_unref(en);
udev_unref(udev);
return ret;
device = udev_device_new_from_syspath(udev, eina_strbuf_string_get(sbuf));
if (!(parent = udev_device_get_parent(device)))
return NULL;
for (; parent; child = parent, parent = udev_device_get_parent(child))
{
path = udev_device_get_syspath(parent);
devlist = eina_list_append(devlist, eina_stringshare_add(path));
}
udev_device_unref(device);
udev_unref(udev);
return devlist;
}
/**
* A more advanced find, allows finds using udev properties.
*
* @param subsystem The udev subsystem to filter by, or NULL
* @param type "ID_INPUT_KEY", "ID_INPUT_MOUSE", "ID_INPUT_TOUCHPAD", NULL, etc
* @param name A filter for the device name, or NULL
* @return A Eina_List* of matched devices or NULL on failure
*
* Return a list of syspaths (/sys/$syspath) for matching udev devices.
* Requires at least one filter.
*
* @ingroup udev
*/
EAPI Eina_List *
eeze_udev_find_by_filter(const char *subsystem, const char *type, const char *name)
{
struct udev *udev;
struct udev_enumerate *en;
struct udev_list_entry *devs, *cur;
struct udev_device *device;
const char *devname;
Eina_List *ret = NULL;
if ((!subsystem) && (!type) && (!name)) return NULL;
udev = udev_new();
if (!udev) return NULL;
en = udev_enumerate_new(udev);
if (!en) return NULL;
if (subsystem)
udev_enumerate_add_match_subsystem(en, subsystem);
udev_enumerate_add_match_property(en, type, "1");
udev_enumerate_scan_devices(en);
devs = udev_enumerate_get_list_entry(en);
udev_list_entry_foreach(cur, devs)
{
devname = udev_list_entry_get_name(cur);
device = udev_device_new_from_syspath(udev, devname);
if (name)
if (!strstr(devname,name))
goto out;
ret = eina_list_append(ret, eina_stringshare_add(udev_device_get_property_value(device, "DEVPATH")));
out:
udev_device_unref(device);
}
udev_enumerate_unref(en);
udev_unref(udev);
return ret;
}
/**
* Get the /dev/ path from the /sys/ path.
*
@ -225,7 +105,7 @@ eeze_udev_syspath_get_devpath(const char *syspath)
{
struct udev *udev;
struct udev_device *device;
const char *name;
const char *name = NULL;
Eina_Strbuf *sbuf;
if (!syspath) return NULL;
@ -238,7 +118,8 @@ eeze_udev_syspath_get_devpath(const char *syspath)
eina_strbuf_append(sbuf, syspath);
device = udev_device_new_from_syspath(udev, eina_strbuf_string_get(sbuf));
name = eina_stringshare_add(udev_device_get_property_value(device, "DEVNAME"));
if ((udev_device_get_property_value(device, "DEVNAME")))
name = eina_stringshare_add(eina_strbuf_string_get(sbuf));
udev_device_unref(device);
udev_unref(udev);
@ -302,7 +183,7 @@ eeze_udev_syspath_get_property(const char *syspath, const char *property)
{
struct udev *udev;
struct udev_device *device;
const char *value;
const char *value = NULL, *test;
Eina_Strbuf *sbuf;
if (!syspath) return NULL;
@ -315,7 +196,8 @@ eeze_udev_syspath_get_property(const char *syspath, const char *property)
eina_strbuf_append(sbuf, syspath);
device = udev_device_new_from_syspath(udev, eina_strbuf_string_get(sbuf));
value = eina_stringshare_add(udev_device_get_property_value(device, property));
if ((test = udev_device_get_property_value(device, property)));
value = eina_stringshare_add(test);
udev_device_unref(device);
udev_unref(udev);
@ -415,7 +297,7 @@ eeze_udev_devpath_get_subsystem(const char *devpath)
/**
* Checks whether the device is a mouse.
*
* @param syspath The /sys/ path of the device
* @param syspath The /sys/ path with or without the /sys/
* @return If true, the device is a mouse
*
* @ingroup udev
@ -462,7 +344,7 @@ eeze_udev_syspath_is_mouse(const char *syspath)
/**
* Checks whether the device is a keyboard.
*
* @param syspath The /sys/ path of the device
* @param syspath The /sys/ path with or without the /sys/
* @return If true, the device is a keyboard
*
* @ingroup udev
@ -509,7 +391,7 @@ eeze_udev_syspath_is_kbd(const char *syspath)
/**
* Checks whether the device is a touchpad.
*
* @param syspath The /sys/ path of the device
* @param syspath The /sys/ path with or without the /sys/
* @return If true, the device is a touchpad
*
* @ingroup udev
@ -546,3 +428,44 @@ eeze_udev_syspath_is_touchpad(const char *syspath)
return touchpad;
}
/**
* Walks up the device chain starting at @p syspath,
* checking each device for @p sysattr with (optional) @p value.
*
* @param syspath The /sys/ path of the device to start at, with or without the /sys/
* @param sysattr The attribute to find
* @param value OPTIONAL: The value that @p sysattr should have, or NULL
*
* @return If the sysattr (with value) is found, returns TRUE. Else, false.
*/
EAPI Eina_Bool
eeze_udev_syspath_check_sysattr(const char *syspath, const char *sysattr, const char *value)
{
struct udev *udev;
struct udev_device *device, *child, *parent;
Eina_Strbuf *sbuf;
const char *test = NULL;
if (!syspath) return 0;
udev = udev_new();
if (!udev) return 0;
sbuf = eina_strbuf_new();
if (!strstr(syspath, "/sys/"))
eina_strbuf_append(sbuf, "/sys/");
eina_strbuf_append(sbuf, syspath);
device = udev_device_new_from_syspath(udev, eina_strbuf_string_get(sbuf));
for (parent = device; parent; child = parent, parent = udev_device_get_parent(child))
{
if ((test = udev_device_get_sysattr_value(parent, sysattr)))
if ((value) && (!strcmp(test, value)))
{
eina_strbuf_free(sbuf);
return 1;
}
}
eina_strbuf_free(sbuf);
return 0;
}

View File

@ -0,0 +1,357 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "eeze_udev_private.h"
#include <Eeze_Udev.h>
/**
* Returns a list of all syspaths that are (or should be) the same
* device as the device pointed at by @p syspath.
*
* @param syspath The syspath of the device to find matches for
* @return All devices which are the same as the one passed
*
* @ingroup udev
*/
EAPI Eina_List *
eeze_udev_find_similar_from_syspath(const char *syspath)
{
struct udev *udev;
struct udev_device *device;
struct udev_list_entry *devs, *cur;
struct udev_enumerate *en;
Eina_List *l, *ret = NULL;
Eina_Strbuf *sbuf;
const char *vendor, *model, *revision, *devname, *dev;
if (!syspath) return NULL;
udev = udev_new();
if (!udev) return NULL;
en = udev_enumerate_new(udev);
if (!en)
{
udev_unref(udev);
return NULL;
}
sbuf = eina_strbuf_new();
if (!strstr(syspath, "/sys/"))
eina_strbuf_append(sbuf, "/sys/");
eina_strbuf_append(sbuf, syspath);
device = udev_device_new_from_syspath(udev, syspath);
vendor = udev_device_get_property_value(device, "ID_VENDOR_ID");
if (vendor)
udev_enumerate_add_match_property(en, "ID_VENDOR_ID", vendor);
model = udev_device_get_property_value(device, "ID_MODEL_ID");
if (model)
udev_enumerate_add_match_property(en, "ID_MODEL_ID", model);
revision = udev_device_get_property_value(device, "ID_REVISION");
if (revision)
udev_enumerate_add_match_property(en, "ID_REVISION", revision);
udev_enumerate_scan_devices(en);
udev_device_unref(device);
devs = udev_enumerate_get_list_entry(en);
udev_list_entry_foreach(cur, devs)
{
devname = udev_list_entry_get_name(cur);
/* verify unlisted device */
EINA_LIST_FOREACH(ret, l, dev)
if (!strcmp(dev, devname))
continue;
ret = eina_list_prepend(ret, eina_stringshare_add(devname));
device = udev_device_new_from_syspath(udev, devname);
/* only device roots have this sysattr,
* and we only need to check parents of the roots
*/
if (udev_device_get_sysattr_value(device, "idVendor"))
_get_unlisted_parents(ret, device);
udev_device_unref(device);
}
udev_enumerate_unref(en);
udev_unref(udev);
eina_strbuf_free(sbuf);
return ret;
}
/**
* Updates a list of all syspaths that are (or should be) the same
* device.
*
* @param syspath The syspath of the device to find matches for.
*
* This function will update @p list to include all devices matching
* devices with syspaths currently stored in @p list.
*
* @ingroup udev
*/
EAPI void
eeze_udev_find_unlisted_similar(Eina_List *list)
{
struct udev *udev;
struct udev_device *device;
struct udev_list_entry *devs, *cur;
struct udev_enumerate *en;
Eina_List *l;
const char *vendor, *model, *revision, *devname, *dev;
if (!list) return;
udev = udev_new();
if (!udev) return;
EINA_LIST_FOREACH(list, l, dev)
{
en = udev_enumerate_new(udev);
if (!en)
{
udev_unref(udev);
return;
}
device = udev_device_new_from_syspath(udev, dev);
vendor = udev_device_get_property_value(device, "ID_VENDOR_ID");
if (vendor)
udev_enumerate_add_match_property(en, "ID_VENDOR_ID", vendor);
model = udev_device_get_property_value(device, "ID_MODEL_ID");
if (model)
udev_enumerate_add_match_property(en, "ID_MODEL_ID", model);
revision = udev_device_get_property_value(device, "ID_REVISION");
if (revision)
udev_enumerate_add_match_property(en, "ID_REVISION", revision);
udev_enumerate_scan_devices(en);
udev_device_unref(device);
devs = udev_enumerate_get_list_entry(en);
udev_list_entry_foreach(cur, devs)
{
devname = udev_list_entry_get_name(cur);
device = udev_device_new_from_syspath(udev, devname);
/* only device roots have this sysattr,
* and we only need to check parents of the roots
*/
if (udev_device_get_sysattr_value(device, "idVendor"))
_get_unlisted_parents(list, device);
udev_device_unref(device);
}
udev_enumerate_unref(en);
}
udev_unref(udev);
return;
}
/**
* Find devices using a EEZE_UDEV_TYPE_* and/or a name.
*
* @param type A Eeze_Udev_Type or 0
* @param name A filter for the device name or NULL
* @return A Eina_List* of matched devices or NULL on failure
*
* Return a list of syspaths (/sys/$syspath) for matching udev devices.
*
* @ingroup udev
*/
EAPI Eina_List *
eeze_udev_find_by_type(const Eeze_Udev_Type etype, const char *name)
{
struct udev *udev;
struct udev_enumerate *en;
struct udev_list_entry *devs, *cur;
struct udev_device *device;
const char *devname;
Eina_List *ret = NULL;
if ((!etype) && (!name)) return NULL;
udev = udev_new();
if (!udev) return NULL;
en = udev_enumerate_new(udev);
if (!en) return NULL;
switch (etype)
{
case EEZE_UDEV_TYPE_NONE:
break;
case EEZE_UDEV_TYPE_KEYBOARD:
udev_enumerate_add_match_subsystem(en, "input");
udev_enumerate_add_match_property(en, "ID_INPUT_KEYBOARD", "1");
break;
case EEZE_UDEV_TYPE_MOUSE:
udev_enumerate_add_match_subsystem(en, "input");
udev_enumerate_add_match_property(en, "ID_INPUT_MOUSE", "1");
break;
case EEZE_UDEV_TYPE_TOUCHPAD:
udev_enumerate_add_match_subsystem(en, "input");
udev_enumerate_add_match_property(en, "ID_INPUT_TOUCHPAD", "1");
break;
case EEZE_UDEV_TYPE_DRIVE_MOUNTABLE:
udev_enumerate_add_match_subsystem(en, "block");
udev_enumerate_add_match_property(en, "ID_FS_USAGE", "filesystem");
udev_enumerate_add_nomatch_sysattr(en, "capability", "52");
break;
case EEZE_UDEV_TYPE_DRIVE_INTERNAL:
udev_enumerate_add_match_subsystem(en, "block");
udev_enumerate_add_match_property(en, "ID_TYPE", "disk");
udev_enumerate_add_match_property(en, "ID_BUS", "ata");
udev_enumerate_add_match_sysattr(en, "removable", "0");
break;
case EEZE_UDEV_TYPE_DRIVE_REMOVABLE:
udev_enumerate_add_match_subsystem(en, "block");
udev_enumerate_add_match_property(en, "ID_TYPE", "disk");
udev_enumerate_add_match_sysattr(en, "removable", "1");
break;
case EEZE_UDEV_TYPE_DRIVE_CDROM:
udev_enumerate_add_match_subsystem(en, "block");
udev_enumerate_add_match_property(en, "ID_CDROM", "1");
break;
case EEZE_UDEV_TYPE_POWER_AC:
udev_enumerate_add_match_subsystem(en, "power_supply");
udev_enumerate_add_match_property(en, "POWER_SUPPLY_TYPE", "Mains");
break;
case EEZE_UDEV_TYPE_POWER_BAT:
udev_enumerate_add_match_subsystem(en, "power_supply");
udev_enumerate_add_match_property(en, "POWER_SUPPLY_TYPE", "Battery");
break;
/*
case EEZE_UDEV_TYPE_ANDROID:
udev_enumerate_add_match_subsystem(en, "block");
udev_enumerate_add_match_property(en, "ID_MODEL", "Android_*");
break;
*/
default:
break;
}
udev_enumerate_scan_devices(en);
devs = udev_enumerate_get_list_entry(en);
udev_list_entry_foreach(cur, devs)
{
devname = udev_list_entry_get_name(cur);
device = udev_device_new_from_syspath(udev, devname);
if (name)
if (!strstr(devname,name))
goto out;
ret = eina_list_append(ret, eina_stringshare_add(devname));
out:
udev_device_unref(device);
}
udev_enumerate_unref(en);
udev_unref(udev);
return ret;
}
/**
* A more advanced find, allows finds using udev properties.
*
* @param subsystem The udev subsystem to filter by, or NULL
* @param type "ID_INPUT_KEY", "ID_INPUT_MOUSE", "ID_INPUT_TOUCHPAD", NULL, etc
* @param name A filter for the device name, or NULL
* @return A Eina_List* of matched devices or NULL on failure
*
* Return a list of syspaths (/sys/$syspath) for matching udev devices.
* Requires at least one filter.
*
* @ingroup udev
*/
EAPI Eina_List *
eeze_udev_find_by_filter(const char *subsystem, const char *type, const char *name)
{
struct udev *udev;
struct udev_enumerate *en;
struct udev_list_entry *devs, *cur;
struct udev_device *device;
const char *devname;
Eina_List *ret = NULL;
if ((!subsystem) && (!type) && (!name)) return NULL;
udev = udev_new();
if (!udev) return NULL;
en = udev_enumerate_new(udev);
if (!en) return NULL;
if (subsystem)
udev_enumerate_add_match_subsystem(en, subsystem);
udev_enumerate_add_match_property(en, type, "1");
udev_enumerate_scan_devices(en);
devs = udev_enumerate_get_list_entry(en);
udev_list_entry_foreach(cur, devs)
{
devname = udev_list_entry_get_name(cur);
device = udev_device_new_from_syspath(udev, devname);
if (name)
if (!strstr(devname,name))
goto out;
ret = eina_list_append(ret, eina_stringshare_add(devname));
out:
udev_device_unref(device);
}
udev_enumerate_unref(en);
udev_unref(udev);
return ret;
}
/**
* Find a list of devices by a sysattr (and, optionally, a value of that sysattr).
*
* @param sysattr The attribute to find
* @param value Optional: the value that the attribute should have
*
* @return A list of the devices found with the attribute
*/
EAPI Eina_List *
eeze_udev_find_by_sysattr(const char *sysattr, const char *value)
{
struct udev *udev;
struct udev_enumerate *en;
struct udev_list_entry *devs, *cur;
struct udev_device *device;
const char *devname;
Eina_List *ret = NULL;
if (!sysattr) return NULL;
udev = udev_new();
if (!udev) return NULL;
en = udev_enumerate_new(udev);
if (!en) return NULL;
udev_enumerate_add_match_sysattr(en, sysattr, value);
udev_enumerate_scan_devices(en);
devs = udev_enumerate_get_list_entry(en);
udev_list_entry_foreach(cur, devs)
{
devname = udev_list_entry_get_name(cur);
device = udev_device_new_from_syspath(udev, devname);
ret = eina_list_append(ret, eina_stringshare_add(devname));
udev_device_unref(device);
}
udev_enumerate_unref(en);
udev_unref(udev);
return ret;
}

View File

@ -0,0 +1,73 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <Eeze_Udev.h>
#include "eeze_udev_private.h"
/**
* private function to simulate udevadm info -a
* walks up the device tree checking each node for sysattr
* with value $value
*/
Eina_Bool
_walk_parents_for_attr(struct udev_device *device, const char *sysattr, const char* value)
{
struct udev_device *parent, *child = device;
const char *test;
parent = udev_device_get_parent(child);
for (; parent; child = parent, parent = udev_device_get_parent(child))
{
if (!(test = udev_device_get_sysattr_value(parent, sysattr)))
continue;
if (!value)
return 1;
else if (!strcmp(test, value))
return 1;
}
return 0;
}
/**
* check a list for all parents of a device,
* stringshare adding all devices that are not in the list
*/
void
_get_unlisted_parents(Eina_List *list, struct udev_device *device)
{
struct udev_device *parent, *child = device;
const char *test, *devname, *vendor, *vendor2, *model, *model2;
Eina_List *l;
Eina_Bool found;
vendor = udev_device_get_property_value(child, "ID_VENDOR_ID");
model = udev_device_get_property_value(child, "ID_MODEL_ID");
parent = udev_device_get_parent(child);
for (; parent; child = parent, parent = udev_device_get_parent(child))
{
found = 0;
model2 = udev_device_get_property_value(parent, "ID_MODEL_ID");
vendor2 = udev_device_get_property_value(parent, "ID_VENDOR_ID");
if ((!model2 && model) || (model2 && !model))
break;
else if ((!vendor2 && vendor) || (vendor2 && !vendor))
break;
else if (strcmp(model, model2) ||
strcmp(vendor, vendor2))
break;
devname = udev_device_get_syspath(parent);
EINA_LIST_FOREACH(list, l, test)
{
if (!strcmp(test, devname))
{
found = 1;
break;
}
}
if (!found)
list = eina_list_prepend(list, eina_stringshare_add(devname));
}
return;
}

View File

@ -1,6 +1,6 @@
#ifndef EEZE_UDEV_PRIVATE_H
#define EEZE_UDEV_PRIVATE_H
#include "Eeze_Udev.h"
#ifndef E_EEZE_COLOR_DEFAULT
#define E_EEZE_COLOR_DEFAULT EINA_COLOR_CYAN
#endif
@ -23,4 +23,8 @@ extern int _e_eeze_udev_log_dom;
#define WARN(...) EINA_LOG_DOM_WARN(_e_eeze_udev_log_dom, __VA_ARGS__)
#define ERR(...) EINA_LOG_DOM_ERR(_e_eeze_udev_log_dom, __VA_ARGS__)
/* from watch.c */
Eina_Bool _walk_parents_for_attr(struct udev_device *device, const char *sysattr, const char* value);
void _get_unlisted_parents(Eina_List *list, struct udev_device *device);
#endif

View File

@ -1,5 +1,9 @@
#include "eeze_udev_private.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <Eeze_Udev.h>
#include "eeze_udev_private.h"
/* opaque */
struct Eeze_Udev_Watch
@ -20,31 +24,9 @@ struct _store_data
};
/* private function to simulate udevadm info -a
* walks up the device tree checking each node for sysattr
* with value value
*/
Eina_Bool
_walk_parents_for_attr(struct udev_device *device, const char *sysattr, const char* value)
{
struct udev_device *parent, *child = device;
const char *test;
for (parent = udev_device_get_parent(child); parent; child = parent, parent = udev_device_get_parent(child))
{
if (!(test = udev_device_get_sysattr_value(parent, sysattr)))
continue;
if (!value)
return 1;
else if (!strcmp(test, value))
return 1;
}
return 0;
}
/* private function to further filter watch results based on Eeze_Udev_Type
* specified
* specified; helpful for new udev versions, but absolutely required for
* old udev, which does not implement filtering in device monitors.
*/
static int
_get_syspath_from_watch(void *data, Ecore_Fd_Handler *fd_handler)