Linux下ls命令的实现_第1页
Linux下ls命令的实现_第2页
Linux下ls命令的实现_第3页
Linux下ls命令的实现_第4页
Linux下ls命令的实现_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Linux环境程序设计大作业报告题目: Linux下ls命令的实现 学 院 物联网工程学院 专 业计算机科学与技术 班 级 计科1105班 学 号 03041105 学生姓名 二一四年十二月0Linux环境程序设计大作业报告目录一、设计思想21.1 实验要求21.2 设计思路2二、数据定义、系统(函数)调用、处理流程22.1 数据定义22.1.1 DIR结构体22.1.2 dirent结构体32.1.3 stat结构体32.2 系统调用42.2.1 opendir函数42.2.2 readdir函数42.2.3 closedir函数52.3 处理流程5三、详细设计(含源程序)6四、运行结果与分

2、析11五、设计体会14六、参考文献14一、设计思想1.1 实验要求 使用opendir、readdir、closedir等函数来操作目录,利用stat函数来获取文件信息。编写一个功能完整的实现Linux下ls命令的程序,该程序实现了-l、-i、-t这几个选项的功能。其中,-l、-i、-t选项说明: -l:use a long listing format.-i:print the index number of each file. -t:sort by modification time, newest first.1.2 设计思路 本实验是实现Linux下的ls功能。其设计思路如下:目的是

3、获取某目录下文件的详细信息。(1) 首先使用opendir()函数打开目录,返回指向该目录的DIR结构体。(2) 接着,调用readdir()函数读取这个目录下所有文件,其中应该包括目录本身,返回指向该目录下所有文件的dirent结构体。(3) 最后,遍历dirent结构体,调用stat来获取每个文件的详细信息并存储在stat结构体中。 如果这个参数是一个文件名,我们输出这个文件的大小和最后修改的时间,如果是一个目录我们输出这个目录下所有文件的大小和修改时间。使用一个数组flags4来标记输入的命令是-l、-i、-t还是空(没有输入命令)。当选择-l功能时,是以长列表方式显示,即显示详细信息;

4、当选择-i功能时,是显示每一个文件在系统里的文件号;当选择-t功能时,是按修改时间来排序,以最新的修改时间来输出。二、数据定义、系统(函数)调用、处理流程2.1 数据定义2.1.1 DIR结构体 该结构体包含在头文件#include <dirent.h>中,其定义如下:struct _dirstream      void     *_fd;     char     *_data; 

5、    int        _entry_data;     char     *_ptr;     int       _entry_ptr;     size_t  _allocation;   

6、0; size_t  _size;     _libc_lock_define (, _lock)  typedef struct _dirstream DIR; DIR结构体类似于FILE,是一个内部结构,以下几个函数用这个内部结构保存当前正在被读取的目录的有关信息。函数 DIR *opendir(const char *pathname),即打开文件目录,返回的就是指向DIR结构体的指针,而该指针由以下几个函数使用:struct dirent *readdir(DIR *

7、dp);void rewinddir(DIR *dp);int  closedir(DIR *dp);long telldir(DIR *dp);void seekdir(DIR *dp, long loc);2.1.2 dirent结构体 对于dirent结构体,首先我们要弄清楚目录文件(directory file)的概念。这种文件包含了其他文件的名字以及指向与这些文件有关的信息的指针。从定义能够看出,dirent不仅仅指向目录,还指向目录中的具体文件,readdir函数同样也读取目录下的文

8、件。以下为dirent结构体的定义:struct dirent  long  d_ino;              /* inode number 索引节点号 */      off_t d_off;             &

9、#160; /* offset to this dirent 在目录文件中的偏移 */      unsigned short d_reclen;  /* length of this d_name 文件名长 */      unsigned char  d_type;    /* the type of d_name

10、 文件类型 */      char  d_nameNAME_MAX+1; /* file name (null-terminated) 文件名,最长255字符 */  从上述定义也能够看出来,dirent结构体存储的关于文件的信息很少,所以dirent同样也是起着一个索引的作用。2.1.3 stat结构体 如果想获得类似ls -l那种效果的文件信息,必须要靠stat函数了。通过readdir函数读取到的文件名存储在结构体dirent的d_nam

11、e成员中,而函数int stat(const char *file_name, struct stat *buf);的作用就是获取文件名为d_name的文件的详细信息,存储在stat结构体中。以下为stat结构体的定义:struct stat              mode_t st_mode;     /文件访问权限        

12、     ino_t  st_ino;      /索引节点号             dev_t  st_dev;      /文件使用的设备号             dev_

13、t  st_rdev;     /设备文件的设备号             nlink_t st_nlink;   /文件的硬连接数             uid_t  st_uid;      /所有者用户

14、识别号             gid_t  st_gid;      /组识别号             off_t  st_size;     /以字节为单位的文件容量     

15、0;       time_t st_atime;    /最后一次访问该文件的时间             time_t st_mtime;     /最后一次修改该文件的时间             tim

16、e_t st_ctime;     /最后一次改变该文件状态的时间             blksize_t st_blksize; /包含该文件的磁盘块的大小             blkcnt_t st_blocks;    /该文件所占的磁盘块 2.

17、2 系统调用2.2.1 opendir函数 该函数的功能是打开目录。相关函数open,readdir,closedir,rewinddir,seekdir,telldir,scandir表头文件#include<sys/types.h>#include<dirent.h>定义函数DIR * opendir(const char * name);函数说明opendir()用来打开参数name指定的目录,并返回DIR*形态的目录流,和open()类似,接下来对目录的读取和搜索都要使用此返回值。返回值如果成功则返回DIR* 型态的目录流,如果打开失败则返回NULL。2.2.2

18、 readdir函数 该函数的功能是读取目录。相关函数open,opendir,closedir,rewinddir,seekdir,telldir,scandir表头文件#include<sys/types.h>#include<dirent.h>定义函数struct dirent * readdir(DIR * dir);函数说明readdir()返回参数dir目录流的下个目录进入点。返回值成功则返回下个目录进入点。有错误发生或读取到目录文件尾则返回NULL。附加说明EBADF参数dir为无效的目录流。2.2.3 closedir函数 该函数的功能是关闭目录。相关函

19、数opendir表头文件#include<sys/types.h>#include<dirent.h>定义函数int closedir(DIR *dir);函数说明closedir()关闭参数dir所指的目录流。返回值如果关闭成功则返回0,如果失败返回-1,错误原因存于errno 中。开始2.3 处理流程DIR结构体opendir()打开目录readdir()读取目录下文件dirent结构体结束输出大小和最后修改时间是否为文件stat获取每个文件详细信息并存储输出目录下所有文件的大小和修改时间否是三、详细设计(含源程序) 本实验是实现Linux下的ls功能。首先设置标志

20、,判断输入的命令。如果是普通文件,则递归输出文件的相关信息,如文件的大小和最后修改时间。如果是目录,则输出该目录下的所有文件和非正常文件的大小以及修改时间。普通文件使用S_ISREG()函数,而目录文件使用S_ISDIR()函数。源代码如下:/*Linux下的ls功能实现计科1105班 颜潇雨*/#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <stdio.h>#include <string.h>#include <errno.h&g

21、t;#include <pwd.h>#include <grp.h>#include <time.h>#include <dirent.h>#include <stdbool.h>static bool flags4; /标志,选项设定全局变量,用来确定是-l,-t还是-iint myls(char *s, bool flag);void lprint(char* fname);/*main函数入口*/int main(int argc, char *argv)char c;int i;while (c = getopt(argc,

22、argv, "alidtFR") != -1) /获取命令行输入的选项参数switch (c)case 'l':flags0 = 1; break;case 'i':flags1 = 1; break;case 't':flags2 = 1; break;default:return -1;if (argc = optind) /命令行没有输入目录参数,设定函数目录参数为当前目录myls(".", flags);elsefor (i = optind; i < argc; i+) /依序对输入的所有目

23、录参数进行myls函数操作myls(argvi, flags);return 0;/*myls函数,调用lprint函数进行-l格式输出*/int myls(char *s, bool flag)struct stat buf, statbuf, tmps;struct stat sort256;char *t;char fname256, tmpn256, sfname256;char sname256256;DIR *dir;struct dirent *pd;int num, i, j;if (lstat(s, &buf) < 0) return -1; /读取文件状态信息

24、if (S_ISDIR(buf.st_mode) /处理目录文件dir = opendir(s); /打开目录/*处理-t*/*对目录下所有文件进行排序,存放在缓存中进行按序输出*/if (flag2)num = 0;while (pd = readdir(dir) != NULL) /遍历目录下所有文件if ( (pd->d_name0 = '.') | (pd->d_name0 != '.')memset(fname, 0, 256);strcpy(fname, s);strcat(fname, "/");strcat(fna

25、me, pd->d_name);lstat(fname, &sortnum); /读取文件信息到缓存数组sort中strcpy(snamenum, pd->d_name); /保存文件名到缓存数组sname中num+;/*将sort存储的文件信息进行排序*/for (i = 0; i < num - 1; i+)for (j = i + 1; j < num; j+)if (sorti.st_mtime < sortj.st_mtime) /按最后修改时间进行排序tmps = sorti; sorti = sortj; sortj = tmps; /交换s

26、orti与sortj/*交换snamei与snamej*/strcpy(tmpn, snamei);strcpy(snamei, snamej);strcpy(snamej, tmpn);/*将排序后的文件信息输出*/for (i = 0; i < num; i+)if (flag1)printf("%ldt", sorti.st_ino);/-imemset(sfname, 0, 256);strcpy(sfname, s);strcat(sfname, "/");strcat(sfname, snamei);if (flag0) lprint(

27、sfname);/-lprintf("%s", snamei);if (flag0) printf("n");else printf("t");printf("n");return 0;/*其他情况*/elsewhile (pd = readdir(dir) != NULL) /遍历目录下所有文件if ( (pd->d_name0 = '.') | (pd->d_name0 != '.')/-amemset(fname, 0, 256);strcpy(fname, s);

28、strcat(fname, "/");strcat(fname, pd->d_name);lstat(fname, &statbuf);if (flag1) printf("%ldt", statbuf.st_ino);/-iif (flag0) lprint(fname);/-lprintf("%s", pd->d_name);if (flag0) printf("n");else printf("t");printf("n");return 0;els

29、eif (flag1)printf("%ldt", buf.st_ino);/-iif (flag0) lprint(s);/-lprintf("%s", s);if (flag0) printf("n");else printf("t");printf("n");/*lprint函数处理-l格式输出*/void lprint(char* fname)struct stat buf;int n;char link256;struct passwd *pw;struct group *gr;str

30、uct tm *t;lstat(fname, &buf);switch (buf.st_mode & S_IFMT)/获取并转换后打印文件类型case S_IFREG:printf("-");break;case S_IFDIR:printf("d");break;case S_IFCHR:printf("c");break;case S_IFBLK:printf("b");break;case S_IFIFO:printf("p");break;case S_IFLNK:pri

31、ntf("l");break;case S_IFSOCK:printf("s");break;for (n = 8; n >= 0; n-)/获取并转换后打印文件的读写属性if (buf.st_mode&(1 << n)switch (n % 3)case 2:printf("r");break;case 1:printf("w");break;case 0:printf("x");break;default:break;elseprintf("-");printf(" %d", buf.st_nlink);/硬链接数pw = getpwuid(buf.st_uid);/所属用户名printf(" %s", pw->pw_name);gr = getgrgid(buf.st_gid);/所属组名printf(" %s", gr->gr_name);printf(" %ld", buf.st_size);/字节数t = localti

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论