如何在Mac插件中使用ioctl()设置RTS?

Aly*_*hak 16 c++ macos plugins ioctl serial-port

我可以在一个小型终端应用程序中使用ioctl设置RTS,但不能在我的Mac插件代码中设置,尽管两者都运行相同的代码.在插件中,我只能"获取"串口标志/引脚,但不能"设置"它们.在终端应用程序中,我可以"获取并"设置"它们.我得到了ENODEV的错误.错误号码是19,消息是"设备不支持操作".

如果这是一个安全问题(在浏览器的上下文中)有没有办法获得使用ioctl修改标志的权限?我有一个连接到usb端口的串行设备.我使用FTDI vcp(虚拟COM端口)驱动程序.Windows端的一切都很流畅.顺便说一句,我使用Safari和Firefox获得相同的结果.以下是我的代码:

int disableRTS ()
{
    char fd, ret, flags;

    // open device
    if ((fd = open("/dev/cu.mydevice", O_RDWR | O_NDELAY)) < 0)
    {
        fprintf(stderr, "failed to open device");
        return -1;
    }

    // Get the current state of the bits
    ioctl(fd, TIOCMGET, &flags);
    fprintf(stderr, "Flags are %x.\n", flags);    

    flags &= ~TIOCM_RTS;  // Disable the RTS bit
    ret = ioctl(fd, TIOCMSET, &flags);

    if (ret == -1)
        fprintf(stderr, "TIOCMSET failed\n");
    else
        fprintf(stderr, "TIOCMSET succeeded. flags: %x.\n", flags);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

=========

更新

如果我刷新浏览器页面,强制再次执行代码,ioctl()返回0,表示成功.不幸的是,我需要它第一次工作.即使我写一个循环并暂时暂停,使用usleep()方法,并进行后续尝试,它也会失败.但是,当我刷新它成功.我还在Mozilla提供的第二个专门的NPAPI项目"BasicPlugin.xcodeproj"中重复了这个问题.我的第一个插件项目是Firebreath项目.它们最初都失败了,然后在页面重新加载时成功.我还有2个单独的Mac应用程序正常工作.一个是SerialTools,它使用完全相同的方法设置RTS(和DTR关闭)作为我的终端应用程序和插件.

========

更新2

我已经能够获得代码级别的Apple支持,因此可能会出现解决方案.这位工程师表示,代码在插件中的运行方式不同于一个插件,并且正在与Safari插件工程师交谈,这是"奇怪的".

Aly*_*hak 1

答案是,每当调用 ioctl() 时使用 TIOCMSET 或 TIOCMGET 时,第三个参数必须是 int。我用的是字符。呃。不敢相信我错过了这个。TIOCMSET 和 TIOCMGET 定义如下:

\n\n
  #define   TIOCMSET    _IOW(\'t\', 109, int) /* set all modem bits */\n  \xe2\x80\xa6\n  #define   TIOCMGET    _IOR(\'t\', 106, int) /* get all modem bits */\n
Run Code Online (Sandbox Code Playgroud)\n\n

因此不难想象,使用 char 作为我的“flags”var 的类型可能会导致不可预测的行为。

\n