当前位置: 首页 > news >正文

wordpress站点地图裂变营销五种模式十六种方法

wordpress站点地图,裂变营销五种模式十六种方法,网站 二维码的作用,影楼网站模板下载frameworks 之getEvent指令 指令解析源码追溯源码解析1.解析参数2.初始化ufds数组3.添加到poll 并做对应处理 通过 getEvent 可以识别按键基本命令和里面的关键信息 涉及到的类如下 system/core/toolbox/toolbox.csystem/core/toolbox/tools.hsystem/core/toolbox/getevent.c …

frameworks 之getEvent指令

  • 指令解析
  • 源码追溯
  • 源码解析
    • 1.解析参数
    • 2.初始化ufds数组
    • 3.添加到poll 并做对应处理

通过 getEvent 可以识别按键基本命令和里面的关键信息
涉及到的类如下

  • system/core/toolbox/toolbox.c
  • system/core/toolbox/tools.h
  • system/core/toolbox/getevent.c

指令解析

通过 getEvent -h 可打印出相关的指令帮助,对应的指令注释如下。输出的数字都为16进制

houji:/ $ getevent -help
Usage: getevent [-t] [-n] [-s switchmask] [-S] [-v [mask]] [-d] [-p] [-i] [-l] [-q] [-c count] [-r] [device]-t: show time stamps  // 打印时间戳-n: don't print newlines // 不换行-s: print switch states for given bits // 打印指定位的开关状态-S: print all switch states // 打印所有开关状态-v: verbosity mask (errs=1, dev=2, name=4, info=8, vers=16, pos. events=32, props=64) // 根据 mask 值显示相关信息,执行后会一直显示上报数据,详细掩码(错误=1,dev=2,名称=4,信息=8,错误=16,位置事件=32,道具=64)默认显示 dev| name| info| vers = 30-d: show HID descriptor, if available // 如果设备可用,显示设备隐藏的描述信息-p: show possible events (errs, dev, name, pos. events) // 显示设备支持的事件类型和编码方式-i: show all device info and possible events // 显示设备的所有信息和支持的事件,比 -p 显示更多信息-l: label event types and names in plain text // 以文本形式输出事件类型和名称,比 -t 更清楚直观-q: quiet (clear verbosity mask) // 以文本形式输出事件类型和名称,比 -t 更清楚直观-c: print given number of events then exit // 打印固定数量的事件并退出-r: print rate events are received // 显示事件上报速率

其中 -v 打印输入设备的详细信息,默认为 默认显示 dev| name| info| vers = 30

emulator_x86_64:/ # getevent -v
add device 1: /dev/input/event0bus:      0019vendor    0000product   0001version   0000name:     "Power Button"location: "LNXPWRBN/button/input0"id:       ""version:  1.0.1

-l 打印的信息 分别对应 type code value

emulator_x86_64:/ # getevent -l                                               
/dev/input/event3: EV_ABS       ABS_MT_TRACKING_ID   00000000            
/dev/input/event3: EV_ABS       ABS_MT_POSITION_X    000031af            
/dev/input/event3: EV_ABS       ABS_MT_POSITION_Y    00004447 

参数可以组合使用,一次性查看需要的触摸屏信息,常用的命令组合为 getevent -ltr

emulator_x86_64:/ # getevent -ltr                                         
[    1384.965200] /dev/input/event3: EV_ABS       ABS_MT_TRACKING_ID   00000000  

源码追溯

可以执行, 则表示 system/bin 有对应的脚本。所以可以通过执行对应的打印 查看文件。通过命令 ls -l | grep event 过滤对应的关键字可以看到 该事件通过 软链接(前面开头为l开头即为软链接)。链接到 toolbox

emulator_x86_64:/system/bin # ls -l | grep event 
lrwxr-xr-x 1 root shell       7 2024-08-17 22:51 getevent -> toolbox
-rwxr-xr-x 1 root shell    3925 2024-03-18 00:26 mm_events
lrwxr-xr-x 1 root shell       6 2024-08-17 22:51 sendevent -> toybox
lrwxr-xr-x 1 root shell       4 2024-08-17 22:51 ueventd -> init

回到源码文件,一般工具类 在 system 目录下,可以先通过该目录查找。执行 find -name toolbox。可以看到在该**./core/toolbox** 文件夹下。
在这里插入图片描述
跳转到该文件夹下,查看对应的文件打印,查看对应的Bp文件。包含以下文件,可以看出入口为
toolbox.c 文件夹。

cc_defaults {...srcs: ["toolbox.c","getevent.c","getprop.cpp","modprobe.cpp","setprop.cpp","start.cpp",],...
}

对应的 main 入口如下,该方法通过读取参数,遍历数组 ,然后判断名称和命令是否相等,相等就执行对应的 func 方法。对应 tools[] 数组 在文件前面定义,定义了名词和执行的方法。
会根据 name 拼接对应的执行方法。如 getEvent 拼接完为 getevent_main。相关数组定义在 tools.h 头文件里面。

// system/core/toolbox/tools.c
#define TOOL(name) int name##_main(int, char**); // 拼接对应的执行方法名称
#include "tools.h"
#undef TOOL
// 定义对应的数组,数组内容来自 tools.h定义
static struct {const char* name;int (*func)(int, char**);
} tools[] = {
#define TOOL(name) { #name, name##_main },
#include "tools.h"
#undef TOOL{ 0, 0 },
};int main(int argc, char** argv) {// Let's assume that none of this code handles broken pipes. At least ls,// ps, and top were broken (though I'd previously added this fix locally// to top). We exit rather than use SIG_IGN because tools like top will// just keep on writing to nowhere forever if we don't stop them.signal(SIGPIPE, SIGPIPE_handler);// 获取第一个参数,遍历数组,判断是否和名称相等,相等执行对应的方法。char* cmd = strrchr(argv[0], '/');char* name = cmd ? (cmd + 1) : argv[0];for (size_t i = 0; tools[i].name; i++) {if (!strcmp(tools[i].name, name)) {return tools[i].func(argc, argv);}}printf("%s: no such tool\n", argv[0]);return 127;
}

头文件定义

// system/core/toolbox/tools.h
TOOL(getevent)
TOOL(getprop)
TOOL(modprobe)
TOOL(setprop)
TOOL(start)
TOOL(stop)
TOOL(toolbox)

所以运行脚本 执行的方法 在 getevent.c 下的 getevent_main方法下。

源码解析

1.解析参数

查看对应的方法 main 方法,可以看到 第一步 通过 getopt 解析对应的参数
部分参数通过 或 记录到 print_flags 中。

opterr = 0;do {c = getopt(argc, argv, "tns:Sv::dpilqc:rh"); // 解析对应的参数if (c == EOF)break;switch (c) {case 't':get_time = 1;break;case 'n':newline = "";break;case 's':get_switch = strtoul(optarg, NULL, 0);if(dont_block == -1)dont_block = 1;break;case 'S':get_switch = ~0;if(dont_block == -1)dont_block = 1;break;case 'v':if(optarg)print_flags |= strtoul(optarg, NULL, 0);elseprint_flags |= PRINT_DEVICE | PRINT_DEVICE_NAME | PRINT_DEVICE_INFO | PRINT_VERSION;print_flags_set = 1;break;case 'd':print_flags |= PRINT_HID_DESCRIPTOR;break;case 'p':print_flags |= PRINT_DEVICE_ERRORS | PRINT_DEVICE| PRINT_DEVICE_NAME | PRINT_POSSIBLE_EVENTS | PRINT_INPUT_PROPS;print_flags_set = 1;if(dont_block == -1)dont_block = 1;break;case 'i':print_flags |= PRINT_ALL_INFO;print_flags_set = 1;if(dont_block == -1)dont_block = 1;break;case 'l':print_flags |= PRINT_LABELS;break;case 'q':print_flags_set = 1;break;case 'c':event_count = atoi(optarg); //解析对应参数值dont_block = 0;break;case 'r':sync_rate = 1;break;case '?':fprintf(stderr, "%s: invalid option -%c\n",argv[0], optopt);case 'h':usage(argv[0]); // 打印帮助exit(1);}} while (1);if(dont_block == -1)dont_block = 0;if (optind + 1 == argc) {device = argv[optind];optind++;}if (optind != argc) {usage(argv[0]);exit(1);}

2.初始化ufds数组

第二步,会通过 device 判断是否 观察单个或者全部 。如如果我们 执行的命令后面加了对应的设备,则只会观察对应的设备 如 getevent -ltr /dev/input/event1。其中 inotify_init 获取了 dev/input 文件夹对应的监听。 然后通过 inotify_add_watch。进行删除和添加的监听。

	nfds = 1;ufds = calloc(1, sizeof(ufds[0]));ufds[0].fd = inotify_init();ufds[0].events = POLLIN;// 打印单个设备对应信息if(device) {if(!print_flags_set)print_flags |= PRINT_DEVICE_ERRORS;// 通过 open 方法打开对应的驱动,并通过 ioctl 获取对应的信息,并放到对应的 ufds 数组res = open_device(device, print_flags);if(res < 0) {return 1;}} else { // 打印全部if(!print_flags_set)print_flags |= PRINT_DEVICE_ERRORS | PRINT_DEVICE | PRINT_DEVICE_NAME;print_device = 1;// 添加删除和添加对应文件夹的监听res = inotify_add_watch(ufds[0].fd, device_path, IN_DELETE | IN_CREATE);if(res < 0) {fprintf(stderr, "could not add watch for %s, %s\n", device_path, strerror(errno));return 1;}// 遍历该文件夹 dev/input 文件夹下所有的res = scan_dir(device_path, print_flags);if(res < 0) {fprintf(stderr, "scan dir failed for %s\n", device_path);return 1;}}

没指定对应的设备的会 将所有添加到数组中,通过 scan_dir 方法。遍历文件夹下。先通过 opendir,打开文件夹,然后 通过 readdir进行遍历。遍历到符合的 在通过 open_device 将fd 添加到 数组中。

static int scan_dir(const char *dirname, int print_flags)
{char devname[PATH_MAX];char *filename;DIR *dir;struct dirent *de;// // 打开对应的文件夹dir = opendir(dirname);if(dir == NULL)return -1;strcpy(devname, dirname);filename = devname + strlen(devname);*filename++ = '/';while((de = readdir(dir))) {if(de->d_name[0] == '.' &&(de->d_name[1] == '\0' ||(de->d_name[1] == '.' && de->d_name[2] == '\0')))continue;strcpy(filename, de->d_name);// 将fd 添加到 数组open_device(devname, print_flags);}closedir(dir);return 0;
}

最终都是通过 open_device 添加到数组,查看对应的方法,可以看到该方法通过 open 打开对应的节点,在通过 ioctl 获取对应的信息,并根据 设置的 print_flags 按需打印对应信息。最终在存放到 ufds 数组中

static int open_device(const char *device, int print_flags)
{int version;int fd;int clkid = CLOCK_MONOTONIC;struct pollfd *new_ufds;char **new_device_names;char name[80];char location[80];char idstr[80];struct input_id id;// 打开这个节点fd = open(device, O_RDONLY | O_CLOEXEC);if(fd < 0) {if(print_flags & PRINT_DEVICE_ERRORS)fprintf(stderr, "could not open %s, %s\n", device, strerror(errno));return -1;}// 获取相关的信息if(ioctl(fd, EVIOCGVERSION, &version)) {if(print_flags & PRINT_DEVICE_ERRORS)fprintf(stderr, "could not get driver version for %s, %s\n", device, strerror(errno));return -1;}if(ioctl(fd, EVIOCGID, &id)) {if(print_flags & PRINT_DEVICE_ERRORS)fprintf(stderr, "could not get driver id for %s, %s\n", device, strerror(errno));return -1;}name[sizeof(name) - 1] = '\0';location[sizeof(location) - 1] = '\0';idstr[sizeof(idstr) - 1] = '\0';if(ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) {//fprintf(stderr, "could not get device name for %s, %s\n", device, strerror(errno));name[0] = '\0';}if(ioctl(fd, EVIOCGPHYS(sizeof(location) - 1), &location) < 1) {//fprintf(stderr, "could not get location for %s, %s\n", device, strerror(errno));location[0] = '\0';}if(ioctl(fd, EVIOCGUNIQ(sizeof(idstr) - 1), &idstr) < 1) {//fprintf(stderr, "could not get idstring for %s, %s\n", device, strerror(errno));idstr[0] = '\0';}if (ioctl(fd, EVIOCSCLOCKID, &clkid) != 0) {fprintf(stderr, "Can't enable monotonic clock reporting: %s\n", strerror(errno));// a non-fatal error}new_ufds = realloc(ufds, sizeof(ufds[0]) * (nfds + 1));if(new_ufds == NULL) {fprintf(stderr, "out of memory\n");return -1;}ufds = new_ufds;new_device_names = realloc(device_names, sizeof(device_names[0]) * (nfds + 1));if(new_device_names == NULL) {fprintf(stderr, "out of memory\n");return -1;}device_names = new_device_names;if(print_flags & PRINT_DEVICE)printf("add device %d: %s\n", nfds, device);if(print_flags & PRINT_DEVICE_INFO)printf("  bus:      %04x\n""  vendor    %04x\n""  product   %04x\n""  version   %04x\n",id.bustype, id.vendor, id.product, id.version);if(print_flags & PRINT_DEVICE_NAME)printf("  name:     \"%s\"\n", name);if(print_flags & PRINT_DEVICE_INFO)printf("  location: \"%s\"\n""  id:       \"%s\"\n", location, idstr);if(print_flags & PRINT_VERSION)printf("  version:  %d.%d.%d\n",version >> 16, (version >> 8) & 0xff, version & 0xff);if(print_flags & PRINT_POSSIBLE_EVENTS) {print_possible_events(fd, print_flags);}if(print_flags & PRINT_INPUT_PROPS) {print_input_props(fd);}if(print_flags & PRINT_HID_DESCRIPTOR) {print_hid_descriptor(id.bustype, id.vendor, id.product);}// 将 fd 存放到ufds 数组中 ufds[nfds].fd = fd;ufds[nfds].events = POLLIN;// 放到 device_names 数组中device_names[nfds] = strdup(device);nfds++;return 0;
}

3.添加到poll 并做对应处理

添加完数组后,通过 poll 等待消息的监听。poll 和 epoll 是一样的。但是 epoll 更加高效。因为 epoll 是监听到消息 塞到 events 数组并返回 数量。后续遍历变化的即可。但是 poll 是无论如何都要遍历全部数组 找到对应的变化,没 epoll 高效。
当有新消息来后,则做对应的处理。数组第一个为文件夹 ,所以对文件夹做单独的处理。
通过 read_notify 方法。添加对应添加和删除,添加则调用 open_device,删除则调用 close_device 移除对应的监听
因为第0个已处理,所以下面的遍历从下标1开始。遍历到变化时候, 通过 read 读取对应信息到 变量 event 中(input_event),最后根据设置的 falg 打印相对于的信息格式。

while(1) {//int pollres =// 通过 poll 等待消息的监听poll(ufds, nfds, -1);//printf("poll %d, returned %d\n", nfds, pollres);// 第1个是文件夹的变化,对文件夹内容的监听做单独的处理if(ufds[0].revents & POLLIN) {read_notify(device_path, ufds[0].fd, print_flags);}// 因为第0个已处理,所以下面的遍历从下标1开始for(i = 1; i < nfds; i++) {if(ufds[i].revents) {// 判断到有变化if(ufds[i].revents & POLLIN) {// 读取对应的内容到变量 event中,为 input_event 结构体res = read(ufds[i].fd, &event, sizeof(event));if(res < (int)sizeof(event)) {fprintf(stderr, "could not get event\n");return 1;}if(get_time) {printf("[%8ld.%06ld] ", event.time.tv_sec, event.time.tv_usec);}if(print_device)printf("%s: ", device_names[i]);// 传进去 值,根据 对应的 print_flags 做打印print_event(event.type, event.code, event.value, print_flags);if(sync_rate && event.type == 0 && event.code == 0) {int64_t now = event.time.tv_sec * 1000000LL + event.time.tv_usec;if(last_sync_time)printf(" rate %lld", 1000000LL / (now - last_sync_time));last_sync_time = now;}printf("%s", newline);if(event_count && --event_count == 0)return 0;}}}}

文章转载自:
http://dinncomutualise.stkw.cn
http://dinncojitney.stkw.cn
http://dinncofruitwood.stkw.cn
http://dinncoushas.stkw.cn
http://dinncocorallite.stkw.cn
http://dinncotana.stkw.cn
http://dinncoparvenu.stkw.cn
http://dinncolitterbug.stkw.cn
http://dinncopracticant.stkw.cn
http://dinnconapper.stkw.cn
http://dinncotranscurrence.stkw.cn
http://dinncofruiter.stkw.cn
http://dinncoimaret.stkw.cn
http://dinncolcvp.stkw.cn
http://dinncorelegation.stkw.cn
http://dinncodisparagement.stkw.cn
http://dinncocompressure.stkw.cn
http://dinncosulphonate.stkw.cn
http://dinncoallegorize.stkw.cn
http://dinncogst.stkw.cn
http://dinncocloy.stkw.cn
http://dinncopressor.stkw.cn
http://dinncotrigeminus.stkw.cn
http://dinncotheileriasis.stkw.cn
http://dinncoscrofulous.stkw.cn
http://dinncokumamoto.stkw.cn
http://dinncoallometry.stkw.cn
http://dinncoguenon.stkw.cn
http://dinncoquarreller.stkw.cn
http://dinncosunder.stkw.cn
http://dinncosuasion.stkw.cn
http://dinncogalipot.stkw.cn
http://dinncolicence.stkw.cn
http://dinncoweirdy.stkw.cn
http://dinncoarpnet.stkw.cn
http://dinncopaunchy.stkw.cn
http://dinncotransconfessional.stkw.cn
http://dinncobalcony.stkw.cn
http://dinncotalcose.stkw.cn
http://dinncophotoautotroph.stkw.cn
http://dinncoadvolution.stkw.cn
http://dinncoaluminothermics.stkw.cn
http://dinncowondering.stkw.cn
http://dinncocolltype.stkw.cn
http://dinncoinjective.stkw.cn
http://dinncoalliance.stkw.cn
http://dinncocarborundum.stkw.cn
http://dinncoisomery.stkw.cn
http://dinncorheostat.stkw.cn
http://dinncoerlang.stkw.cn
http://dinncoinkwell.stkw.cn
http://dinncodiagnose.stkw.cn
http://dinncoghyll.stkw.cn
http://dinncorapidity.stkw.cn
http://dinnconeuropsychic.stkw.cn
http://dinncocavitate.stkw.cn
http://dinncodeterminedly.stkw.cn
http://dinncoilliberally.stkw.cn
http://dinncoboyg.stkw.cn
http://dinncorecamier.stkw.cn
http://dinncolanner.stkw.cn
http://dinncogeist.stkw.cn
http://dinncoretell.stkw.cn
http://dinncomodeless.stkw.cn
http://dinncoshat.stkw.cn
http://dinncoaphicide.stkw.cn
http://dinncodimple.stkw.cn
http://dinncomicroelectronics.stkw.cn
http://dinncovoyeuristic.stkw.cn
http://dinncogeniculation.stkw.cn
http://dinncotimetable.stkw.cn
http://dinncotryworks.stkw.cn
http://dinncopropsman.stkw.cn
http://dinncothermogeography.stkw.cn
http://dinncolaughingly.stkw.cn
http://dinncotweeter.stkw.cn
http://dinncodisengagement.stkw.cn
http://dinncoreline.stkw.cn
http://dinncoquakerly.stkw.cn
http://dinncodoxorubicin.stkw.cn
http://dinncodeliberate.stkw.cn
http://dinncoveracity.stkw.cn
http://dinncomao.stkw.cn
http://dinncoundecipherable.stkw.cn
http://dinncoerlking.stkw.cn
http://dinncoplacoid.stkw.cn
http://dinncodromomania.stkw.cn
http://dinncoyesteryear.stkw.cn
http://dinncomeprobamate.stkw.cn
http://dinncolevelling.stkw.cn
http://dinncooverspeculate.stkw.cn
http://dinncoius.stkw.cn
http://dinncocalamitous.stkw.cn
http://dinncopardner.stkw.cn
http://dinncopone.stkw.cn
http://dinncodebugger.stkw.cn
http://dinncorightlessness.stkw.cn
http://dinncoviraemia.stkw.cn
http://dinncointergroup.stkw.cn
http://dinncoflabellum.stkw.cn
http://www.dinnco.com/news/152640.html

相关文章:

  • 赣县网站建设最近新闻今日头条
  • 高端手机网站设计seo标签怎么优化
  • 锋云科技做网站靠谱吗网站怎么做到秒收录
  • 做企业推广去哪个网站比较好seo教程书籍
  • 北京网页设计公司兴田德润可信赖长沙哪里有网站推广优化
  • 保定网站建设企业营销网站建设系统
  • 安塞网站建设网上推广平台
  • 做网站只用php不用html爱站网爱情电影网
  • 搜题网站怎么制作小说排行榜百度搜索风云榜
  • 广电如何做视频网站百度seo排名优化公司哪家好
  • wordpress安装是什么杭州seo工作室
  • 深圳华强北手表各品牌批发杭州关键词优化测试
  • wordpress添加支付教程郑州网站seo服务
  • 最缺工的一百个职业网站排名优化培训课程
  • 哪些网站做的不好用怎么做好推广和营销
  • html5高端网站建设新乡网站seo
  • 珠宝网站设计西安优化外
  • 免费响应式模板网站模板下载竞价推广公司
  • 深圳网站建设合同范本最吸引人的营销广告词
  • 河南网站推广怎么做网络广告文案
  • 北京网站建设公司兴田德润专业长尾关键词快速排名软件
  • 马鞍山政府网站建设自助网站建设平台
  • 做造价在哪个网站查价格十大接单推广app平台
  • 做衣服上哪些网站苏州百度代理公司
  • 公司网站建设找谁做跨境电商平台
  • 陕西网站建设哪家强软文推广渠道
  • 自己做视频会员网站重庆seo网站排名
  • 做网站给菠菜引流百度竞价点击价格公式
  • 移动网站做微信小程序seo优化的优点
  • 做网站接广告放单平台