插入与设备不一致

发布于 2025-01-22 03:51:12 字数 2020 浏览 3 评论 0原文

在Linux上,我试图检测一个连接的蓝牙控制器并开始从中读取。我知道有SDL可以做到这一点,但是我只是想学习如何专门在Linux上进行操作。因此,我正在使用Inotify API等待文件/dev/input/js0显示。但是,当我检测到文件时,我无法打开它。我有以下C ++代码:

#include <iostream>
#include <fstream>
#include <sys/inotify.h>
#include <unistd.h>
#include <linux/joystick.h>
#include <string.h>

constexpr int NAME_MAX = 16;

int main(int argc, char **argv) {

    std::string path = std::string(argv[1]);
    std::string directory = path.substr(0, path.find_last_of("/"));
    std::string file = path.substr(path.find_last_of("/") + 1);
    std::cout << "Directory is " << directory << ", file is " << file  << std::endl;

    int fd = inotify_init();

    if (inotify_add_watch(fd, directory.c_str(), IN_CREATE) < 0) {
        std::cout << "Could not watch: " << file << std::endl;
        return -1;
    }
    else
        std::cout << "Watching: " << file << std::endl;

    char buffer[sizeof(struct inotify_event) + NAME_MAX + 1];

    while (true) {

        if (read(fd, buffer, sizeof(buffer)) < 0) {
            std::cout << "Error reading event" << std::endl;
            break;
        }
        struct inotify_event &event = (struct inotify_event &) buffer;

        std::cout << event.name << std::endl;

        if ((strcmp(event.name, file.c_str()) == 0) && (event.mask & IN_CREATE)) {
            std::cout << "File has been created" << std::endl;
            close(fd);
            break;
        }
    }
    std::fstream file_stream(file, std::fstream::in);
    std::cout << file_stream.is_open() << std::endl;
}

如果我运行它以检测常规文件,则可以正常工作,它会等待文件创建事件,并且在尝试使用std :: fstreamis_open 返回true。但是,如果我运行它以检测/dev/input/js0,即使事件到来并且检测到文件,则打开FSTREAM不起作用,因为is_open返回false False 。 inotify适合检测设备文件吗?如果没有,这样做的正确方法是什么?

On Linux, I am trying to detect a bluetooth controller being connected and start reading from it. I know there's SDL to do that, but I just wanted to learn how to do it specifically on Linux. So I'm using the inotify api to wait for the file /dev/input/js0 to show up. But when I detect the file I cannot open it. I have the following c++ code:

#include <iostream>
#include <fstream>
#include <sys/inotify.h>
#include <unistd.h>
#include <linux/joystick.h>
#include <string.h>

constexpr int NAME_MAX = 16;

int main(int argc, char **argv) {

    std::string path = std::string(argv[1]);
    std::string directory = path.substr(0, path.find_last_of("/"));
    std::string file = path.substr(path.find_last_of("/") + 1);
    std::cout << "Directory is " << directory << ", file is " << file  << std::endl;

    int fd = inotify_init();

    if (inotify_add_watch(fd, directory.c_str(), IN_CREATE) < 0) {
        std::cout << "Could not watch: " << file << std::endl;
        return -1;
    }
    else
        std::cout << "Watching: " << file << std::endl;

    char buffer[sizeof(struct inotify_event) + NAME_MAX + 1];

    while (true) {

        if (read(fd, buffer, sizeof(buffer)) < 0) {
            std::cout << "Error reading event" << std::endl;
            break;
        }
        struct inotify_event &event = (struct inotify_event &) buffer;

        std::cout << event.name << std::endl;

        if ((strcmp(event.name, file.c_str()) == 0) && (event.mask & IN_CREATE)) {
            std::cout << "File has been created" << std::endl;
            close(fd);
            break;
        }
    }
    std::fstream file_stream(file, std::fstream::in);
    std::cout << file_stream.is_open() << std::endl;
}

If I run it to detect a regular file, it works, it waits for the file creation event, and when trying to open it with a std::fstream, is_open returns true. But if I run it to detect /dev/input/js0, even when the event comes and the file is detected, opening the fstream does not work, as is_open returns false. Is inotify appropriate to detect device files? If not, what would be the right way to do so?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

酷到爆炸 2025-01-29 03:51:12

根据 inotify(7)

iNotify仅报告用户空间程序触发的事件
通过文件系统API。结果,它不会抓住
网络文件系统上发生的远程事件。 (应用程序
必须回到轮询文件系统以捕获此类事件的情况下。)
此外,各种伪文件系统,例如 /proc, /sys和
/dev/pts无法使用inotify监控。

我要说的是/dev/input/也落入此存储桶中。

我想知道 udev>使用UDEVINFO -A -P/DEV/INPUT/JS0的设备,但也请查看使用udevadm Monitor -eenvironment -eNvironment -eudev使用哪些事件连接到外围的事件。

编辑:如果您成功获得了一个iNotify事件,但无法读取文件:

  • 当BT设备已经连接时,是否尝试使用另一个更简单的程序读取文件?
  • fstream :: Openopen&lt; cstdio&gt;之间有区别吗?
  • 您是否检查了设备上的权限?另外,CAT/DEV/INPUT/JS0产生什么?

According to inotify(7)

Inotify reports only events that a user-space program triggers
through the filesystem API. As a result, it does not catch
remote events that occur on network filesystems. (Applications
must fall back to polling the filesystem to catch such events.)
Furthermore, various pseudo-filesystems such as /proc, /sys, and
/dev/pts are not monitorable with inotify.

I would say that /dev/input/ also falls into this bucket.

I wonder if udev could be used: you should get info about the device using udevinfo -a -p /dev/input/js0, but also see what events connecting the peripheral generates using udevadm monitor --environment --udev.

Edit: if you successfuly get an inotify event but can't read the file:

  • Did you try reading the file with another simpler program when the BT device is already connected?
  • Is there a difference between fstream::open and open from <cstdio>?
  • Have you checked the permissions on the device? Also what does cat /dev/input/js0 produces?
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文