3

我有一个在 Linux 上以 root 身份运行的程序,与一个 tty(实际上是一个作为 tty 实现的 LCD)交谈。值得的设备是/dev/ttyUSB0。我希望写入此设备的程序能够独占访问该设备,以免受到同时运行的其他程序实例的任何干扰。

我看到有一个名为 TIOCEXCL 的 ioctl 选项,它可以防止设备的附加打开,“除非发出 TIOCEXCL ioctl,否则对同一文件的多个 open() 调用将成功。这将阻止除 root 拥有的进程之外的其他打开。 " 我对此进行了测试,它的工作原理与宣传的一样:如果非 root 用户尝试打开 /dev/ttyUSB0 (一旦我更改了权限),则打开失败并显示“设备忙”之类的内容,并且如果 root 用户尝试打开它, 有用。

我理想中想要的是一种对 tty 的独占访问权,以便为 root 用户工作。因此,我将有多个 root 用户使用写入 LCD 的程序,但不知何故,他们对 LCD (tty) 的访问将被序列化。显然 TIOCEXCL ioctl 选项对我不起作用,因为它不会阻止 root 用户打开已经打开的 tty 设备。

我想这里有很多选择,但我正在与大家联系,看看您是否有其他想法或建议。

  1. 也许我错过了使用 TIOCEXCL 的一些东西......

  2. 也许还有其他方法可以通过 open() 或 ioctl() 或其他方式获得独占访问。

  3. 如果有某种方法可以检测到其他进程打开了设备,我可以等待并重试。我知道 lsof 但我不愿意从这个程序内部调用它只是为了了解这一点。并且有竞争条件。(也许我可以克服它?:))

  4. 我可以像以前那样实现锁定,以获得对 tty 设备的独占访问权限。

更新1:

由于写入 LCD 设备的唯一程序是我的,因此我倾向于执行以下操作(伪代码)来锁定代码内部:

f = open("/dev/ttyUSB0", O_RDWR)
flock(f, LOCK_EX)

// do any ioctl's, etc.

// do any write's

// sleep a tad to not flash messages too fast on LCD
nanosleep({0, 250000000}, NULL)

flock(f, LOCK_UN)
close(f)
4

5 回答 5

7

或许这篇关于LKML的讨论:【TTY】独占模式问题对你有帮助!

于 2009-03-27T23:03:57.910 回答
1

我有一些像你这样的问题。如果你可以破解你的 linux 内核,你可以像这样进行肮脏的破解。在文件中

linux/drivers/char/tty_io.c

添加新命令到函数

long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
    ...
    switch (cmd) {
    ...
    case 0x54FF:
        return put_user(tty->count, (int __user *)p);
    ...
}

的值tty->count是当前打开的描述符的计数。

在您的应用程序中,您可以尝试此代码

int fd, count, res;
fd = open("/dev/ttyS0", O_RDWR|O_NOCTTY|O_NONBLOCK);
if (fd >= 0)
{
    count = 0;
    res = ioctl(fd, 0x54FF, &count);
    if (res>=0)
    {
        if (count > 1)
        {
            printf("Device already in use.\n")
            close(fd);
            fd = -1;
        }
    }
}
于 2014-12-02T10:41:17.613 回答
0

答: Root 始终具有访问权限。总是。

也许如果您更多地说明还有什么正在抓取设备,或者您担心什么可能会抓取设备......

于 2009-03-27T23:42:22.297 回答
0

我鼓励您研究 UUCP 锁定。Linux 上应该有一个实现它的库,但如果没有,它很容易实现。我已经在类似的情况下广泛使用它,我不希望同一程序的多个实例相互踩踏。

作为旁注,也许您应该重新考虑解决方案的架构。访问 LCD/ttyUSB0 的进程可以充当服务器并处理来自需要写入 LCD 的客户端进程的消息。这将需要某种形式的 IPC。对于您的项目来说,这可能是矫枉过正。

请记住,您提出的任何解决方案只有在访问设备的所有进程都符合协议时才有效。如果您担心以 root 身份运行的恶意进程,那么您可能会陷入破解内核以获得所需解决方案的困境。

于 2009-08-11T18:12:10.650 回答
0

我不知道你是否已经找到了解决方案,或者你只是改变了你的设计,但这里有一个“根域”的解决方法:

  1. 在您的系统中创建另一个与您的端口名称相同的文件,或者包括类似ttyUSB0_islocked.
  2. 当您打开端口时,让您的进程查找/创建并打开此文件并在其中写入一些信息,例如它的进程 ID。
  3. 在其他程序中打开端口之前,请检查该文件是否存在以及文件中是否存在具有相同进程 ID 的进程,如果没有此类进程,则继续执行,否则请等待或退出。
于 2014-10-21T21:04:22.820 回答