Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6de783af authored by Rob Herring's avatar Rob Herring Committed by Elliott Hughes
Browse files

init: support matching sysfs class paths in ueventd.rc



Currently, ueventd.rc files only support /sys/devices/... paths
and don't support symlinked paths, specifically /sys/class/...
Supporting the class paths is necessary to have non-hardware
dependent paths. Some subsystems like IIO use /sys/bus/iio/, so
support that as well.

Change-Id: I29f3bf67b41664d1d75ac1820c46e13afe336d56
Signed-off-by: default avatarRob Herring <robh@kernel.org>
parent 0504a94c
Loading
Loading
Loading
Loading
+23 −14
Original line number Original line Diff line number Diff line
@@ -43,6 +43,7 @@
#include <sys/wait.h>
#include <sys/wait.h>


#include <android-base/file.h>
#include <android-base/file.h>
#include <android-base/stringprintf.h>
#include <cutils/list.h>
#include <cutils/list.h>
#include <cutils/uevent.h>
#include <cutils/uevent.h>


@@ -146,21 +147,29 @@ static bool perm_path_matches(const char *path, struct perms_ *dp)
    return false;
    return false;
}
}


void fixup_sys_perms(const char *upath)
static bool match_subsystem(perms_* dp, const char* pattern,
{
                            const char* path, const char* subsystem) {
    struct listnode *node;
    if (!pattern || !subsystem || strstr(dp->name, subsystem) == NULL) {
        return false;
    }


    /* upaths omit the "/sys" that paths in this list
    std::string subsys_path = android::base::StringPrintf(pattern, subsystem, basename(path));
     * contain, so we prepend it...
    return perm_path_matches(subsys_path.c_str(), dp);
     */
}
    std::string path = SYSFS_PREFIX;
    path += upath;


    list_for_each(node, &sys_perms) {
static void fixup_sys_perms(const char* upath, const char* subsystem) {
        perms_ *dp;
    // upaths omit the "/sys" that paths in this list
    // contain, so we prepend it...
    std::string path = std::string(SYSFS_PREFIX) + upath;


        dp = &(node_to_item(node, struct perm_node, plist))->dp;
    listnode* node;
        if (!perm_path_matches(path.c_str(), dp)) {
    list_for_each(node, &sys_perms) {
        perms_* dp = &(node_to_item(node, perm_node, plist))->dp;
        if (match_subsystem(dp, SYSFS_PREFIX "/class/%s/%s", path.c_str(), subsystem)) {
            ; // matched
        } else if (match_subsystem(dp, SYSFS_PREFIX "/bus/%s/devices/%s", path.c_str(), subsystem)) {
            ; // matched
        } else if (!perm_path_matches(path.c_str(), dp)) {
            continue;
            continue;
        }
        }


@@ -734,7 +743,7 @@ static void handle_generic_device_event(struct uevent *uevent)
static void handle_device_event(struct uevent *uevent)
static void handle_device_event(struct uevent *uevent)
{
{
    if (!strcmp(uevent->action,"add") || !strcmp(uevent->action, "change") || !strcmp(uevent->action, "online"))
    if (!strcmp(uevent->action,"add") || !strcmp(uevent->action, "change") || !strcmp(uevent->action, "online"))
        fixup_sys_perms(uevent->path);
        fixup_sys_perms(uevent->path, uevent->subsystem);


    if (!strncmp(uevent->subsystem, "block", 5)) {
    if (!strncmp(uevent->subsystem, "block", 5)) {
        handle_block_device_event(uevent);
        handle_block_device_event(uevent);