我有一个在Linux上以root身份运行的程序,与一个tty(实际上是一个tty实现的LCD)交谈。 该设备的价值是/ dev / ttyUSB0。 我想让我的程序写入这个设备能够独占访问设备,以免同时运行的程序的其他实例的任何干扰。
我发现有一个名为TIOCEXCL的ioctl选项,它将阻止设备的额外打开,除非TIOCEXCL ioctl被发出,否则对同一个文件的多个open()调用将会成功。 “ 我testing了这一点,它的工作原理和广告一样:如果一个非root用户试图打开/ dev / ttyUSB0(一旦我改变了权限),那么打开失败,像“设备繁忙”,如果一个root用户试图打开它, 有用。
我最想要的是通过这种独占方式访问tty,以便为root用户工作。 所以我会有多个root用户使用写入LCD的程序,但是他们对LCD(tty)的访问将被序列化。 显然,TIOCEXCL ioctl选项不适用于我,因为它不会阻止root用户打开已经打开的tty设备。
我想这里有很多select,但是我想深入了解你们是否有其他想法或build议。
也许我错过了使用TIOCEXCL的一些东西…
也许有一些其他方式通过开放()或ioctl()或什么 – 不是获得独占访问。
如果有某种方法可以检测到某个其他进程已打开设备,则可以等待并重试。 我知道lsof,但是我不愿意从这个程序中调用它来学习。 而且还有与此相关的竞争条件。 (也许我可以克服?:))
我可以实现锁,就像显然习惯于获得对tty设备的独占访问一样。
更新1:
由于唯一的程序写入液晶显示设备是我的,我倾向于做类似于以下(伪代码)来locking代码:
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)
也许这个关于LKML的讨论:[TTY]独家模式的问题可以帮助你!
答:Root始终有权访问。 总是。
也许如果你更多地谈论了还有什么东西是抓住这个设备,或者你担心什么可能抓住设备…
我鼓励你看看UUCP锁定。 Linux上应该有一个库来实现它,但是如果没有的话,实现起来相当容易。 我已经在类似的情况下广泛地使用了它,我不希望同一个程序的多个实例互相踩在一起。
作为一个方面说明,也许你应该重新考虑你的解决方案的架构。 访问LCD / ttyUSB0的过程可以充当服务器,并处理需要写入LCD的客户端进程的消息。 这将需要某种形式的IPC。 这可能是你的项目过度
请记住,只有在访问设备的所有进程符合协议的情况下,您所提出的任何解决方案才会起作用。 如果您担心以root身份运行的恶意进程,那么您可能会被黑客攻击内核以获得所需的解决方案。
我不知道你是否已经找到了一个解决方案,或者你只是改变了你的设计,但是这里有一个“根源地”的解决方案:
ttyUSB0_islocked
这样的ttyUSB0_islocked
。 我有像你这样的问题。 如果你可以破解你的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; } } }