st_dev和st_rdev这两个字段经常引起混淆,在18.9节,我们编写ttyname函数时,需要使用这两个字段。有关规则很简单:
- 每个文件系统所在的存储设备都由其主、次设备号表示。设备号所用的数据类型是基本系统数据类型dev_t。主设备号表示设备驱动程序,有时编码为与其通信的外设板;次设备号标识特定的子设备。回忆图4-13,一个磁盘驱动器经常包含若干个文件系统。在同一磁盘驱动器上的各文件系统通常具有相同的主设备号,但是次设备号却不同。
- 我们通常可以使用两个宏:major和minor来访问主、次设备号,大多数实现都定义这两个宏。这就意味着我们无需关心这两个数是如何存放在dev_t对象中的。
- 系统中与每个文件名关联的st_dev值是文件系统的设备号,该文件系统包含了这一文件名以及与其对应的i节点。
- 只有字符特殊文件和块特殊文件才有st_rdev值。此值包含实际设备的设备号。
我们期望设备是字符特殊文件。从程序的输出可见,根目录和/home/sar目录的设备号不同,这表示他们位于不同的文件系统中。运行mount(l)命令可以证明了这一点。
然后用ls命令查看由mount命令报告的两个磁盘设备和两个终端设备。这两个磁盘设备是块特殊文件,而两个终端设备是字符特殊文件。(通常,只有那些包含随机访问文件系统的设备类型是块特殊文件设备,如硬盘驱动器、软盘驱动器和CD-ROM等。UNIX的早期版本支持磁带存放文件系统,但这从未广泛使用过。)
注意,两个终端设备(st_dev)的文件名和i节点在设备0/5上(devtmpfs伪文件系统,它实现了/dev文件系统),但是它们的实际设备号是4/0和4/1。