【问题标题】:writing to /dev/uinput (on ubuntu 12.04)写入 /dev/uinput(在 ubuntu 12.04 上)
【发布时间】:2020-02-06 17:37:21
【问题描述】:

我正在开发一个在 linux 上创建虚拟操纵杆的小程序,带有 python 前端。它是Linux-Virtual-Joystick 的一个分支。

我需要写入 dev/uinput 以创建用户定义的操纵杆。 该文件使用 O_RDWR 打开(我在调试时临时添加了其他文件的读/写访问权限)。当我这样做时

write(uifd, &uidev, sizeof(uinput_user_dev));

它返回 -1 并将 errno 设置为 22(EINVAL)。参数正确,文件已成功打开。

还有其他人遇到过这个问题吗?我将这个项目搁置了大约一个月,但我记得它在 Ubuntu 的最新版本中运行。

更新: uinput 适用于 ubuntu 12.10

【问题讨论】:

  • 你好,uinput模块加载了吗?
  • /dev/uinput 存在于我的系统中(Lubuntu 11.10),但我无法加载 uinput 模块
  • 呃……我该怎么做?模块,如在共享库中?
  • 在终端输入lsmod查看所有加载的模块(可加载内核模块)
  • modprobe uinput && lsmod | grep uinput 什么也没给出

标签: linux input ubuntu-12.04


【解决方案1】:

我认为您遇到的问题是对uinput 的访问权限。您收到的错误消息是典型的,我之前在其他设备上看到过相同的行为。

为了测试该假设,更改/dev/uinput 权限以允许访问所有人:

chmod +0666 /dev/uinput

然后重试您的代码。如果现在它工作正常,您将需要将该更改永久化,否则它将在重新启动后恢复为原始权限。

要以安全的方式执行此操作,请添加一个位于以下位置的规则文件:/etc/dev/rules.d

下面一行:

KERNEL=="uinput", GROUP="udev_group"

要查看规则文件的外观,请查看位于以下位置的 udev 规则文件:

/lib/udev/rules.d/50-udev-default.rules

准备就绪后,添加一个名为 udev_group 的组,并向其中添加您的用户名(或任何应该对uinput 具有写入权限的用户)。

您可能需要重新启动才能使新规则生效。

结果将是该组成员的任何用户都将拥有对uinput 的完全访问权限,这正是您想要的。


要添加组,您可以安装“用户和组”:

sudo apt-get install gnome-system-tools

并在以下位置启动它:

Application -> System Tools -> Administration -> Users and Groups**

或在终端中:

gnome-system-tools

【讨论】:

  • 感谢您的回复。问题是我以超级用户身份尝试了该程序,然后将 o+rw 添加到 /dev/uinput 以以普通用户身份运行它,并在 eclipse 中附加到 gdb。无论哪种方式,它都在同一点上失败了。我认为这不是权限问题。
  • 我们可以将 chmod 命令也添加到 rule.d 文件中吗?这是因为最终用户可能不知道为 /dev/uinput 设置所需的访问权限
  • 登录用户自动访问:添加文件/etc/udev/rules.d/50-uinput.rules,内容为:KERNEL=="uinput", TAG+="uaccess"
【解决方案2】:

由于缺少 uinput 模块,您应该考虑在继续之前构建它。

我从来没有这样重建过Linux内核模块,所以你可以按照here的解释

首先,您需要获取相应的 Linux 源代码和头文件。同时安装 module-init-tools
然后,将 dir 更改为 /usr/src/linux 并以 root 身份执行

cp /boot/config-* ./.config
make drivers/input/misc/uinput.ko

构建 uinput.ko 需要几分钟时间

在将 uinput.ko 移动到 /lib/modules//kernel/drivers/input/misc 之前检查它是否有效

insmod ./drivers/input/misc/uinput.ko

编辑 1:

似乎从 Linux 2.6.35-17.23 开始,uinput is a built-in module。这就是为什么it's not shown by lsmod

我刚刚看了你的代码,我认为问题出在这一行

if (write(uifd, &uidev, sizeof(uinput_user_dev) != sizeof(uinput_user_dev))) 

应该是

if (write(uifd, &uidev, sizeof(uinput_user_dev)) != sizeof(uinput_user_dev))

希望有帮助

【讨论】:

  • 这真的让事情变得更糟了。我希望创造一个开箱即用的小用玩具。
  • (应该是编辑)你确定没有 uinput 吗? lsmod 不显示 uinput,但 modprobe uinput 不返回任何内容,因此它存在,但处于非活动状态。我会尝试添加它 /etc/modules 看看重启后会发生什么。感谢您的回复
  • 嗯...不是现在。看起来 uinput 实际已加载:/ 我将编辑我的答案
【解决方案3】:

我在 Ubuntu 14.04 中也遇到了这个错误,来自你的 repo (https://github.com/ferry-/Linux-Virtual-Joystick-cpp)。我通过将 device.h 中设备构造函数中的 device::uidev 成员清零来修复它。

memset(&uidev, 0, sizeof(uidev));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-01
    • 2012-05-31
    • 2014-08-12
    • 2012-12-10
    • 2013-05-27
    • 2013-07-10
    相关资源
    最近更新 更多