文件和目录之设备特殊文件

st_dev和st_rdev:

  • 每个文件系统所在的存储设备都由主、次设备号表示。设备号所用的数据类型是基本系统数据类型dev_t。主设备号标识设备驱动程序,有时编码为与其通信的外设板;次设备号标识特定的子设备。例如,磁盘驱动器经常包含若干个文件系统。在同一磁盘驱动器上的各文件系统通常具有相同的主设备号,但它们的次设备号却不同。
  • 我们通常可以使用两个宏,即major和minor来访问主、次设备号,大多数实现都定义了这两个宏。这就意味着我们无需关心这两个数是如何存放在dev_t对象中的。

Linux将宏major和minor定义在头文件<sys/sysmacros.h>中,而该头文件又包括在<sys/type.h>中。

  • 系统中与每个文件名关联st_dev值是文件系统的设备号,该文件系统包含了这一个文件名以及与其对应的i节点。
  • 只有字符特殊文件和块特殊文件才有st_rdev值。此值包含实际设备的设备号。

The  st_dev  field  describes  the device on which this file resides.

The st_rdev field describes the device that this file (inode) represents.

st_rdev是和inode有关的。 参考自:http://my.oschina.net/xiangxw/blog/10125

实例

程序清单4-10中的程序为每个命令行参数打印设备号,另外,若此参数引用的是字符特殊文件或块特殊文件,则还会打印该特殊文件的st_rdev值。

程序清单4-10 打印st_dev和st_rdev值

[root@localhost apue]# cat prog4-10.c
#include "apue.h"
//#ifndef SOLARIS
//#include <sys/mkdev.h>
//#endif
#include <sys/sysmacros.h>

int 
main(int argc, char *argv[])
{
        int         i;
        struct stat buf;

        for(i=1; i<argc; i++)
        {
                printf("%s: ", argv[i]);
                if(stat(argv[i], &buf) < 0)
                {
                        err_ret("stat error");
                        continue;
                }
                printf("dev = %d/%d", major(buf.st_dev), minor(buf.st_dev));
                if(S_ISCHR(buf.st_mode) || S_ISBLK(buf.st_mode))
                {
                        printf(" (%s) rdev = %d/%d", 
                                (S_ISCHR(buf.st_mode)) ? "character" : "block",
                                major(buf.st_rdev), minor(buf.st_rdev));
                }
                printf("\n");
        }
        exit(0);
}

运行结果:

[root@localhost apue]# ./prog4-10 / /home/zhu /dev/tty[01]
/: dev = 8/2
/home/zhu: dev = 8/3
/dev/tty0: dev = 0/16 (character) rdev = 4/0
/dev/tty1: dev = 0/16 (character) rdev = 4/1
[root@localhost apue]# mount
/dev/sda2 on / type ext3 (rw)
/dev/sda3 on /home type ext3 (rw)
[root@localhost apue]# ls -lL /dev/tty[01] /dev/sda[23]
brw-r----- 1 root disk 8, 2 Jan  3 17:07 /dev/sda2
brw-r----- 1 root disk 8, 3 Jan  3 17:07 /dev/sda3
crw-rw---- 1 root root 4, 0 Jan  3 17:06 /dev/tty0
crw------- 1 root root 4, 1 Jan  3 16:39 /dev/tty1

传递给该程序的前两个参数是目录(/和/home/zhu),后两个是设备名/dev/tty[01]。(这里使用了正则表达式以缩短设备名,shell将扩展该字符串/dev/tty[01]为/dev/tty0 /dev/tty1.)

这两个设备是字符 特殊设备。从程序的输出可见,根目录和/home/zhu目录的设备号不同,这表示它们位于不同的文件系统中。运行mount(1)命令证明了这一点。

然后用ls命令查看由mount命令报告的两个磁盘设备和两个终端设备。这两个磁盘设备是块特殊文件,而两个终端设备则是字符特殊文件。(通常,只有块特殊文件类型的设备才能包含随机访问的文件系统,它们是:硬盘驱动器、软盘驱动器和CD-ROM等。)

注意,两个终端设备(st_dev)的文件名和i节点在设备0/16上(devfs伪文件系统,它实现了/dev文件系统),但是它们的实际设备号是4/0和4/1。

 

本篇博文内容摘自《UNIX环境高级编程》(第二版),仅作个人学习记录所用。关于本书可参考:http://www.apuebook.com/

posted @ 2014-01-04 17:31  ITtecman  阅读(1362)  评论(0编辑  收藏  举报