diff options
| author | Greg Hackmann <ghackmann@google.com> | 2013-11-27 17:09:20 +0000 |
|---|---|---|
| committer | Android Git Automerger <android-git-automerger@android.com> | 2013-11-27 17:09:20 +0000 |
| commit | bf5e7ed84e51f40da30a1350cdc3124c19a3484c (patch) | |
| tree | 4380d8d3725814b9eb31f160cbceed18e98869ec /init/devices.c | |
| parent | dde75d940a0f8c177fea9299c26959eeb6707033 (diff) | |
| parent | 5ebd8e43ba992d12fcdac4aedf7da51b50d6b949 (diff) | |
| download | system_core-bf5e7ed84e51f40da30a1350cdc3124c19a3484c.zip system_core-bf5e7ed84e51f40da30a1350cdc3124c19a3484c.tar.gz system_core-bf5e7ed84e51f40da30a1350cdc3124c19a3484c.tar.bz2 | |
am 5ebd8e43: am b2406973: Merge changes I727d9135,I3bd1b59d,I0d05aa28
* commit '5ebd8e43ba992d12fcdac4aedf7da51b50d6b949':
rootdir: add ueventd.rc rule for adf subsystem
init: add subsystem rules to ueventd.rc
init: handle ueventd path truncation better
Diffstat (limited to 'init/devices.c')
| -rw-r--r-- | init/devices.c | 83 |
1 files changed, 63 insertions, 20 deletions
diff --git a/init/devices.c b/init/devices.c index af88c5f..f7df453 100644 --- a/init/devices.c +++ b/init/devices.c @@ -44,6 +44,7 @@ #include <cutils/uevent.h> #include "devices.h" +#include "ueventd_parser.h" #include "util.h" #include "log.h" @@ -530,8 +531,11 @@ static const char *parse_device_name(struct uevent *uevent, unsigned int len) name++; /* too-long names would overrun our buffer */ - if(strlen(name) > len) + if(strlen(name) > len) { + ERROR("DEVPATH=%s exceeds %u-character limit on filename; ignoring event\n", + name, len); return NULL; + } return name; } @@ -557,37 +561,76 @@ static void handle_block_device_event(struct uevent *uevent) uevent->major, uevent->minor, links); } +#define DEVPATH_LEN 96 + +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) { + ERROR("failed to assemble device path (%s); ignoring event\n", + strerror(errno)); + return false; + } else if (s >= DEVPATH_LEN) { + ERROR("%s/%s exceeds %u-character limit on path; ignoring event\n", + dirname, devname, DEVPATH_LEN); + return false; + } + return true; +} + +static void mkdir_recursive_for_devpath(const char *devpath) +{ + char dir[DEVPATH_LEN]; + char *slash; + + strcpy(dir, devpath); + slash = strrchr(dir, '/'); + *slash = '\0'; + mkdir_recursive(dir, 0755); +} + static void handle_generic_device_event(struct uevent *uevent) { char *base; const char *name; - char devpath[96] = {0}; + char devpath[DEVPATH_LEN] = {0}; char **links = NULL; name = parse_device_name(uevent, 64); if (!name) return; - if (!strncmp(uevent->subsystem, "usb", 3)) { + struct ueventd_subsystem *subsystem = + ueventd_subsystem_find_by_name(uevent->subsystem); + + if (subsystem) { + const char *devname; + + switch (subsystem->devname_src) { + case DEVNAME_UEVENT_DEVNAME: + devname = uevent->device_name; + break; + + case DEVNAME_UEVENT_DEVPATH: + devname = name; + break; + + default: + ERROR("%s subsystem's devpath option is not set; ignoring event\n", + uevent->subsystem); + return; + } + + if (!assemble_devpath(devpath, subsystem->dirname, devname)) + return; + mkdir_recursive_for_devpath(devpath); + } else if (!strncmp(uevent->subsystem, "usb", 3)) { if (!strcmp(uevent->subsystem, "usb")) { if (uevent->device_name) { - /* - * create device node provided by kernel if present - * see drivers/base/core.c - */ - char *p = devpath; - snprintf(devpath, sizeof(devpath), "/dev/%s", uevent->device_name); - /* skip leading /dev/ */ - p += 5; - /* build directories */ - while (*p) { - if (*p == '/') { - *p = 0; - make_dir(devpath, 0755); - *p = '/'; - } - p++; - } + if (!assemble_devpath(devpath, "/dev", uevent->device_name)) + return; + mkdir_recursive_for_devpath(devpath); } else { /* This imitates the file system that would be created |
