Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4233083
  • 博文数量: 176
  • 博客积分: 10059
  • 博客等级: 上将
  • 技术积分: 4681
  • 用 户 组: 普通用户
  • 注册时间: 2006-03-24 12:27
文章分类

全部博文(176)

文章存档

2012年(1)

2011年(4)

2010年(14)

2009年(71)

2008年(103)

分类: C/C++

2008-10-04 23:52:42

stat,fstat以及lstat函数

  本章的讨论的中心是三个stat函数以及它们所返回的信息。
  
        #include
        int stat(const char*pathname,struct stat*buf);
        int fstat(int filedes,struct stat*buf);
        int lstat(const char *pathname,struct stat*buf);

  三个函数的返回:若成功为0,出错为-1

  给予一个pathname,stat函数返回一个与此命名文件有关的信息结构,fstat函数获得已在描述符filedes上打开的文件的有关信息。 lstat函数类似于stat,但是当命名的文件是一个符号连接时,lstat返回该符号连接的有关信息,而不是由该符号连接引用的文件的信息。(在 4.2)节中当降序周游目录层次结构时,我们需要lstat。在4.16节中的较详细地说明符号连接。)

  lstat函数不属于POSIX10031-1990标准,但很可能加到10031a中。SVR4和4.3+BSD支持lstat。

  第二个参数是个指针,它指向一个我们应提供的结构。这些函数填写由buf指向的结构。该结构的实际定义可能所实施而有所不同,但其基本形式是:

      struct stat{
        mode st_mode; /*文件类型和方式(许可数)*/
        ino st_ino;/* i-节点号(序列号)*/
        dev st_dev;/*设备号(文件系统)*/
        dev st_rdev;/*特殊文件的设备号*/
        nlink st_nlink;/*连接数*/
        uid st_uid;/*属主的用户ID*/
        gid st_gid;/*属主的组ID*/
        off st_size;/*普通文件的字节长度*/
        time st_atime;/*最后存取时间*/
        time st_mtime;/*最后修改存取时间*/
        time st_ctime;/*最后文件状态更改时间*/
        long st_blksize;/*最佳I/O块长*/
        long st_blocks;/*分配的512字节块块数
        };

  POSIX.1未定义stdevstksige和stblocks字段。SVR4和4.3+BSD则定义了这些字段。注意,除最后两个以外,其它各成员都? 为基本系统数据类型(见2.7节)。我们将说明此结构的每个成员以了解文件属性。

  stat函数的最大用户很可能是ls-l命令,用其可以获得有关一个文件的所有信息。

4.3文件类型

  至今我们已介绍了两种不同的文件类型-普通文件和目录。Unix系统的大多数文件是普通文件或目录,但是也有另外一些文件类型:

  1.普通文件(Regular file)。这是最常见的文件类型,这种文件包含了某种形式的数据。至于这种数据是文本还是二进制数据对于系统核而言并无区别。对普通文件内容的解释由处理该文件的应用程序进行。

  2.目录文件(Directory file)。这种文件包含了其它文件的名字以及指向与这些文件有关信息的指针。对一个目录文件具有读许可数的任一进程都可以读该目录的内容,但只有系统核可以写目录文件。

  3.字符特殊文件(Charocter special file)。这种文件用于系统中的某些类型的设备。

  4.块特殊文件(Block special file)。这种文件典型地用于磁盘设备。系统中的所有设备或者是字符特殊文件,或者是块特殊文件。

  5.FIFO。这种文件用于进程间的通信,有时也将其称为命名管道。在14.5对其进行说明。

  6.套接口(socket)。这种文件用于进程间的网络通信。套接口也可用于在一台宿主机上的进程之间的非网络通信。在第十五章,我们将用套接口进行进程间的通信。只有4.3+BSD才返回套接口文件类型,虽然 SVR4支持用套接口进行进程间通信,但现在是经由套接口函数库实现的,而不是通过系统核内的套接口文件类型,将来的SVR4版本可能会支持套接口文件类型。

  7.符号连接(Symboliclink)。这种文件指向另一个文件。我们在4.16中将更多地述及符号连接。

  文件类型信息,包含在stat结构的stode成员中。我们可以用图4.1中的宏确室文件类型。这些宏的参数都是stat结构中的stode成员。
  图4.1在中的文件类型宏

实例

#include
#include
#include

int main( int argc, char *argv[] )
{
    int             i;
    struct stat buf;
    char             *msg;
    
    for ( i=1; i    {
        printf( "%s:    ", argv[i] );
        if ( lstat(argv[i], &buf) < 0 )
        {
            printf("** lstat error...\n");
            continue;
        }
   
        if ( S_ISREG(buf.st_mode) )
        {
            msg = "regular";
        }
        else if ( S_ISDIR(buf.st_mode) )
        {
            msg = "directory";
        }
        else if ( S_ISCHR(buf.st_mode) )
        {
            msg = "character special";
        }
        else if ( S_ISBLK(buf.st_mode) )
        {
            msg = "block special";
        }
        else if ( S_ISFIFO(buf.st_mode) )
        {
            msg = "fifo";
        }
        else if ( S_ISLNK(buf.st_mode) )
        {
            msg = "symbolic link";
        }
        else if ( S_ISSOCK(buf.st_mode) )
        {
            msg = "socket";
        }
        else
        {
            msg = " ** unknown mode";
        }
       
        printf( "%s\n", msg );
    }
   
    exit (0);
}

  程序4.1取其命令行参数,然后针对每一个命令行参数打印其文件类型。
  程序4.1对每个命令行参数打印文件类型
  程序4.1的样本输出是:
  
  

$ ./a.out /etc /etc/profile /dev/tty0 /dev/sda1 /dev/cdrom /dev/log
/etc:   directory
/etc/profile:   regular
/dev/tty0:      character special
/dev/sda1:      block special
/dev/cdrom:     symbolic link
/dev/log:       socket


  (其中,在第一命令行末端我们键入了一个反斜线,通知shell我们要在下一行继续键入命令,然后shell在下一行上用其第二提示符提示我们特地使用了lstat函数而不是stat函数以便检测符号连接。如若使用了stat函数,则决不会观察到符号连接。较早的Unix版本并不提供SSXXX宏,于是就需要将stmode与屏蔽字SFMT逻辑与,然后与名为sFXXX的常数相比较。SVR4和4.3+BSD在文件中定义了此屏蔽字和相关的常数。如若我们查看此文件,则可找到SSDIR宏定义为:

  我们说过,普通文件是最主要的文件类型,但是观察一下在一个给定的系统中各种文件的比例是很有兴趣的。图4.2中显示了在一个中等规模的系统中的统计值。这一数据是由4.21节中的程序得到的。

  图4.2不同类型文件的计数值和比例 
阅读(10071) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~