下一篇 上一篇 目录

13. 阻止他人使用

13.1 简介

当您使用串口时,您可能希望阻止其他人在同一时间使用它。然而,在某些情况下,您可能希望其他人使用它,例如,如果您正在使用文本终端,他们可以向您发送重要消息。

有多种方法可以防止其他人(或其他进程)在您使用串口时使用它(锁定)。这应该会自动发生,但如果它给您带来麻烦,了解这一点很重要。如果程序异常退出或 PC 突然关闭(例如,拔掉电源插头),您的串口可能会被锁定。即使锁定仍然存在,当您想再次使用串口时,通常会自动移除锁定。但在极少数情况下,它不会被移除。这时您就需要了解发生了什么。

一种实现锁定的方法是设计内核来处理它,但到目前为止,Linux 避开了这种解决方案(除了涉及 cua 设备的情况,该设备现在已过时)。Linux 使用的两种解决方案是:

  1. 创建锁定文件
  2. 修改设备(例如 /dev/ttyS2)的权限和/或所有者

13.2 锁定文件

如果您使用新的设备文件系统 (devfs),请参阅下一节。锁定文件只是一个被创建的文件,用来表示某个特定设备正在使用中。它们保存在 /var/lock 中。以前它们在 /usr/spool/uucp 中。Linux 锁定文件通常命名为 LCK..name,其中 name 可以是设备名称、进程 ID 号、设备的主次设备号或 UUCP 站点名称。大多数进程(getty 是一个例外)创建这些锁,以便它们可以独占访问设备。例如,如果您拨号连接到调制解调器,将会出现一些锁定文件,以告知其他进程有人正在使用该调制解调器。在较旧的版本(1990 年代)中,每个进程通常只有一个锁定文件。锁定文件包含锁定设备的进程的 PID。请注意,如果一个进程坚持使用已被锁定的设备,它可以忽略锁定文件并仍然使用该设备。这在向文本终端发送消息等情况下很有用。

当程序想要使用串口但发现它被锁定文件锁定时,它应该检查锁定文件的 PID 是否仍在被使用。如果不是,则意味着锁定已过时,可以继续使用端口(在删除过时的锁定文件之后)。不幸的是,可能有一些程序没有这样做,而是放弃并告诉您设备已被使用,但实际上并非如此。

如果锁定文件仅使用设备名称,则可能会出现以下问题:如果同一设备有两个不同的名称,则两个不同的进程可能各自使用同一设备的不同名称。这会导致具有不同名称但实际上是同一设备的锁定文件。以前,每个物理串口都以两个不同的设备名称而闻名:ttyS0 和 cua0。为了解决这个锁定文件别名问题,已经使用了 3 种方法。这可能有些过度,因为其中任何一种方法都可以解决问题。

  1. 锁定检查软件被告知 ttyS 与 cua 的区别。
  2. cua 设备已被弃用
  3. 创建了使用唯一设备号而不是名称的附加锁。

如果一个程序打开 /dev/ttyS2,而另一个程序打开 /dev/modem,则使用备用名称(例如 /dev/modem 代替 /dev/ttyS2)可能会导致问题。据说这个问题在 2000 年左右已修复,但在 2005 年仍然存在。对于哑终端,不使用锁定文件,因为这将不允许其他人使用 write 或 talk 程序向您的终端发送消息。

13.3 更改设备文件的所有者、组和/或权限

为了使用设备,您(或者如果您设置了“set user id”,则您运行的程序)需要具有读取和写入 /dev 目录中设备“文件”的权限。因此,阻止其他人使用设备的逻辑方法是将自己设置为设备的临时所有者,并设置权限,以便其他人都不能使用它。程序可能会为您执行此操作。类似的方法可以用于设备文件的组。

虽然锁定文件阻止其他进程使用设备,但更改设备文件所有者/权限会限制其他用户(或组)使用它。一种情况是允许组写入端口,但不允许从端口读取。写入端口可能只是意味着向文本终端发送消息,而读取意味着破坏性读取。如果另一个进程已经读取了数据,则需要读取数据的原始进程可能会发现数据丢失。因此,读取可能比写入造成更大的危害,因为读取会导致数据丢失,而写入只会添加额外的数据。这就是允许写入但不允许读取的原因。这与普通文件的情况正好相反,在普通文件中,您允许其他人读取文件,但不允许写入(修改)文件。端口的使用通常需要读取和写入权限。

更改设备文件属性的程序应在退出时撤消这些更改。但是,如果退出异常,则设备文件可能会处于某种状态,当再次尝试使用它时,会给出“权限被拒绝”的错误。


下一篇 上一篇 目录