ueventd: Fix up string handling in handle_*_device_event()

Bug: 36250207

Test: Boot bullhead
Test: Boot sailfish, observe no boot time regression
Test: init unit tests

Change-Id: Ie5ec609a3f74bb03f5920734ada4d7de57508de4
diff --git a/init/devices.cpp b/init/devices.cpp
index 4d63448..6cd3564 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -604,93 +604,35 @@
         remove_platform_device(path);
 }
 
-static const char *parse_device_name(struct uevent *uevent, unsigned int len)
-{
-    const char *name;
+static void handle_block_device_event(uevent* uevent) {
+    // if it's not a /dev device, nothing to do
+    if (uevent->major < 0 || uevent->minor < 0) return;
 
-    /* if it's not a /dev device, nothing else to do */
-    if((uevent->major < 0) || (uevent->minor < 0))
-        return NULL;
-
-    /* do we have a name? */
-    name = strrchr(uevent->path, '/');
-    if(!name)
-        return NULL;
-    name++;
-
-    /* too-long names would overrun our buffer */
-    if(strlen(name) > len) {
-        LOG(ERROR) << "DEVPATH=" << name << " exceeds " << len << "-character limit on filename; ignoring event";
-        return NULL;
-    }
-
-    return name;
-}
-
-#define DEVPATH_LEN 96
-#define MAX_DEV_NAME 64
-
-static void handle_block_device_event(struct uevent *uevent)
-{
-    const char *base = "/dev/block/";
-    const char *name;
-    char devpath[DEVPATH_LEN];
-
-    name = parse_device_name(uevent, MAX_DEV_NAME);
-    if (!name)
-        return;
-
-    snprintf(devpath, sizeof(devpath), "%s%s", base, name);
+    const char* base = "/dev/block/";
     make_dir(base, 0755);
 
+    std::string name = android::base::Basename(uevent->path);
+    std::string devpath = base + name;
+
     std::vector<std::string> links;
     if (!strncmp(uevent->path, "/devices/", 9))
         links = get_block_device_symlinks(uevent);
 
-    handle_device(uevent->action, devpath, uevent->path, 1,
-            uevent->major, uevent->minor, links);
+    handle_device(uevent->action, devpath.c_str(), uevent->path, 1, uevent->major, uevent->minor,
+                  links);
 }
 
-static bool assemble_devpath(char *devpath, const char *dirname,
-        const char *devname)
-{
-    int s = snprintf(devpath, DEVPATH_LEN, "%s/%s", dirname, devname);
-    if (s < 0) {
-        PLOG(ERROR) << "failed to assemble device path; ignoring event";
-        return false;
-    } else if (s >= DEVPATH_LEN) {
-        LOG(ERROR) << dirname << "/" << devname
-                   << " exceeds " << DEVPATH_LEN << "-character limit on path; ignoring event";
-        return false;
-    }
-    return true;
-}
+static void handle_generic_device_event(uevent* uevent) {
+    // if it's not a /dev device, nothing to do
+    if (uevent->major < 0 || uevent->minor < 0) return;
 
-static void mkdir_recursive_for_devpath(const char *devpath)
-{
-    char dir[DEVPATH_LEN];
-    char *slash;
+    std::string name = android::base::Basename(uevent->path);
+    ueventd_subsystem* subsystem = ueventd_subsystem_find_by_name(uevent->subsystem);
 
-    strcpy(dir, devpath);
-    slash = strrchr(dir, '/');
-    *slash = '\0';
-    mkdir_recursive(dir, 0755);
-}
-
-static void handle_generic_device_event(struct uevent *uevent)
-{
-    const char *name;
-    char devpath[DEVPATH_LEN] = {0};
-
-    name = parse_device_name(uevent, MAX_DEV_NAME);
-    if (!name)
-        return;
-
-    struct ueventd_subsystem *subsystem =
-            ueventd_subsystem_find_by_name(uevent->subsystem);
+    std::string devpath;
 
     if (subsystem) {
-        const char *devname;
+        std::string devname;
 
         switch (subsystem->devname_src) {
         case DEVNAME_UEVENT_DEVNAME:
@@ -706,41 +648,35 @@
             return;
         }
 
-        if (!assemble_devpath(devpath, subsystem->dirname, devname))
-            return;
-        mkdir_recursive_for_devpath(devpath);
+        // TODO: Remove std::string()
+        devpath = std::string(subsystem->dirname) + "/" + devname;
+        mkdir_recursive(android::base::Dirname(devpath), 0755);
     } else if (!strncmp(uevent->subsystem, "usb", 3)) {
-         if (!strcmp(uevent->subsystem, "usb")) {
+        if (!strcmp(uevent->subsystem, "usb")) {
             if (uevent->device_name) {
-                if (!assemble_devpath(devpath, "/dev", uevent->device_name))
-                    return;
-                mkdir_recursive_for_devpath(devpath);
-             }
-             else {
-                 /* This imitates the file system that would be created
-                  * if we were using devfs instead.
-                  * Minors are broken up into groups of 128, starting at "001"
-                  */
-                 int bus_id = uevent->minor / 128 + 1;
-                 int device_id = uevent->minor % 128 + 1;
-                 /* build directories */
-                 make_dir("/dev/bus", 0755);
-                 make_dir("/dev/bus/usb", 0755);
-                 snprintf(devpath, sizeof(devpath), "/dev/bus/usb/%03d", bus_id);
-                 make_dir(devpath, 0755);
-                 snprintf(devpath, sizeof(devpath), "/dev/bus/usb/%03d/%03d", bus_id, device_id);
-             }
-         } else {
-             /* ignore other USB events */
-             return;
-         }
+                // TODO: Remove std::string
+                devpath = "/dev/" + std::string(uevent->device_name);
+            } else {
+                // This imitates the file system that would be created
+                // if we were using devfs instead.
+                // Minors are broken up into groups of 128, starting at "001"
+                int bus_id = uevent->minor / 128 + 1;
+                int device_id = uevent->minor % 128 + 1;
+                devpath = android::base::StringPrintf("/dev/bus/usb/%03d/%03d", bus_id, device_id);
+            }
+            mkdir_recursive(android::base::Dirname(devpath), 0755);
+        } else {
+            // ignore other USB events
+            return;
+        }
     } else {
-        snprintf(devpath, sizeof(devpath), "/dev/%s", name);
+        devpath = "/dev/" + name;
     }
 
     auto links = get_character_device_symlinks(uevent);
 
-    handle_device(uevent->action, devpath, uevent->path, 0, uevent->major, uevent->minor, links);
+    handle_device(uevent->action, devpath.c_str(), uevent->path, 0, uevent->major, uevent->minor,
+                  links);
 }
 
 static void handle_device_event(struct uevent *uevent)