专栏首页科技分享Linux下对input设备调用ioctl时指定EVIOCGBIT选项时的缓冲区该多大【转】

Linux下对input设备调用ioctl时指定EVIOCGBIT选项时的缓冲区该多大【转】

转自:https://blog.csdn.net/imred/article/details/82669990

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/imred/article/details/82669990 我们有时候需要获取/dev/input目录下的eventX设备支持哪些事件(EV_KEY、EV_REL和EV_ABS等),可以通过ioctl调用指定EVIOCGBIT(ev, len)选项来获取,例如:

ioctl(fd, EVIOCGBIT(0, EV_MAX), buf); 1 来获取fd设备支持的事件。这涉及到一个问题:buf需要指定多大的长度? EVIOCGBIT宏的第二个参数是事件标志位最高位可能有多高,例如当前4.16内核版本中该值为0x1f,说明缓冲区最高第0x1f位可能会被置位。因此之前缓冲区是这样指定的:

uint8_t buf[EV_MAX / 8 + 1]; 1 这样的话理论上可以容纳下所有标志位。但是实际执行时(64位机器上)会有栈溢出问题:

$ sudo ./eviocgbit /dev/input/event4 Supported event types: Event type 0x00 (Synch Events) Event type 0x01 (Keys or Buttons) *** stack smashing detected ***: <unknown> terminated Aborted 1 2 3 4 5 6 为什么会这样呢,跟了一下内核代码,发现在计算需要往用户空间拷贝多少字节的数据是在这个函数中计算的:

static int bits_to_user(unsigned long *bits, unsigned int maxbit, unsigned int maxlen, void __user *p, int compat) { int len = BITS_TO_LONGS(maxbit) * sizeof(long);

if (len > maxlen) len = maxlen;

return copy_to_user(p, bits, len) ? -EFAULT : len; } 1 2 3 4 5 6 7 8 9 10 其中的maxbit在本例中即为我们指定的EV_MAX,这个函数首先使用BITS_TO_LONGS宏计算出需要几个long型数据能够放下这么多位的数据,然后乘以long的大小,得到缓冲区的大小。虽然下面有使用maxlen限制缓冲区大小,但是maxlen也被指定为了EV_MAX,所以并没有效果。 如上所述,我们在申请缓冲区时也要像内核代码一样以long型数据大小为最小单位,申请n个long型数据大小的缓冲区就没有问题了:

uint8_t evtype_b[(EV_MAX / (sizeof(long) * 8) + 1) * sizeof(long)]; ———————————————— 版权声明:本文为CSDN博主「imred」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/imred/article/details/82669990

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • linux下c语言实现多线程文件复制

    int open(char *filename, int access);

    用户3033338
  • 多线程内存问题分析之mprotect方法【转】

    转自:https://blog.csdn.net/agwtpcbox/article/details/53230664

    用户3033338
  • linux内核中的宏ffs(x)

    __t & -__t 等于找到__t 第一个为1的位(从低位开始),并把该位保留为1其余位清0.

    用户3033338
  • 基础知识 | 每日一练(179)

    士人有百折不回之真心,才有万变不穷之妙用。立业建功,事事要从实地着脚,若少慕声闻,便成伪果;讲道修德,念念要从虚处立基,若稍计功效,便落尘情。 ...

    闫小林
  • C++上机考试试题解析

    慕白
  • 剑指offer——机器人的运动范围

    题目描述 地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和...

    AI那点小事
  • 算法细节系列(19):广度搜索优先

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.n...

    用户1147447
  • HDU 6629 (2019杭电第五场 1006) string matching (扩展kmp)

    题意: 求字符串 s[i…len−1] and s[0…len−1] i>0 最长公共前缀长度求解过程的比较次数

    用户2965768
  • Contest 176 - LeetCode 1352. Product of the Last K Numbers

    题解:由于数字可能为0,所以我们只要维护最后一个0 的位置pos 之后的所有数字的前缀乘积就可以了。如果k<pos 答案显然为0,如果k>pos那么答案就是s[...

    ShenduCC
  • C# 扩展方法 白话总结

    我们在变成的时候时常遇到这样的问题,new了一个系统内的对象之后,我们想要对该对象有一个方法可是却点不出来,说明该对象本身没有声明该方法,可是微软又不允许我们去...

    码农阿宇

扫码关注云+社区

领取腾讯云代金券