Chinaunix首页 | 论坛 | 博客
  • 博客访问: 295164
  • 博文数量: 56
  • 博客积分: 3025
  • 博客等级: 中校
  • 技术积分: 534
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-06 17:28
个人简介

Honesty and diligence should be your eternal mates.

文章分类

全部博文(56)

文章存档

2012年(1)

2011年(27)

2010年(20)

2008年(8)

分类: LINUX

2010-12-08 19:13:03

摘要:本文从分析ls命令基本功能入手,层层深入。分析了ls命令所使用的系统调用,并着重分析了内核态 
     下的系统调用服务例程,以阐明ls命令的最基本的功能是如何实现的。

一、ls命令的功能分析:

*
使用man ls命令查看ls命令手册(功能描述和主要选项摘录如下):

List  information  about  the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuvSUX nor --sort.

列出文件(默认当前目录)信息,如果没有-cftuvSUX和--sort选项,就按照字母顺序排序。

*
-a, --all   do not ignore entries starting with .

不忽略以.开始的隐藏文件

-A, --almost-all   do not list implied . and ..

不列出 .(当前目录)和..(上级目录)

-B, --ignore-backups  do not list implied entries ending with ~

忽略以~结尾的备份文件

-c with -lt: sort by, and show, ctime (time of last modification of file              status information) 
   with -l: show ctime and  sort  by  name 
   otherwise: sort by ctime

和-lt一起使用,则显示ctime(最后修改文件信息的时间),并按ctime排序显示;和-l一起使用,则显示
ctime,但只按文件名的字母顺序排序;其他,按ctime排序显示。
/*该选项和-t选项在单独使用的时候是等价的,但在和-l选项配合使用的时候,-c的功能会被屏蔽,而-t选项不会*/

-d, --directory   list directory entries instead of contents, and do not  derefer�
                  ence symbolic links

不是列出该目录的文件信息,而是列出该目录项。不追踪符号链接的实际位置。

-F, --classify   append indicator (one of */=>@|) to entries

在每个entry后面加上标识文件内容的符号:

     * : 标识可执行文件     / : 标识目录          = : 套接字文件
     @ : 符号链接文件       | : 管道文件

-l     use a long listing format

以长格式显示。

二、ls所用到的系统调用:

使用strace ls命令我们可以查看ls命令使用到的系统调用,其中最重要的几个为:

open(".", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 3
getdents64(3, /* 68 entries */, 32768)  = 2240
getdents64(3, /* 0 entries */, 32768)   = 0
close(3)                                = 0

1、open系统调用:

   打开当前目录文件,返回获得的文件描述符。

O_RDONLY:只读  O_NONBLOCK:以非阻塞的方式打开文件 O_LARGEFILE:允许打开大文件
O_DIRECTORY:如果路径不是目录,则打开错误  O_CLOEXEC:在创建新的进程后关闭文件描述符

2、close系统调用:

关闭文件描述符。

3、getdents64:

读取当前目录下的文件。

三、getdents64的系统调用服务例程:

    由于getdents64实现了ls核心功能,下面着重分析getdents64系统调用在内核态下的实现。getdents64在fs/readdir.c中定义如下:


 275(, unsigned int, ,
 276                struct   *, , unsigned int, )
 277{
 278        struct  * ;
 279        struct   * ;
 280        struct  ;
 281        int ;
 282
 283         = -;
 284        if (!(, , ))
 285                goto ;
 286
 287         = -;
 288         = ();
 289        if (!)
 290                goto ;
 291
 292        .current_dir = ;
 293        . = ;
 294        . = ;
 295        . = 0;
 296
 297         = (, , &);
 298        if ( >= 0)
 299                 = .;
 300         = .;
 301        if () {
 302                (->)  = ->;
 303                if ((, &->))
 304                         = -;
 305                else
 306                         =  - .;
 307        }
 308        ();
 309:
 310        return ;
 311}
   
getdents64首先调用fget函数得到目录文件的file结构体,再调用虚拟文件系统提供的函数,读取目录项,该函数的定义也在fs/readdir64中:

int (struct  *,  , void *)
  24{
  25        struct  * = ->.->;
  26        int  = -;
  27        if (!-> || !->->)
  28                goto ;
  29
  30         = security_file_permission(, );
  31        if ()
  32                goto ;
  33
  34         = (&->);
  35        if ()
  36                goto ;
  37
  38         = -;
  39        if (!()) {
  40                 = ->->(, , );
  41                ();
  42        }
  43        (&->);
  44:
  45        return ;
  46}

   该函数首先通过file结构体得到inode,然后从inode中获得并执行file_operations结构体
中的读取目录函数(底层文件系统提供)->->(, , )。

   综上所述,实际上对文件进行操作的是底层文件系统提供的函数,它通过file_operations结
构体可被上层的虚拟文件系统调用,而用户程序又可通过系统调用进入内核态,调用虚拟文件系统提供
的接口函数。
阅读(5510) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

ziyanghgd2015-11-11 16:06:15

不错哈

ziyanghgd2015-11-11 16:06:00

不错哈