⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 devices.c

📁 Android 一些工具
💻 C
📖 第 1 页 / 共 2 页
字号:
            msg += 7;            uevent->action = msg;        } else if(!strncmp(msg, "DEVPATH=", 8)) {            msg += 8;            uevent->path = msg;        } else if(!strncmp(msg, "SUBSYSTEM=", 10)) {            msg += 10;            uevent->subsystem = msg;        } else if(!strncmp(msg, "FIRMWARE=", 9)) {            msg += 9;            uevent->firmware = msg;        } else if(!strncmp(msg, "MAJOR=", 6)) {            msg += 6;            uevent->major = atoi(msg);        } else if(!strncmp(msg, "MINOR=", 6)) {            msg += 6;            uevent->minor = atoi(msg);        }            /* advance to after the next \0 */        while(*msg++)            ;    }    log_event_print("event { '%s', '%s', '%s', '%s', %d, %d }\n",                    uevent->action, uevent->path, uevent->subsystem,                    uevent->firmware, uevent->major, uevent->minor);}static void handle_device_event(struct uevent *uevent){    char devpath[96];    char *base, *name;    int block;        /* if it's not a /dev device, nothing to do */    if((uevent->major < 0) || (uevent->minor < 0))        return;        /* do we have a name? */    name = strrchr(uevent->path, '/');    if(!name)        return;    name++;        /* too-long names would overrun our buffer */    if(strlen(name) > 64)        return;        /* are we block or char? where should we live? */    if(!strncmp(uevent->path, "/block", 6)) {        block = 1;        base = "/dev/block/";        mkdir(base, 0755);    } else {        block = 0;            /* this should probably be configurable somehow */        if(!strncmp(uevent->path, "/class/graphics/", 16)) {            base = "/dev/graphics/";            mkdir(base, 0755);        } else if (!strncmp(uevent->path, "/class/oncrpc/", 14)) {            base = "/dev/oncrpc/";            mkdir(base, 0755);        } else if (!strncmp(uevent->path, "/class/adsp/", 12)) {            base = "/dev/adsp/";            mkdir(base, 0755);      } else if(!strncmp(uevent->path, "/class/input/", 13)) {            base = "/dev/input/";            mkdir(base, 0755);        } else if(!strncmp(uevent->path, "/class/mtd/", 11)) {            base = "/dev/mtd/";            mkdir(base, 0755);        } else if(!strncmp(uevent->path, "/class/misc/", 12) &&                    !strncmp(name, "log_", 4)) {            base = "/dev/log/";            mkdir(base, 0755);            name += 4;        } else            base = "/dev/";    }    snprintf(devpath, sizeof(devpath), "%s%s", base, name);    if(!strcmp(uevent->action, "add")) {        make_device(devpath, block, uevent->major, uevent->minor);        return;    }    if(!strcmp(uevent->action, "remove")) {        unlink(devpath);        return;    }}static int load_firmware(int fw_fd, int loading_fd, int data_fd){    struct stat st;    long len_to_copy;    int ret = 0;    if(fstat(fw_fd, &st) < 0)        return -1;    len_to_copy = st.st_size;    write(loading_fd, "1", 1);  /* start transfer */    while (len_to_copy > 0) {        char buf[PAGE_SIZE];        ssize_t nr;        nr = read(fw_fd, buf, sizeof(buf));        if(!nr)            break;        if(nr < 0) {            ret = -1;            break;        }        len_to_copy -= nr;        while (nr > 0) {            ssize_t nw = 0;            nw = write(data_fd, buf + nw, nr);            if(nw <= 0) {                ret = -1;                goto out;            }            nr -= nw;        }    }out:    if(!ret)        write(loading_fd, "0", 1);  /* successful end of transfer */    else        write(loading_fd, "-1", 2); /* abort transfer */    return ret;}static void process_firmware_event(struct uevent *uevent){    char *root, *loading, *data, *file;    int l, loading_fd, data_fd, fw_fd;    log_event_print("firmware event { '%s', '%s' }\n",                    uevent->path, uevent->firmware);    l = asprintf(&root, SYSFS_PREFIX"%s/", uevent->path);    if (l == -1)        return;    l = asprintf(&loading, "%sloading", root);    if (l == -1)        goto root_free_out;    l = asprintf(&data, "%sdata", root);    if (l == -1)        goto loading_free_out;    l = asprintf(&file, FIRMWARE_DIR"/%s", uevent->firmware);    if (l == -1)        goto data_free_out;    loading_fd = open(loading, O_WRONLY);    if(loading_fd < 0)        goto file_free_out;    data_fd = open(data, O_WRONLY);    if(data_fd < 0)        goto loading_close_out;    fw_fd = open(file, O_RDONLY);    if(fw_fd < 0)        goto data_close_out;    if(!load_firmware(fw_fd, loading_fd, data_fd))        log_event_print("firmware copy success { '%s', '%s' }\n", root, file);    else        log_event_print("firmware copy failure { '%s', '%s' }\n", root, file);    close(fw_fd);data_close_out:    close(data_fd);loading_close_out:    close(loading_fd);file_free_out:    free(file);data_free_out:    free(data);loading_free_out:    free(loading);root_free_out:    free(root);}static void handle_firmware_event(struct uevent *uevent){    pid_t pid;    if(strcmp(uevent->subsystem, "firmware"))        return;    if(strcmp(uevent->action, "add"))        return;    /* we fork, to avoid making large memory allocations in init proper */    pid = fork();    if (!pid) {        process_firmware_event(uevent);        exit(EXIT_SUCCESS);    }}#define UEVENT_MSG_LEN  1024void handle_device_fd(int fd){    char msg[UEVENT_MSG_LEN+2];    int n;    while((n = recv(fd, msg, UEVENT_MSG_LEN, 0)) > 0) {        struct uevent uevent;        if(n == UEVENT_MSG_LEN)   /* overflow -- discard */            continue;        msg[n] = '\0';        msg[n+1] = '\0';        parse_event(msg, &uevent);        handle_device_event(&uevent);        handle_firmware_event(&uevent);    }}/* Coldboot walks parts of the /sys tree and pokes the uevent files** to cause the kernel to regenerate device add events that happened** before init's device manager was started**** We drain any pending events from the netlink socket every time** we poke another uevent file to make sure we don't overrun the** socket's buffer.  */static void do_coldboot(int event_fd, DIR *d){    struct dirent *de;    int dfd, fd;    dfd = dirfd(d);    fd = openat(dfd, "uevent", O_WRONLY);    if(fd >= 0) {        write(fd, "add\n", 4);        close(fd);        handle_device_fd(event_fd);    }    while((de = readdir(d))) {        DIR *d2;        if(de->d_type != DT_DIR || de->d_name[0] == '.')            continue;        fd = openat(dfd, de->d_name, O_RDONLY | O_DIRECTORY);        if(fd < 0)            continue;        d2 = fdopendir(fd);        if(d2 == 0)            close(fd);        else {            do_coldboot(event_fd, d2);            closedir(d2);        }    }}static void coldboot(int event_fd, const char *path){    DIR *d = opendir(path);    if(d) {        do_coldboot(event_fd, d);        closedir(d);    }}int device_init(void){    suseconds_t t0, t1;    int fd;    fd = open_uevent_socket();    if(fd < 0)        return -1;    fcntl(fd, F_SETFD, FD_CLOEXEC);    fcntl(fd, F_SETFL, O_NONBLOCK);    t0 = get_usecs();    coldboot(fd, "/sys/class");    coldboot(fd, "/sys/block");    coldboot(fd, "/sys/devices");    t1 = get_usecs();    log_event_print("coldboot %ld uS\n", ((long) (t1 - t0)));    return fd;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -